blob: d397e2cd25f81a5fbfbd531f2d265aed4f40b76a [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{
Guido van Rossume77a7571993-11-03 15:01:26 +0000157#ifdef BUGGY_CODE_BW_COMPAT
158 /* See comments below */
Guido van Rossum50098201992-07-31 15:10:13 +0000159 int k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossume77a7571993-11-03 15:01:26 +0000160#else
161 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
162#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000163 int i;
164 int len=strlen(key);
165 for (i=0;i<len;i++) {
Guido van Rossum06676261993-11-01 16:20:18 +0000166#ifdef BUGGY_CODE_BW_COMPAT
167 /* This is the code as it was originally released.
168 It causes warnings on many systems and can generate
169 different results as well. If you have files
170 encrypted using an older version you may want to
171 #define BUGGY_CODE_BW_COMPAT so as to be able to
172 decrypt them... */
Guido van Rossum50098201992-07-31 15:10:13 +0000173 k1 = (((k1<<3 | k1<<-13) + key[i]) & 65535);
174 k2 = (((k2<<3 | k2<<-13) ^ key[i]) & 65535);
175 k3 = (((k3<<3 | k3<<-13) - key[i]) & 65535);
176 k4 = ((key[i] - (k4<<3 | k4<<-13)) & 65535);
177 k5 = (((k5<<3 | k5<<-13) ^ ~key[i]) & 65535);
Guido van Rossum06676261993-11-01 16:20:18 +0000178#else
179 /* This code should be more portable */
180 k1 = (((k1<<3 | k1>>13) + key[i]) & 65535);
181 k2 = (((k2<<3 | k2>>13) ^ key[i]) & 65535);
182 k3 = (((k3<<3 | k3>>13) - key[i]) & 65535);
183 k4 = ((key[i] - (k4<<3 | k4>>13)) & 65535);
184 k5 = (((k5<<3 | k5>>13) ^ ~key[i]) & 65535);
185#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000186 }
187 r->key[0] = (short)k1;
188 r->key[1] = (short)(k2|1);
189 r->key[2] = (short)k3;
190 r->key[3] = (short)k4;
191 r->key[4] = (short)k5;
192
193 set_seed(r);
194}
195
196/* These define the interface to a rotor object */
197static rotorobject *
198newrotorobject(num_rotors, key)
199 int num_rotors;
200 char *key;
201{
202 rotorobject *xp;
203 xp = NEWOBJ(rotorobject, &Rotortype);
204 if (xp == NULL)
205 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000206 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000207
208 xp->size = 256;
209 xp->size_mask = xp->size - 1;
210 xp->size_mask = 0;
211 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000212 xp->e_rotor = NULL;
213 xp->d_rotor = NULL;
214 xp->positions = NULL;
215 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000216
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000217 xp->e_rotor =
218 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
219 if (xp->e_rotor == (unsigned char *)NULL)
220 goto fail;
221 xp->d_rotor =
222 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
223 if (xp->d_rotor == (unsigned char *)NULL)
224 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000225 xp->positions = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000226 if (xp->positions == (unsigned char *)NULL)
227 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000228 xp->advances = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000229 if (xp->advances == (unsigned char *)NULL)
230 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000231 return xp;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000232fail:
233 DECREF(xp);
234 return (rotorobject *)err_nomem();
Guido van Rossum50098201992-07-31 15:10:13 +0000235}
236
237/* These routines impliment the rotor itself */
238
239/* Here is a fairly sofisticated {en,de}cryption system. It is bassed
240on the idea of a "rotor" machine. A bunch of rotors, each with a
241different permutation of the alphabet, rotate around a different
242amount after encrypting one character. The current state of the
243rotors is used to encrypt one character.
244
245 The code is smart enought to tell if your alphabet has a number of
246characters equal to a power of two. If it does, it uses logical
247operations, if not it uses div and mod (both require a division).
248
249 You will need to make two changes to the code 1) convert to c, and
250customize for an alphabet of 255 chars 2) add a filter at the
251begining, and end, which subtracts one on the way in, and adds one on
252the way out.
253
254 You might wish to do some timing studies. Another viable
255alternative is to "byte stuff" the encrypted data of a normal (perhaps
256this one) encryption routine.
257
258j'
259*/
260
261/*(defun RTR-make-id-rotor (rotor)
262 "Set ROTOR to the identity permutation"
263 (let ((j 0))
264 (while (< j RTR-size)
265 (aset rotor j j)
266 (setq j (+ 1 j)))
267 rotor))*/
268static void RTR_make_id_rotor(r, rtr)
269 rotorobject *r;
270 unsigned char *rtr;
271{
272 register int j;
273 register int size = r->size;
274 for (j=0;j<size;j++) {
275 rtr[j] = (unsigned char)j;
276 }
277}
278
279
280/*(defvar RTR-e-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 (RTR-make-id-rotor tr)
287 (aset rv i tr)
288 (setq i (+ 1 i)))
289 rv)
290 "The current set of encryption rotors")*/
291static void RTR_e_rotors(r)
292 rotorobject *r;
293{
294 int i;
295 for (i=0;i<r->rotors;i++) {
296 RTR_make_id_rotor(r,&(r->e_rotor[(i*r->size)]));
297 }
298}
299
300/*(defvar RTR-d-rotors
301 (let ((rv (make-vector RTR-number-of-rotors 0))
302 (i 0)
303 tr)
304 (while (< i RTR-number-of-rotors)
305 (setq tr (make-vector RTR-size 0))
306 (setq j 0)
307 (while (< j RTR-size)
308 (aset tr j j)
309 (setq j (+ 1 j)))
310 (aset rv i tr)
311 (setq i (+ 1 i)))
312 rv)
313 "The current set of decryption rotors")*/
314static void RTR_d_rotors(r)
315 rotorobject *r;
316{
317 register int i, j;
318 for (i=0;i<r->rotors;i++) {
319 for (j=0;j<r->size;j++) {
320 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
321 }
322 }
323}
324
325/*(defvar RTR-positions (make-vector RTR-number-of-rotors 1)
326 "The positions of the rotors at this time")*/
327static void RTR_positions(r)
328 rotorobject *r;
329{
330 int i;
331 for (i=0;i<r->rotors;i++) {
332 r->positions[i] = 1;
333 }
334}
335
336/*(defvar RTR-advances (make-vector RTR-number-of-rotors 1)
337 "The number of positions to advance the rotors at a time")*/
338static void RTR_advances(r)
339 rotorobject *r;
340{
341 int i;
342 for (i=0;i<r->rotors;i++) {
343 r->advances[i] = 1;
344 }
345}
346
347/*(defun RTR-permute-rotor (e d)
348 "Permute the E rotor, and make the D rotor its inverse"
349 ;; see Knuth for explaination of algorythm.
350 (RTR-make-id-rotor e)
351 (let ((i RTR-size)
352 q j)
353 (while (<= 2 i)
354 (setq q (fair16 i)) ; a little tricky, decrement here
355 (setq i (- i 1)) ; since we have origin 0 array's
356 (setq j (aref e q))
357 (aset e q (aref e i))
358 (aset e i j)
359 (aset d j i))
360 (aset e 0 (aref e 0)) ; don't forget e[0] and d[0]
361 (aset d (aref e 0) 0)))*/
362static void RTR_permute_rotor(r, e, d)
363 rotorobject *r;
364 unsigned char *e;
365 unsigned char *d;
366{
367 short i = r->size;
368 short q;
369 unsigned char j;
370 RTR_make_id_rotor(r,e);
371 while (2 <= i) {
372 q = r_rand(r,i);
373 i--;
374 j = e[q];
375 e[q] = (unsigned char)e[i];
376 e[i] = (unsigned char)j;
377 d[j] = (unsigned char)i;
378 }
379 e[0] = (unsigned char)e[0];
380 d[(e[0])] = (unsigned char)0;
381}
382
383/*(defun RTR-init (key)
384 "Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
385Set the advancement, position, and permutation of the rotors"
386 (R16-set-state key)
387 (let (i)
388 (setq i 0)
389 (while (< i RTR-number-of-rotors)
390 (aset RTR-positions i (fair16 RTR-size))
391 (aset RTR-advances i (+ 1 (* 2 (fair16 (/ RTR-size 2)))))
392 (message "Initializing rotor %d..." i)
393 (RTR-permute-rotor (aref RTR-e-rotors i) (aref RTR-d-rotors i))
394 (setq i (+ 1 i)))))*/
395static void RTR_init(r)
396 rotorobject *r;
397{
398 int i;
399 set_seed(r);
400 RTR_positions(r);
401 RTR_advances(r);
402 RTR_e_rotors(r);
403 RTR_d_rotors(r);
404 for(i=0;i<r->rotors;i++) {
405 r->positions[i] = r_rand(r,r->size);
406 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
407 RTR_permute_rotor(r,&(r->e_rotor[(i*r->size)]),&(r->d_rotor[(i*r->size)]));
408 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000409 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000410}
411
412/*(defun RTR-advance ()
413 "Change the RTR-positions vector, using the RTR-advances vector"
414 (let ((i 0)
415 (temp 0))
416 (if RTR-size-mask
417 (while (< i RTR-number-of-rotors)
418 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
419 (aset RTR-positions i (logand temp RTR-size-mask))
420 (if (and (>= temp RTR-size)
421 (< i (- RTR-number-of-rotors 1)))
422 (aset RTR-positions (+ i 1)
423 (+ 1 (aref RTR-positions (+ i 1)))))
424 (setq i (+ i 1)))
425 (while (< i RTR-number-of-rotors)
426 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
427 (aset RTR-positions i (% temp RTR-size))
428 (if (and (>= temp RTR-size)
429 (< i (- RTR-number-of-rotors 1)))
430 (aset RTR-positions (+ i 1)
431 (+ 1 (aref RTR-positions (+ i 1)))))
432 (setq i (+ i 1))))))*/
433static void RTR_advance(r)
434 rotorobject *r;
435{
436 register int i=0, temp=0;
437 if (r->size_mask) {
438 while (i<r->rotors) {
439 temp = r->positions[i] + r->advances[i];
440 r->positions[i] = temp & r->size_mask;
441 if ((temp >= r->size) && (i < (r->rotors - 1))) {
442 r->positions[(i+1)] = 1 + r->positions[(i+1)];
443 }
444 i++;
445 }
446 } else {
447 while (i<r->rotors) {
448 temp = r->positions[i] + r->advances[i];
449 r->positions[i] = temp%r->size;
450 if ((temp >= r->size) && (i < (r->rotors - 1))) {
451 r->positions[(i+1)] = 1 + r->positions[(i+1)];
452 }
453 i++;
454 }
455 }
456}
457
458/*(defun RTR-e-char (p)
459 "Encrypt the character P with the current rotor machine"
460 (let ((i 0))
461 (if RTR-size-mask
462 (while (< i RTR-number-of-rotors)
463 (setq p (aref (aref RTR-e-rotors i)
464 (logand (logxor (aref RTR-positions i)
465 p)
466 RTR-size-mask)))
467 (setq i (+ 1 i)))
468 (while (< i RTR-number-of-rotors)
469 (setq p (aref (aref RTR-e-rotors i)
470 (% (logxor (aref RTR-positions i)
471 p)
472 RTR-size)))
473 (setq i (+ 1 i))))
474 (RTR-advance)
475 p))*/
476static unsigned char RTR_e_char(r, p)
477 rotorobject *r;
478 unsigned char p;
479{
480 register int i=0;
481 register unsigned char tp=p;
482 if (r->size_mask) {
483 while (i < r->rotors) {
484 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) & r->size_mask))];
485 i++;
486 }
487 } else {
488 while (i < r->rotors) {
489 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) % r->size))];
490 i++;
491 }
492 }
493 RTR_advance(r);
494 return ((unsigned char)tp);
495}
496
497/*(defun RTR-d-char (c)
498 "Decrypt the character C with the current rotor machine"
499 (let ((i (- RTR-number-of-rotors 1)))
500 (if RTR-size-mask
501 (while (<= 0 i)
502 (setq c (logand (logxor (aref RTR-positions i)
503 (aref (aref RTR-d-rotors i)
504 c))
505 RTR-size-mask))
506 (setq i (- i 1)))
507 (while (<= 0 i)
508 (setq c (% (logxor (aref RTR-positions i)
509 (aref (aref RTR-d-rotors i)
510 c))
511 RTR-size))
512 (setq i (- i 1))))
513 (RTR-advance)
514 c))*/
515static unsigned char RTR_d_char(r, c)
516 rotorobject *r;
517 unsigned char c;
518{
519 register int i=r->rotors - 1;
520 register unsigned char tc=c;
521 if (r->size_mask) {
522 while (0 <= i) {
523 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) & r->size_mask;
524 i--;
525 }
526 } else {
527 while (0 <= i) {
528 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) % r->size;
529 i--;
530 }
531 }
532 RTR_advance(r);
533 return(tc);
534}
535
536/*(defun RTR-e-region (beg end key)
537 "Perform a rotor encryption of the region from BEG to END by KEY"
538 (save-excursion
539 (let ((tenth (/ (- end beg) 10)))
540 (RTR-init key)
541 (goto-char beg)
542 ;; ### make it stop evry 10% or so to tell us
543 (while (< (point) end)
544 (let ((fc (following-char)))
545 (insert-char (RTR-e-char fc) 1)
546 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000547static void RTR_e_region(r, beg, len, doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000548 rotorobject *r;
549 unsigned char *beg;
550 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000551 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000552{
553 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000554 if (doinit || r->isinited == FALSE)
555 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000556 for (i=0;i<len;i++) {
557 beg[i]=RTR_e_char(r,beg[i]);
558 }
559}
560
561/*(defun RTR-d-region (beg end key)
562 "Perform a rotor decryption of the region from BEG to END by KEY"
563 (save-excursion
564 (progn
565 (RTR-init key)
566 (goto-char beg)
567 (while (< (point) end)
568 (let ((fc (following-char)))
569 (insert-char (RTR-d-char fc) 1)
570 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000571void static RTR_d_region(r, beg, len, doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000572 rotorobject *r;
573 unsigned char *beg;
574 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000575 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000576{
577 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000578 if (doinit || r->isinited == FALSE)
579 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000580 for (i=0;i<len;i++) {
581 beg[i]=RTR_d_char(r,beg[i]);
582 }
583}
584
585
586/*(defun RTR-key-string-to-ints (key)
587 "Convert a string into a list of 4 numbers"
588 (let ((k1 995)
589 (k2 576)
590 (k3 767)
591 (k4 671)
592 (k5 463)
593 (i 0))
594 (while (< i (length key))
595 (setq k1 (logand (+ (logior (lsh k1 3) (lsh k1 -13)) (aref key i)) 65535))
596 (setq k2 (logand (logxor (logior (lsh k2 3) (lsh k2 -13)) (aref key i)) 65535))
597 (setq k3 (logand (- (logior (lsh k3 3) (lsh k3 -13)) (aref key i)) 65535))
598 (setq k4 (logand (- (aref key i) (logior (lsh k4 3) (lsh k4 -13))) 65535))
599 (setq k5 (logand (logxor (logior (lsh k5 3) (lsh k5 -13)) (lognot (aref key i))) 65535))
600 (setq i (+ i 1)))
601 (list k1 (logior 1 k2) k3 k4 k5)))*/
602/* This is done in set_key() above */
603
604/*(defun encrypt-region (beg end key)
605 "Interactivly encrypt the region"
606 (interactive "r\nsKey:")
607 (RTR-e-region beg end (RTR-key-string-to-ints key)))*/
608static void encrypt_region(r, region, len)
609 rotorobject *r;
610 unsigned char *region;
611 int len;
612{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000613 RTR_e_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000614}
615
616/*(defun decrypt-region (beg end key)
617 "Interactivly decrypt the region"
618 (interactive "r\nsKey:")
619 (RTR-d-region beg end (RTR-key-string-to-ints key)))*/
620static void decrypt_region(r, region, len)
621 rotorobject *r;
622 unsigned char *region;
623 int len;
624{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000625 RTR_d_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000626}
627
628/* Rotor methods */
629
630static void
631rotor_dealloc(xp)
632 rotorobject *xp;
633{
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000634 XDEL(xp->e_rotor);
635 XDEL(xp->d_rotor);
636 XDEL(xp->positions);
637 XDEL(xp->advances);
Guido van Rossum50098201992-07-31 15:10:13 +0000638 DEL(xp);
639}
640
641static object *
642rotor_encrypt(self, args)
643 rotorobject *self;
644 object *args;
645{
646 char *string = (char *)NULL;
647 int len = 0;
648 object *rtn = (object *)NULL;
649 char *tmp;
650
651 if (!getargs(args,"s#",&string, &len))
652 return NULL;
653 if (!(tmp = (char *)malloc(len+5))) {
654 err_nomem();
655 return NULL;
656 }
657 memset(tmp,'\0',len+1);
658 memcpy(tmp,string,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000659 RTR_e_region(self,tmp,len, TRUE);
660 rtn = newsizedstringobject(tmp,len);
661 free(tmp);
662 return(rtn);
663}
664
665static object *
666rotor_encryptmore(self, args)
667 rotorobject *self;
668 object *args;
669{
670 char *string = (char *)NULL;
671 int len = 0;
672 object *rtn = (object *)NULL;
673 char *tmp;
674
675 if (!getargs(args,"s#",&string, &len))
676 return NULL;
677 if (!(tmp = (char *)malloc(len+5))) {
678 err_nomem();
679 return NULL;
680 }
681 memset(tmp,'\0',len+1);
682 memcpy(tmp,string,len);
683 RTR_e_region(self,tmp,len, FALSE);
Guido van Rossum50098201992-07-31 15:10:13 +0000684 rtn = newsizedstringobject(tmp,len);
685 free(tmp);
686 return(rtn);
687}
688
689static object *
690rotor_decrypt(self, args)
691 rotorobject *self;
692 object *args;
693{
694 char *string = (char *)NULL;
695 int len = 0;
696 object *rtn = (object *)NULL;
697 char *tmp;
698
699 if (!getargs(args,"s#",&string, &len))
700 return NULL;
701 if (!(tmp = (char *)malloc(len+5))) {
702 err_nomem();
703 return NULL;
704 }
705 memset(tmp,'\0',len+1);
706 memcpy(tmp,string,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000707 RTR_d_region(self,tmp,len, TRUE);
708 rtn = newsizedstringobject(tmp,len);
709 free(tmp);
710 return(rtn);
711}
712
713static object *
714rotor_decryptmore(self, args)
715 rotorobject *self;
716 object *args;
717{
718 char *string = (char *)NULL;
719 int len = 0;
720 object *rtn = (object *)NULL;
721 char *tmp;
722
723 if (!getargs(args,"s#",&string, &len))
724 return NULL;
725 if (!(tmp = (char *)malloc(len+5))) {
726 err_nomem();
727 return NULL;
728 }
729 memset(tmp,'\0',len+1);
730 memcpy(tmp,string,len);
731 RTR_d_region(self,tmp,len, FALSE);
Guido van Rossum50098201992-07-31 15:10:13 +0000732 rtn = newsizedstringobject(tmp,len);
733 free(tmp);
734 return(rtn);
735}
736
737static object *
738rotor_setkey(self, args)
739 rotorobject *self;
740 object *args;
741{
742 char *key;
743 char *string;
744
745 if (getargs(args,"s",&string))
746 set_key(self,string);
747 INCREF(None);
748 return None;
749}
750
751static struct methodlist rotor_methods[] = {
752 {"encrypt", rotor_encrypt},
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000753 {"encryptmore", rotor_encryptmore},
Guido van Rossum50098201992-07-31 15:10:13 +0000754 {"decrypt", rotor_decrypt},
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000755 {"decryptmore", rotor_decryptmore},
Guido van Rossum50098201992-07-31 15:10:13 +0000756 {"setkey", rotor_setkey},
757 {NULL, NULL} /* sentinel */
758};
759
760
761/* Return a rotor object's named attribute. */
762static object *
763rotor_getattr(s, name)
764 rotorobject *s;
765 char *name;
766{
767 return findmethod(rotor_methods, (object *) s, name);
768}
769
770static typeobject Rotortype = {
771 OB_HEAD_INIT(&Typetype)
772 0, /*ob_size*/
773 "rotor", /*tp_name*/
774 sizeof(rotorobject), /*tp_size*/
775 0, /*tp_itemsize*/
776 /* methods */
777 rotor_dealloc, /*tp_dealloc*/
778 0, /*tp_print*/
779 rotor_getattr, /*tp_getattr*/
780 0, /*tp_setattr*/
781 0, /*tp_compare*/
782 0, /*tp_repr*/
783};
784
785
Guido van Rossum234f9421993-06-17 12:35:49 +0000786static object *
787rotor_rotor(self, args)
788 object *self;
789 object *args;
Guido van Rossum50098201992-07-31 15:10:13 +0000790{
791 char *string;
792 rotorobject *r;
793 int len;
794 int num_rotors;
795
796 if (getargs(args,"s#", &string, &len)) {
797 num_rotors = 6;
798 } else {
799 err_clear();
800 if (!getargs(args,"(s#i)", &string, &len, &num_rotors))
801 return NULL;
802 }
803 r = newrotorobject(num_rotors, string);
804 return (object *)r;
805}
806
807static struct methodlist rotor_rotor_methods[] = {
808 {"newrotor", rotor_rotor},
809 {NULL, NULL} /* Sentinel */
810};
811
812
813/* Initialize this module.
814 This is called when the first 'import rotor' is done,
815 via a table in config.c, if config.c is compiled with USE_ROTOR
816 defined. */
817
818void
819initrotor()
820{
821 object *m;
822
823 m = initmodule("rotor", rotor_rotor_methods);
824}