blob: 71bac909a683496fc0f551340bb5d0b085635122 [file] [log] [blame]
Guido van Rossum50098201992-07-31 15:10:13 +00001/***********************************************************
Guido van Rossum34679b71993-01-26 13:33:44 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossum50098201992-07-31 15:10:13 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000024/******************************************************************
25Copyright 1992 by Lance Ellinghouse (lance@markv.com)
26
27All Rights Reserved
28
29Permission to use, copy, distribute for any purpose and without fee
30is hereby granted, provided that this copyright notice appear in
31all copies and that both this copyright notice and this permission
32notice appear in supporting documentation.
33Permission to make any changes is granted on the basis that all
34changes and improvements are also forwarded to Lance Ellinghouse
35before distribution.
36******************************************************************/
Guido van Rossum50098201992-07-31 15:10:13 +000037
38/* This creates an encryption and decryption engine I am calling
39 a rotor due to the original design was a harware rotor with
40 contacts used in Germany during WWII.
41
42Rotor Module:
43
44- rotor.newrotor('key') -> rotorobject (default of 6 rotors)
45- rotor.newrotor('key', num_rotors) -> rotorobject
46
47Rotor Objects:
48
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000049- ro.setkey('string') -> None (resets the key as defined in newrotor().
Guido van Rossum50098201992-07-31 15:10:13 +000050- ro.encrypt('string') -> encrypted string
51- ro.decrypt('encrypted string') -> unencrypted string
52
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000053- ro.encryptmore('string') -> encrypted string
54- ro.decryptmore('encrypted string') -> unencrypted string
55
56NOTE: the {en,de}cryptmore() methods use the setup that was
57 established via the {en,de}crypt calls. They will NOT
58 re-initalize the rotors unless: 1) They have not been
59 initalized with {en,de}crypt since the last setkey() call;
60 2) {en,de}crypt has not been called for this rotor yet.
61
Guido van Rossum50098201992-07-31 15:10:13 +000062NOTE: you MUST use the SAME key in rotor.newrotor()
63 if you wish to decrypt an encrypted string.
64 Also, the encrypted string is NOT 0-127 ASCII.
65 It is considered BINARY data.
66
67*/
68
69/* Rotor objects */
70
71#include "allobjects.h"
72#include "modsupport.h"
73#include <stdio.h>
74#include <math.h>
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000075#define TRUE 1
76#define FALSE 0
Guido van Rossum50098201992-07-31 15:10:13 +000077
78typedef struct {
79 OB_HEAD
80 int seed[3];
81 short key[5];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000082 int isinited;
Guido van Rossum50098201992-07-31 15:10:13 +000083 int size;
84 int size_mask;
85 int rotors;
86 unsigned char *e_rotor; /* [num_rotors][size] */
87 unsigned char *d_rotor; /* [num_rotors][size] */
88 unsigned char *positions; /* [num_rotors] */
89 unsigned char *advances; /* [num_rotors] */
90} rotorobject;
91
92extern typeobject Rotortype; /* Really static, forward */
93
94#define is_rotorobject(v) ((v)->ob_type == &Rotortype)
95
96/*
97 This defines the necessary routines to manage rotor objects
98*/
99
100static void set_seed( r )
101rotorobject *r;
102{
103 r->seed[0] = r->key[0];
104 r->seed[1] = r->key[1];
105 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000106 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +0000107}
108
109/* Return the next random number in the range [0.0 .. 1.0) */
110static float r_random( r )
111rotorobject *r;
112{
113 int x, y, z;
114 float val, term;
115
116 x = r->seed[0];
117 y = r->seed[1];
118 z = r->seed[2];
119
120 x = 171 * (x % 177) - 2 * (x/177);
121 y = 172 * (y % 176) - 35 * (y/176);
122 z = 170 * (z % 178) - 63 * (z/178);
123
124 if (x < 0) x = x + 30269;
125 if (y < 0) y = y + 30307;
126 if (z < 0) z = z + 30323;
127
128 r->seed[0] = x;
129 r->seed[1] = y;
130 r->seed[2] = z;
131
132 term = (float)(
133 (((float)x)/(float)30269.0) +
134 (((float)y)/(float)30307.0) +
135 (((float)z)/(float)30323.0)
136 );
137 val = term - (float)floor((double)term);
138
139 if (val >= 1.0) val = 0.0;
140
141 return val;
142}
143
144static short r_rand(r,s)
145rotorobject *r;
146short s;
147{
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000148 /*short tmp = (short)((int)(r_random(r) * (float)32768.0) % 32768);*/
Guido van Rossum50098201992-07-31 15:10:13 +0000149 short tmp = (short)((short)(r_random(r) * (float)s) % s);
150 return tmp;
151}
152
153static void set_key(r, key)
154rotorobject *r;
155char *key;
156{
157 int k1=995, k2=576, k3=767, k4=671, k5=463;
158 int i;
159 int len=strlen(key);
160 for (i=0;i<len;i++) {
161 k1 = (((k1<<3 | k1<<-13) + key[i]) & 65535);
162 k2 = (((k2<<3 | k2<<-13) ^ key[i]) & 65535);
163 k3 = (((k3<<3 | k3<<-13) - key[i]) & 65535);
164 k4 = ((key[i] - (k4<<3 | k4<<-13)) & 65535);
165 k5 = (((k5<<3 | k5<<-13) ^ ~key[i]) & 65535);
166 }
167 r->key[0] = (short)k1;
168 r->key[1] = (short)(k2|1);
169 r->key[2] = (short)k3;
170 r->key[3] = (short)k4;
171 r->key[4] = (short)k5;
172
173 set_seed(r);
174}
175
176/* These define the interface to a rotor object */
177static rotorobject *
178newrotorobject(num_rotors, key)
179 int num_rotors;
180 char *key;
181{
182 rotorobject *xp;
183 xp = NEWOBJ(rotorobject, &Rotortype);
184 if (xp == NULL)
185 return NULL;
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000186 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000187
188 xp->size = 256;
189 xp->size_mask = xp->size - 1;
190 xp->size_mask = 0;
191 xp->rotors = num_rotors;
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000192 xp->e_rotor = NULL;
193 xp->d_rotor = NULL;
194 xp->positions = NULL;
195 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000196
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000197 xp->e_rotor =
198 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
199 if (xp->e_rotor == (unsigned char *)NULL)
200 goto fail;
201 xp->d_rotor =
202 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
203 if (xp->d_rotor == (unsigned char *)NULL)
204 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000205 xp->positions = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000206 if (xp->positions == (unsigned char *)NULL)
207 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000208 xp->advances = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000209 if (xp->advances == (unsigned char *)NULL)
210 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000211 return xp;
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000212fail:
213 DECREF(xp);
214 return (rotorobject *)err_nomem();
Guido van Rossum50098201992-07-31 15:10:13 +0000215}
216
217/* These routines impliment the rotor itself */
218
219/* Here is a fairly sofisticated {en,de}cryption system. It is bassed
220on the idea of a "rotor" machine. A bunch of rotors, each with a
221different permutation of the alphabet, rotate around a different
222amount after encrypting one character. The current state of the
223rotors is used to encrypt one character.
224
225 The code is smart enought to tell if your alphabet has a number of
226characters equal to a power of two. If it does, it uses logical
227operations, if not it uses div and mod (both require a division).
228
229 You will need to make two changes to the code 1) convert to c, and
230customize for an alphabet of 255 chars 2) add a filter at the
231begining, and end, which subtracts one on the way in, and adds one on
232the way out.
233
234 You might wish to do some timing studies. Another viable
235alternative is to "byte stuff" the encrypted data of a normal (perhaps
236this one) encryption routine.
237
238j'
239*/
240
241/*(defun RTR-make-id-rotor (rotor)
242 "Set ROTOR to the identity permutation"
243 (let ((j 0))
244 (while (< j RTR-size)
245 (aset rotor j j)
246 (setq j (+ 1 j)))
247 rotor))*/
248static void RTR_make_id_rotor(r, rtr)
249 rotorobject *r;
250 unsigned char *rtr;
251{
252 register int j;
253 register int size = r->size;
254 for (j=0;j<size;j++) {
255 rtr[j] = (unsigned char)j;
256 }
257}
258
259
260/*(defvar RTR-e-rotors
261 (let ((rv (make-vector RTR-number-of-rotors 0))
262 (i 0)
263 tr)
264 (while (< i RTR-number-of-rotors)
265 (setq tr (make-vector RTR-size 0))
266 (RTR-make-id-rotor tr)
267 (aset rv i tr)
268 (setq i (+ 1 i)))
269 rv)
270 "The current set of encryption rotors")*/
271static void RTR_e_rotors(r)
272 rotorobject *r;
273{
274 int i;
275 for (i=0;i<r->rotors;i++) {
276 RTR_make_id_rotor(r,&(r->e_rotor[(i*r->size)]));
277 }
278}
279
280/*(defvar RTR-d-rotors
281 (let ((rv (make-vector RTR-number-of-rotors 0))
282 (i 0)
283 tr)
284 (while (< i RTR-number-of-rotors)
285 (setq tr (make-vector RTR-size 0))
286 (setq j 0)
287 (while (< j RTR-size)
288 (aset tr j j)
289 (setq j (+ 1 j)))
290 (aset rv i tr)
291 (setq i (+ 1 i)))
292 rv)
293 "The current set of decryption rotors")*/
294static void RTR_d_rotors(r)
295 rotorobject *r;
296{
297 register int i, j;
298 for (i=0;i<r->rotors;i++) {
299 for (j=0;j<r->size;j++) {
300 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
301 }
302 }
303}
304
305/*(defvar RTR-positions (make-vector RTR-number-of-rotors 1)
306 "The positions of the rotors at this time")*/
307static void RTR_positions(r)
308 rotorobject *r;
309{
310 int i;
311 for (i=0;i<r->rotors;i++) {
312 r->positions[i] = 1;
313 }
314}
315
316/*(defvar RTR-advances (make-vector RTR-number-of-rotors 1)
317 "The number of positions to advance the rotors at a time")*/
318static void RTR_advances(r)
319 rotorobject *r;
320{
321 int i;
322 for (i=0;i<r->rotors;i++) {
323 r->advances[i] = 1;
324 }
325}
326
327/*(defun RTR-permute-rotor (e d)
328 "Permute the E rotor, and make the D rotor its inverse"
329 ;; see Knuth for explaination of algorythm.
330 (RTR-make-id-rotor e)
331 (let ((i RTR-size)
332 q j)
333 (while (<= 2 i)
334 (setq q (fair16 i)) ; a little tricky, decrement here
335 (setq i (- i 1)) ; since we have origin 0 array's
336 (setq j (aref e q))
337 (aset e q (aref e i))
338 (aset e i j)
339 (aset d j i))
340 (aset e 0 (aref e 0)) ; don't forget e[0] and d[0]
341 (aset d (aref e 0) 0)))*/
342static void RTR_permute_rotor(r, e, d)
343 rotorobject *r;
344 unsigned char *e;
345 unsigned char *d;
346{
347 short i = r->size;
348 short q;
349 unsigned char j;
350 RTR_make_id_rotor(r,e);
351 while (2 <= i) {
352 q = r_rand(r,i);
353 i--;
354 j = e[q];
355 e[q] = (unsigned char)e[i];
356 e[i] = (unsigned char)j;
357 d[j] = (unsigned char)i;
358 }
359 e[0] = (unsigned char)e[0];
360 d[(e[0])] = (unsigned char)0;
361}
362
363/*(defun RTR-init (key)
364 "Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
365Set the advancement, position, and permutation of the rotors"
366 (R16-set-state key)
367 (let (i)
368 (setq i 0)
369 (while (< i RTR-number-of-rotors)
370 (aset RTR-positions i (fair16 RTR-size))
371 (aset RTR-advances i (+ 1 (* 2 (fair16 (/ RTR-size 2)))))
372 (message "Initializing rotor %d..." i)
373 (RTR-permute-rotor (aref RTR-e-rotors i) (aref RTR-d-rotors i))
374 (setq i (+ 1 i)))))*/
375static void RTR_init(r)
376 rotorobject *r;
377{
378 int i;
379 set_seed(r);
380 RTR_positions(r);
381 RTR_advances(r);
382 RTR_e_rotors(r);
383 RTR_d_rotors(r);
384 for(i=0;i<r->rotors;i++) {
385 r->positions[i] = r_rand(r,r->size);
386 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
387 RTR_permute_rotor(r,&(r->e_rotor[(i*r->size)]),&(r->d_rotor[(i*r->size)]));
388 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000389 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000390}
391
392/*(defun RTR-advance ()
393 "Change the RTR-positions vector, using the RTR-advances vector"
394 (let ((i 0)
395 (temp 0))
396 (if RTR-size-mask
397 (while (< i RTR-number-of-rotors)
398 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
399 (aset RTR-positions i (logand temp RTR-size-mask))
400 (if (and (>= temp RTR-size)
401 (< i (- RTR-number-of-rotors 1)))
402 (aset RTR-positions (+ i 1)
403 (+ 1 (aref RTR-positions (+ i 1)))))
404 (setq i (+ i 1)))
405 (while (< i RTR-number-of-rotors)
406 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
407 (aset RTR-positions i (% temp RTR-size))
408 (if (and (>= temp RTR-size)
409 (< i (- RTR-number-of-rotors 1)))
410 (aset RTR-positions (+ i 1)
411 (+ 1 (aref RTR-positions (+ i 1)))))
412 (setq i (+ i 1))))))*/
413static void RTR_advance(r)
414 rotorobject *r;
415{
416 register int i=0, temp=0;
417 if (r->size_mask) {
418 while (i<r->rotors) {
419 temp = r->positions[i] + r->advances[i];
420 r->positions[i] = temp & r->size_mask;
421 if ((temp >= r->size) && (i < (r->rotors - 1))) {
422 r->positions[(i+1)] = 1 + r->positions[(i+1)];
423 }
424 i++;
425 }
426 } else {
427 while (i<r->rotors) {
428 temp = r->positions[i] + r->advances[i];
429 r->positions[i] = temp%r->size;
430 if ((temp >= r->size) && (i < (r->rotors - 1))) {
431 r->positions[(i+1)] = 1 + r->positions[(i+1)];
432 }
433 i++;
434 }
435 }
436}
437
438/*(defun RTR-e-char (p)
439 "Encrypt the character P with the current rotor machine"
440 (let ((i 0))
441 (if RTR-size-mask
442 (while (< i RTR-number-of-rotors)
443 (setq p (aref (aref RTR-e-rotors i)
444 (logand (logxor (aref RTR-positions i)
445 p)
446 RTR-size-mask)))
447 (setq i (+ 1 i)))
448 (while (< i RTR-number-of-rotors)
449 (setq p (aref (aref RTR-e-rotors i)
450 (% (logxor (aref RTR-positions i)
451 p)
452 RTR-size)))
453 (setq i (+ 1 i))))
454 (RTR-advance)
455 p))*/
456static unsigned char RTR_e_char(r, p)
457 rotorobject *r;
458 unsigned char p;
459{
460 register int i=0;
461 register unsigned char tp=p;
462 if (r->size_mask) {
463 while (i < r->rotors) {
464 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) & r->size_mask))];
465 i++;
466 }
467 } else {
468 while (i < r->rotors) {
469 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) % r->size))];
470 i++;
471 }
472 }
473 RTR_advance(r);
474 return ((unsigned char)tp);
475}
476
477/*(defun RTR-d-char (c)
478 "Decrypt the character C with the current rotor machine"
479 (let ((i (- RTR-number-of-rotors 1)))
480 (if RTR-size-mask
481 (while (<= 0 i)
482 (setq c (logand (logxor (aref RTR-positions i)
483 (aref (aref RTR-d-rotors i)
484 c))
485 RTR-size-mask))
486 (setq i (- i 1)))
487 (while (<= 0 i)
488 (setq c (% (logxor (aref RTR-positions i)
489 (aref (aref RTR-d-rotors i)
490 c))
491 RTR-size))
492 (setq i (- i 1))))
493 (RTR-advance)
494 c))*/
495static unsigned char RTR_d_char(r, c)
496 rotorobject *r;
497 unsigned char c;
498{
499 register int i=r->rotors - 1;
500 register unsigned char tc=c;
501 if (r->size_mask) {
502 while (0 <= i) {
503 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) & r->size_mask;
504 i--;
505 }
506 } else {
507 while (0 <= i) {
508 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) % r->size;
509 i--;
510 }
511 }
512 RTR_advance(r);
513 return(tc);
514}
515
516/*(defun RTR-e-region (beg end key)
517 "Perform a rotor encryption of the region from BEG to END by KEY"
518 (save-excursion
519 (let ((tenth (/ (- end beg) 10)))
520 (RTR-init key)
521 (goto-char beg)
522 ;; ### make it stop evry 10% or so to tell us
523 (while (< (point) end)
524 (let ((fc (following-char)))
525 (insert-char (RTR-e-char fc) 1)
526 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000527static void RTR_e_region(r, beg, len, doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000528 rotorobject *r;
529 unsigned char *beg;
530 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000531 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000532{
533 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000534 if (doinit || r->isinited == FALSE)
535 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000536 for (i=0;i<len;i++) {
537 beg[i]=RTR_e_char(r,beg[i]);
538 }
539}
540
541/*(defun RTR-d-region (beg end key)
542 "Perform a rotor decryption of the region from BEG to END by KEY"
543 (save-excursion
544 (progn
545 (RTR-init key)
546 (goto-char beg)
547 (while (< (point) end)
548 (let ((fc (following-char)))
549 (insert-char (RTR-d-char fc) 1)
550 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000551void static RTR_d_region(r, beg, len, doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000552 rotorobject *r;
553 unsigned char *beg;
554 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000555 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000556{
557 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000558 if (doinit || r->isinited == FALSE)
559 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000560 for (i=0;i<len;i++) {
561 beg[i]=RTR_d_char(r,beg[i]);
562 }
563}
564
565
566/*(defun RTR-key-string-to-ints (key)
567 "Convert a string into a list of 4 numbers"
568 (let ((k1 995)
569 (k2 576)
570 (k3 767)
571 (k4 671)
572 (k5 463)
573 (i 0))
574 (while (< i (length key))
575 (setq k1 (logand (+ (logior (lsh k1 3) (lsh k1 -13)) (aref key i)) 65535))
576 (setq k2 (logand (logxor (logior (lsh k2 3) (lsh k2 -13)) (aref key i)) 65535))
577 (setq k3 (logand (- (logior (lsh k3 3) (lsh k3 -13)) (aref key i)) 65535))
578 (setq k4 (logand (- (aref key i) (logior (lsh k4 3) (lsh k4 -13))) 65535))
579 (setq k5 (logand (logxor (logior (lsh k5 3) (lsh k5 -13)) (lognot (aref key i))) 65535))
580 (setq i (+ i 1)))
581 (list k1 (logior 1 k2) k3 k4 k5)))*/
582/* This is done in set_key() above */
583
584/*(defun encrypt-region (beg end key)
585 "Interactivly encrypt the region"
586 (interactive "r\nsKey:")
587 (RTR-e-region beg end (RTR-key-string-to-ints key)))*/
588static void encrypt_region(r, region, len)
589 rotorobject *r;
590 unsigned char *region;
591 int len;
592{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000593 RTR_e_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000594}
595
596/*(defun decrypt-region (beg end key)
597 "Interactivly decrypt the region"
598 (interactive "r\nsKey:")
599 (RTR-d-region beg end (RTR-key-string-to-ints key)))*/
600static void decrypt_region(r, region, len)
601 rotorobject *r;
602 unsigned char *region;
603 int len;
604{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000605 RTR_d_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000606}
607
608/* Rotor methods */
609
610static void
611rotor_dealloc(xp)
612 rotorobject *xp;
613{
Guido van Rossume6e9fe11992-07-31 15:11:01 +0000614 XDEL(xp->e_rotor);
615 XDEL(xp->d_rotor);
616 XDEL(xp->positions);
617 XDEL(xp->advances);
Guido van Rossum50098201992-07-31 15:10:13 +0000618 DEL(xp);
619}
620
621static object *
622rotor_encrypt(self, args)
623 rotorobject *self;
624 object *args;
625{
626 char *string = (char *)NULL;
627 int len = 0;
628 object *rtn = (object *)NULL;
629 char *tmp;
630
631 if (!getargs(args,"s#",&string, &len))
632 return NULL;
633 if (!(tmp = (char *)malloc(len+5))) {
634 err_nomem();
635 return NULL;
636 }
637 memset(tmp,'\0',len+1);
638 memcpy(tmp,string,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000639 RTR_e_region(self,tmp,len, TRUE);
640 rtn = newsizedstringobject(tmp,len);
641 free(tmp);
642 return(rtn);
643}
644
645static object *
646rotor_encryptmore(self, args)
647 rotorobject *self;
648 object *args;
649{
650 char *string = (char *)NULL;
651 int len = 0;
652 object *rtn = (object *)NULL;
653 char *tmp;
654
655 if (!getargs(args,"s#",&string, &len))
656 return NULL;
657 if (!(tmp = (char *)malloc(len+5))) {
658 err_nomem();
659 return NULL;
660 }
661 memset(tmp,'\0',len+1);
662 memcpy(tmp,string,len);
663 RTR_e_region(self,tmp,len, FALSE);
Guido van Rossum50098201992-07-31 15:10:13 +0000664 rtn = newsizedstringobject(tmp,len);
665 free(tmp);
666 return(rtn);
667}
668
669static object *
670rotor_decrypt(self, args)
671 rotorobject *self;
672 object *args;
673{
674 char *string = (char *)NULL;
675 int len = 0;
676 object *rtn = (object *)NULL;
677 char *tmp;
678
679 if (!getargs(args,"s#",&string, &len))
680 return NULL;
681 if (!(tmp = (char *)malloc(len+5))) {
682 err_nomem();
683 return NULL;
684 }
685 memset(tmp,'\0',len+1);
686 memcpy(tmp,string,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000687 RTR_d_region(self,tmp,len, TRUE);
688 rtn = newsizedstringobject(tmp,len);
689 free(tmp);
690 return(rtn);
691}
692
693static object *
694rotor_decryptmore(self, args)
695 rotorobject *self;
696 object *args;
697{
698 char *string = (char *)NULL;
699 int len = 0;
700 object *rtn = (object *)NULL;
701 char *tmp;
702
703 if (!getargs(args,"s#",&string, &len))
704 return NULL;
705 if (!(tmp = (char *)malloc(len+5))) {
706 err_nomem();
707 return NULL;
708 }
709 memset(tmp,'\0',len+1);
710 memcpy(tmp,string,len);
711 RTR_d_region(self,tmp,len, FALSE);
Guido van Rossum50098201992-07-31 15:10:13 +0000712 rtn = newsizedstringobject(tmp,len);
713 free(tmp);
714 return(rtn);
715}
716
717static object *
718rotor_setkey(self, args)
719 rotorobject *self;
720 object *args;
721{
722 char *key;
723 char *string;
724
725 if (getargs(args,"s",&string))
726 set_key(self,string);
727 INCREF(None);
728 return None;
729}
730
731static struct methodlist rotor_methods[] = {
732 {"encrypt", rotor_encrypt},
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000733 {"encryptmore", rotor_encryptmore},
Guido van Rossum50098201992-07-31 15:10:13 +0000734 {"decrypt", rotor_decrypt},
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000735 {"decryptmore", rotor_decryptmore},
Guido van Rossum50098201992-07-31 15:10:13 +0000736 {"setkey", rotor_setkey},
737 {NULL, NULL} /* sentinel */
738};
739
740
741/* Return a rotor object's named attribute. */
742static object *
743rotor_getattr(s, name)
744 rotorobject *s;
745 char *name;
746{
747 return findmethod(rotor_methods, (object *) s, name);
748}
749
750static typeobject Rotortype = {
751 OB_HEAD_INIT(&Typetype)
752 0, /*ob_size*/
753 "rotor", /*tp_name*/
754 sizeof(rotorobject), /*tp_size*/
755 0, /*tp_itemsize*/
756 /* methods */
757 rotor_dealloc, /*tp_dealloc*/
758 0, /*tp_print*/
759 rotor_getattr, /*tp_getattr*/
760 0, /*tp_setattr*/
761 0, /*tp_compare*/
762 0, /*tp_repr*/
763};
764
765
Guido van Rossum234f9421993-06-17 12:35:49 +0000766static object *
767rotor_rotor(self, args)
768 object *self;
769 object *args;
Guido van Rossum50098201992-07-31 15:10:13 +0000770{
771 char *string;
772 rotorobject *r;
773 int len;
774 int num_rotors;
775
776 if (getargs(args,"s#", &string, &len)) {
777 num_rotors = 6;
778 } else {
779 err_clear();
780 if (!getargs(args,"(s#i)", &string, &len, &num_rotors))
781 return NULL;
782 }
783 r = newrotorobject(num_rotors, string);
784 return (object *)r;
785}
786
787static struct methodlist rotor_rotor_methods[] = {
788 {"newrotor", rotor_rotor},
789 {NULL, NULL} /* Sentinel */
790};
791
792
793/* Initialize this module.
794 This is called when the first 'import rotor' is done,
795 via a table in config.c, if config.c is compiled with USE_ROTOR
796 defined. */
797
798void
799initrotor()
800{
801 object *m;
802
803 m = initmodule("rotor", rotor_rotor_methods);
804}