blob: da5ed106743e0bb290eeeeb6490860d2a5afaf2e [file] [log] [blame]
Guido van Rossum50098201992-07-31 15:10:13 +00001/***********************************************************
Guido van Rossumf6971e21994-08-30 12:25:20 +00002Copyright 1994 by Lance Ellinghouse,
3Cathedral City, California Republic, United States of America.
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
Guido van Rossumf6971e21994-08-30 12:25:20 +000011supporting documentation, and that the name of Lance Ellinghouse
12not be used in advertising or publicity pertaining to distribution
13of the software without specific, written prior permission.
Guido van Rossum50098201992-07-31 15:10:13 +000014
Guido van Rossumf6971e21994-08-30 12:25:20 +000015LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
Guido van Rossum50098201992-07-31 15:10:13 +000016THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
Guido van Rossumf6971e21994-08-30 12:25:20 +000017FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL,
18INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
19FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum50098201992-07-31 15:10:13 +000022
23******************************************************************/
24
25/* This creates an encryption and decryption engine I am calling
26 a rotor due to the original design was a harware rotor with
27 contacts used in Germany during WWII.
28
29Rotor Module:
30
31- rotor.newrotor('key') -> rotorobject (default of 6 rotors)
32- rotor.newrotor('key', num_rotors) -> rotorobject
33
34Rotor Objects:
35
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000036- ro.setkey('string') -> None (resets the key as defined in newrotor().
Guido van Rossum50098201992-07-31 15:10:13 +000037- ro.encrypt('string') -> encrypted string
38- ro.decrypt('encrypted string') -> unencrypted string
39
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000040- ro.encryptmore('string') -> encrypted string
41- ro.decryptmore('encrypted string') -> unencrypted string
42
43NOTE: the {en,de}cryptmore() methods use the setup that was
44 established via the {en,de}crypt calls. They will NOT
45 re-initalize the rotors unless: 1) They have not been
46 initalized with {en,de}crypt since the last setkey() call;
47 2) {en,de}crypt has not been called for this rotor yet.
48
Guido van Rossum50098201992-07-31 15:10:13 +000049NOTE: you MUST use the SAME key in rotor.newrotor()
50 if you wish to decrypt an encrypted string.
51 Also, the encrypted string is NOT 0-127 ASCII.
52 It is considered BINARY data.
53
54*/
55
56/* Rotor objects */
57
58#include "allobjects.h"
59#include "modsupport.h"
60#include <stdio.h>
61#include <math.h>
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000062#define TRUE 1
63#define FALSE 0
Guido van Rossum50098201992-07-31 15:10:13 +000064
Guido van Rossum7b1e9741994-08-29 10:46:42 +000065/* This is temp until the renaming effort is done with Python */
66#include "rename1.h"
67
Guido van Rossum50098201992-07-31 15:10:13 +000068typedef struct {
Guido van Rossum7b1e9741994-08-29 10:46:42 +000069 PyObject_HEAD
Guido van Rossum50098201992-07-31 15:10:13 +000070 int seed[3];
71 short key[5];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000072 int isinited;
Guido van Rossum50098201992-07-31 15:10:13 +000073 int size;
74 int size_mask;
75 int rotors;
76 unsigned char *e_rotor; /* [num_rotors][size] */
77 unsigned char *d_rotor; /* [num_rotors][size] */
78 unsigned char *positions; /* [num_rotors] */
79 unsigned char *advances; /* [num_rotors] */
Guido van Rossum7b1e9741994-08-29 10:46:42 +000080} PyRotorObject;
Guido van Rossum50098201992-07-31 15:10:13 +000081
Guido van Rossum7b1e9741994-08-29 10:46:42 +000082staticforward PyTypeObject PyRotor_Type;
Guido van Rossum50098201992-07-31 15:10:13 +000083
Guido van Rossum7b1e9741994-08-29 10:46:42 +000084#define PyRotor_Check(v) ((v)->ob_type == &PyRotor_Type)
Guido van Rossum50098201992-07-31 15:10:13 +000085
86/*
87 This defines the necessary routines to manage rotor objects
88*/
89
90static void set_seed( r )
Guido van Rossum7b1e9741994-08-29 10:46:42 +000091PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +000092{
93 r->seed[0] = r->key[0];
94 r->seed[1] = r->key[1];
95 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000096 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +000097}
98
99/* Return the next random number in the range [0.0 .. 1.0) */
100static float r_random( r )
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000101PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000102{
103 int x, y, z;
104 float val, term;
105
106 x = r->seed[0];
107 y = r->seed[1];
108 z = r->seed[2];
109
110 x = 171 * (x % 177) - 2 * (x/177);
111 y = 172 * (y % 176) - 35 * (y/176);
112 z = 170 * (z % 178) - 63 * (z/178);
113
114 if (x < 0) x = x + 30269;
115 if (y < 0) y = y + 30307;
116 if (z < 0) z = z + 30323;
117
118 r->seed[0] = x;
119 r->seed[1] = y;
120 r->seed[2] = z;
121
122 term = (float)(
123 (((float)x)/(float)30269.0) +
124 (((float)y)/(float)30307.0) +
125 (((float)z)/(float)30323.0)
126 );
127 val = term - (float)floor((double)term);
128
129 if (val >= 1.0) val = 0.0;
130
131 return val;
132}
133
134static short r_rand(r,s)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000135PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000136short s;
137{
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000138 /*short tmp = (short)((int)(r_random(r) * (float)32768.0) % 32768);*/
Guido van Rossum50098201992-07-31 15:10:13 +0000139 short tmp = (short)((short)(r_random(r) * (float)s) % s);
140 return tmp;
141}
142
143static void set_key(r, key)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000144PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000145char *key;
146{
Guido van Rossume77a7571993-11-03 15:01:26 +0000147#ifdef BUGGY_CODE_BW_COMPAT
148 /* See comments below */
Guido van Rossum50098201992-07-31 15:10:13 +0000149 int k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossume77a7571993-11-03 15:01:26 +0000150#else
151 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
152#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000153 int i;
154 int len=strlen(key);
155 for (i=0;i<len;i++) {
Guido van Rossum06676261993-11-01 16:20:18 +0000156#ifdef BUGGY_CODE_BW_COMPAT
157 /* This is the code as it was originally released.
158 It causes warnings on many systems and can generate
159 different results as well. If you have files
160 encrypted using an older version you may want to
161 #define BUGGY_CODE_BW_COMPAT so as to be able to
162 decrypt them... */
Guido van Rossum50098201992-07-31 15:10:13 +0000163 k1 = (((k1<<3 | k1<<-13) + key[i]) & 65535);
164 k2 = (((k2<<3 | k2<<-13) ^ key[i]) & 65535);
165 k3 = (((k3<<3 | k3<<-13) - key[i]) & 65535);
166 k4 = ((key[i] - (k4<<3 | k4<<-13)) & 65535);
167 k5 = (((k5<<3 | k5<<-13) ^ ~key[i]) & 65535);
Guido van Rossum06676261993-11-01 16:20:18 +0000168#else
169 /* This code should be more portable */
170 k1 = (((k1<<3 | k1>>13) + key[i]) & 65535);
171 k2 = (((k2<<3 | k2>>13) ^ key[i]) & 65535);
172 k3 = (((k3<<3 | k3>>13) - key[i]) & 65535);
173 k4 = ((key[i] - (k4<<3 | k4>>13)) & 65535);
174 k5 = (((k5<<3 | k5>>13) ^ ~key[i]) & 65535);
175#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000176 }
177 r->key[0] = (short)k1;
178 r->key[1] = (short)(k2|1);
179 r->key[2] = (short)k3;
180 r->key[3] = (short)k4;
181 r->key[4] = (short)k5;
182
183 set_seed(r);
184}
185
186/* These define the interface to a rotor object */
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000187static PyRotorObject *
188PyRotor_New(num_rotors, key)
Guido van Rossum50098201992-07-31 15:10:13 +0000189 int num_rotors;
190 char *key;
191{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000192 PyRotorObject *xp;
193 xp = PyObject_NEW(PyRotorObject, &PyRotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000194 if (xp == NULL)
195 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000196 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000197
198 xp->size = 256;
199 xp->size_mask = xp->size - 1;
200 xp->size_mask = 0;
201 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000202 xp->e_rotor = NULL;
203 xp->d_rotor = NULL;
204 xp->positions = NULL;
205 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000206
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000207 xp->e_rotor =
208 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
209 if (xp->e_rotor == (unsigned char *)NULL)
210 goto fail;
211 xp->d_rotor =
212 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
213 if (xp->d_rotor == (unsigned char *)NULL)
214 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000215 xp->positions = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000216 if (xp->positions == (unsigned char *)NULL)
217 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000218 xp->advances = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000219 if (xp->advances == (unsigned char *)NULL)
220 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000221 return xp;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000222fail:
223 DECREF(xp);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000224 return (PyRotorObject *)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000225}
226
227/* These routines impliment the rotor itself */
228
229/* Here is a fairly sofisticated {en,de}cryption system. It is bassed
230on the idea of a "rotor" machine. A bunch of rotors, each with a
231different permutation of the alphabet, rotate around a different
232amount after encrypting one character. The current state of the
233rotors is used to encrypt one character.
234
235 The code is smart enought to tell if your alphabet has a number of
236characters equal to a power of two. If it does, it uses logical
237operations, if not it uses div and mod (both require a division).
238
239 You will need to make two changes to the code 1) convert to c, and
240customize for an alphabet of 255 chars 2) add a filter at the
241begining, and end, which subtracts one on the way in, and adds one on
242the way out.
243
244 You might wish to do some timing studies. Another viable
245alternative is to "byte stuff" the encrypted data of a normal (perhaps
246this one) encryption routine.
247
248j'
249*/
250
251/*(defun RTR-make-id-rotor (rotor)
252 "Set ROTOR to the identity permutation"
253 (let ((j 0))
254 (while (< j RTR-size)
255 (aset rotor j j)
256 (setq j (+ 1 j)))
257 rotor))*/
258static void RTR_make_id_rotor(r, rtr)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000259 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000260 unsigned char *rtr;
261{
262 register int j;
263 register int size = r->size;
264 for (j=0;j<size;j++) {
265 rtr[j] = (unsigned char)j;
266 }
267}
268
269
270/*(defvar RTR-e-rotors
271 (let ((rv (make-vector RTR-number-of-rotors 0))
272 (i 0)
273 tr)
274 (while (< i RTR-number-of-rotors)
275 (setq tr (make-vector RTR-size 0))
276 (RTR-make-id-rotor tr)
277 (aset rv i tr)
278 (setq i (+ 1 i)))
279 rv)
280 "The current set of encryption rotors")*/
281static void RTR_e_rotors(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000282 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000283{
284 int i;
285 for (i=0;i<r->rotors;i++) {
286 RTR_make_id_rotor(r,&(r->e_rotor[(i*r->size)]));
287 }
288}
289
290/*(defvar RTR-d-rotors
291 (let ((rv (make-vector RTR-number-of-rotors 0))
292 (i 0)
293 tr)
294 (while (< i RTR-number-of-rotors)
295 (setq tr (make-vector RTR-size 0))
296 (setq j 0)
297 (while (< j RTR-size)
298 (aset tr j j)
299 (setq j (+ 1 j)))
300 (aset rv i tr)
301 (setq i (+ 1 i)))
302 rv)
303 "The current set of decryption rotors")*/
304static void RTR_d_rotors(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000305 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000306{
307 register int i, j;
308 for (i=0;i<r->rotors;i++) {
309 for (j=0;j<r->size;j++) {
310 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
311 }
312 }
313}
314
315/*(defvar RTR-positions (make-vector RTR-number-of-rotors 1)
316 "The positions of the rotors at this time")*/
317static void RTR_positions(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000318 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000319{
320 int i;
321 for (i=0;i<r->rotors;i++) {
322 r->positions[i] = 1;
323 }
324}
325
326/*(defvar RTR-advances (make-vector RTR-number-of-rotors 1)
327 "The number of positions to advance the rotors at a time")*/
328static void RTR_advances(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000329 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000330{
331 int i;
332 for (i=0;i<r->rotors;i++) {
333 r->advances[i] = 1;
334 }
335}
336
337/*(defun RTR-permute-rotor (e d)
338 "Permute the E rotor, and make the D rotor its inverse"
339 ;; see Knuth for explaination of algorythm.
340 (RTR-make-id-rotor e)
341 (let ((i RTR-size)
342 q j)
343 (while (<= 2 i)
344 (setq q (fair16 i)) ; a little tricky, decrement here
345 (setq i (- i 1)) ; since we have origin 0 array's
346 (setq j (aref e q))
347 (aset e q (aref e i))
348 (aset e i j)
349 (aset d j i))
350 (aset e 0 (aref e 0)) ; don't forget e[0] and d[0]
351 (aset d (aref e 0) 0)))*/
352static void RTR_permute_rotor(r, e, d)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000353 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000354 unsigned char *e;
355 unsigned char *d;
356{
357 short i = r->size;
358 short q;
359 unsigned char j;
360 RTR_make_id_rotor(r,e);
361 while (2 <= i) {
362 q = r_rand(r,i);
363 i--;
364 j = e[q];
365 e[q] = (unsigned char)e[i];
366 e[i] = (unsigned char)j;
367 d[j] = (unsigned char)i;
368 }
369 e[0] = (unsigned char)e[0];
370 d[(e[0])] = (unsigned char)0;
371}
372
373/*(defun RTR-init (key)
374 "Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
375Set the advancement, position, and permutation of the rotors"
376 (R16-set-state key)
377 (let (i)
378 (setq i 0)
379 (while (< i RTR-number-of-rotors)
380 (aset RTR-positions i (fair16 RTR-size))
381 (aset RTR-advances i (+ 1 (* 2 (fair16 (/ RTR-size 2)))))
382 (message "Initializing rotor %d..." i)
383 (RTR-permute-rotor (aref RTR-e-rotors i) (aref RTR-d-rotors i))
384 (setq i (+ 1 i)))))*/
385static void RTR_init(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000386 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000387{
388 int i;
389 set_seed(r);
390 RTR_positions(r);
391 RTR_advances(r);
392 RTR_e_rotors(r);
393 RTR_d_rotors(r);
394 for(i=0;i<r->rotors;i++) {
395 r->positions[i] = r_rand(r,r->size);
396 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
397 RTR_permute_rotor(r,&(r->e_rotor[(i*r->size)]),&(r->d_rotor[(i*r->size)]));
398 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000399 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000400}
401
402/*(defun RTR-advance ()
403 "Change the RTR-positions vector, using the RTR-advances vector"
404 (let ((i 0)
405 (temp 0))
406 (if RTR-size-mask
407 (while (< i RTR-number-of-rotors)
408 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
409 (aset RTR-positions i (logand temp RTR-size-mask))
410 (if (and (>= temp RTR-size)
411 (< i (- RTR-number-of-rotors 1)))
412 (aset RTR-positions (+ i 1)
413 (+ 1 (aref RTR-positions (+ i 1)))))
414 (setq i (+ i 1)))
415 (while (< i RTR-number-of-rotors)
416 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
417 (aset RTR-positions i (% temp RTR-size))
418 (if (and (>= temp RTR-size)
419 (< i (- RTR-number-of-rotors 1)))
420 (aset RTR-positions (+ i 1)
421 (+ 1 (aref RTR-positions (+ i 1)))))
422 (setq i (+ i 1))))))*/
423static void RTR_advance(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000424 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000425{
426 register int i=0, temp=0;
427 if (r->size_mask) {
428 while (i<r->rotors) {
429 temp = r->positions[i] + r->advances[i];
430 r->positions[i] = temp & r->size_mask;
431 if ((temp >= r->size) && (i < (r->rotors - 1))) {
432 r->positions[(i+1)] = 1 + r->positions[(i+1)];
433 }
434 i++;
435 }
436 } else {
437 while (i<r->rotors) {
438 temp = r->positions[i] + r->advances[i];
439 r->positions[i] = temp%r->size;
440 if ((temp >= r->size) && (i < (r->rotors - 1))) {
441 r->positions[(i+1)] = 1 + r->positions[(i+1)];
442 }
443 i++;
444 }
445 }
446}
447
448/*(defun RTR-e-char (p)
449 "Encrypt the character P with the current rotor machine"
450 (let ((i 0))
451 (if RTR-size-mask
452 (while (< i RTR-number-of-rotors)
453 (setq p (aref (aref RTR-e-rotors i)
454 (logand (logxor (aref RTR-positions i)
455 p)
456 RTR-size-mask)))
457 (setq i (+ 1 i)))
458 (while (< i RTR-number-of-rotors)
459 (setq p (aref (aref RTR-e-rotors i)
460 (% (logxor (aref RTR-positions i)
461 p)
462 RTR-size)))
463 (setq i (+ 1 i))))
464 (RTR-advance)
465 p))*/
466static unsigned char RTR_e_char(r, p)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000467 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000468 unsigned char p;
469{
470 register int i=0;
471 register unsigned char tp=p;
472 if (r->size_mask) {
473 while (i < r->rotors) {
474 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) & r->size_mask))];
475 i++;
476 }
477 } else {
478 while (i < r->rotors) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000479 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) % (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000480 i++;
481 }
482 }
483 RTR_advance(r);
484 return ((unsigned char)tp);
485}
486
487/*(defun RTR-d-char (c)
488 "Decrypt the character C with the current rotor machine"
489 (let ((i (- RTR-number-of-rotors 1)))
490 (if RTR-size-mask
491 (while (<= 0 i)
492 (setq c (logand (logxor (aref RTR-positions i)
493 (aref (aref RTR-d-rotors i)
494 c))
495 RTR-size-mask))
496 (setq i (- i 1)))
497 (while (<= 0 i)
498 (setq c (% (logxor (aref RTR-positions i)
499 (aref (aref RTR-d-rotors i)
500 c))
501 RTR-size))
502 (setq i (- i 1))))
503 (RTR-advance)
504 c))*/
505static unsigned char RTR_d_char(r, c)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000506 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000507 unsigned char c;
508{
509 register int i=r->rotors - 1;
510 register unsigned char tc=c;
511 if (r->size_mask) {
512 while (0 <= i) {
513 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) & r->size_mask;
514 i--;
515 }
516 } else {
517 while (0 <= i) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000518 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) % (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000519 i--;
520 }
521 }
522 RTR_advance(r);
523 return(tc);
524}
525
526/*(defun RTR-e-region (beg end key)
527 "Perform a rotor encryption of the region from BEG to END by KEY"
528 (save-excursion
529 (let ((tenth (/ (- end beg) 10)))
530 (RTR-init key)
531 (goto-char beg)
532 ;; ### make it stop evry 10% or so to tell us
533 (while (< (point) end)
534 (let ((fc (following-char)))
535 (insert-char (RTR-e-char fc) 1)
536 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000537static void RTR_e_region(r, beg, len, doinit)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000538 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000539 unsigned char *beg;
540 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000541 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000542{
543 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000544 if (doinit || r->isinited == FALSE)
545 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000546 for (i=0;i<len;i++) {
547 beg[i]=RTR_e_char(r,beg[i]);
548 }
549}
550
551/*(defun RTR-d-region (beg end key)
552 "Perform a rotor decryption of the region from BEG to END by KEY"
553 (save-excursion
554 (progn
555 (RTR-init key)
556 (goto-char beg)
557 (while (< (point) end)
558 (let ((fc (following-char)))
559 (insert-char (RTR-d-char fc) 1)
560 (delete-char 1))))))*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000561static void RTR_d_region(r, beg, len, doinit)
562 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000563 unsigned char *beg;
564 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000565 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000566{
567 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000568 if (doinit || r->isinited == FALSE)
569 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000570 for (i=0;i<len;i++) {
571 beg[i]=RTR_d_char(r,beg[i]);
572 }
573}
574
575
576/*(defun RTR-key-string-to-ints (key)
577 "Convert a string into a list of 4 numbers"
578 (let ((k1 995)
579 (k2 576)
580 (k3 767)
581 (k4 671)
582 (k5 463)
583 (i 0))
584 (while (< i (length key))
585 (setq k1 (logand (+ (logior (lsh k1 3) (lsh k1 -13)) (aref key i)) 65535))
586 (setq k2 (logand (logxor (logior (lsh k2 3) (lsh k2 -13)) (aref key i)) 65535))
587 (setq k3 (logand (- (logior (lsh k3 3) (lsh k3 -13)) (aref key i)) 65535))
588 (setq k4 (logand (- (aref key i) (logior (lsh k4 3) (lsh k4 -13))) 65535))
589 (setq k5 (logand (logxor (logior (lsh k5 3) (lsh k5 -13)) (lognot (aref key i))) 65535))
590 (setq i (+ i 1)))
591 (list k1 (logior 1 k2) k3 k4 k5)))*/
592/* This is done in set_key() above */
593
594/*(defun encrypt-region (beg end key)
595 "Interactivly encrypt the region"
596 (interactive "r\nsKey:")
597 (RTR-e-region beg end (RTR-key-string-to-ints key)))*/
598static void encrypt_region(r, region, len)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000599 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000600 unsigned char *region;
601 int len;
602{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000603 RTR_e_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000604}
605
606/*(defun decrypt-region (beg end key)
607 "Interactivly decrypt the region"
608 (interactive "r\nsKey:")
609 (RTR-d-region beg end (RTR-key-string-to-ints key)))*/
610static void decrypt_region(r, region, len)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000611 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000612 unsigned char *region;
613 int len;
614{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000615 RTR_d_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000616}
617
618/* Rotor methods */
619
620static void
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000621PyRotor_Dealloc(xp)
622 PyRotorObject *xp;
Guido van Rossum50098201992-07-31 15:10:13 +0000623{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000624 PyMem_XDEL(xp->e_rotor);
625 PyMem_XDEL(xp->d_rotor);
626 PyMem_XDEL(xp->positions);
627 PyMem_XDEL(xp->advances);
628 PyMem_DEL(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000629}
630
Guido van Rossumf6971e21994-08-30 12:25:20 +0000631static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000632PyRotor_Encrypt(self, args)
633 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000634 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000635{
636 char *string = (char *)NULL;
637 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000638 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000639 char *tmp;
640
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000641 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000642 return NULL;
643 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000644 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000645 return NULL;
646 }
647 memset(tmp,'\0',len+1);
648 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000649 RTR_e_region(self,(unsigned char *)tmp,len, TRUE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000650 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000651 free(tmp);
652 return(rtn);
653}
654
Guido van Rossumf6971e21994-08-30 12:25:20 +0000655static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000656PyRotor_EncryptMore(self, args)
657 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000658 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000659{
660 char *string = (char *)NULL;
661 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000662 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000663 char *tmp;
664
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000665 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000666 return NULL;
667 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000668 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000669 return NULL;
670 }
671 memset(tmp,'\0',len+1);
672 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000673 RTR_e_region(self,(unsigned char *)tmp,len, FALSE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000674 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum50098201992-07-31 15:10:13 +0000675 free(tmp);
676 return(rtn);
677}
678
Guido van Rossumf6971e21994-08-30 12:25:20 +0000679static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000680PyRotor_Decrypt(self, args)
681 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000682 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000683{
684 char *string = (char *)NULL;
685 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000686 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000687 char *tmp;
688
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000689 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000690 return NULL;
691 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000692 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000693 return NULL;
694 }
695 memset(tmp,'\0',len+1);
696 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000697 RTR_d_region(self,(unsigned char *)tmp,len, TRUE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000698 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000699 free(tmp);
700 return(rtn);
701}
702
Guido van Rossumf6971e21994-08-30 12:25:20 +0000703static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000704PyRotor_DecryptMore(self, args)
705 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000706 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000707{
708 char *string = (char *)NULL;
709 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000710 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000711 char *tmp;
712
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000713 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000714 return NULL;
715 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000716 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000717 return NULL;
718 }
719 memset(tmp,'\0',len+1);
720 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000721 RTR_d_region(self,(unsigned char *)tmp,len, FALSE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000722 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum50098201992-07-31 15:10:13 +0000723 free(tmp);
724 return(rtn);
725}
726
Guido van Rossumf6971e21994-08-30 12:25:20 +0000727static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000728PyRotor_SetKey(self, args)
729 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000730 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000731{
732 char *key;
733 char *string;
734
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000735 if (PyArg_Parse(args,"s",&string))
Guido van Rossum50098201992-07-31 15:10:13 +0000736 set_key(self,string);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000737 Py_INCREF(Py_None);
738 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000739}
740
Guido van Rossumf6971e21994-08-30 12:25:20 +0000741static struct methodlist PyRotor_Methods[] = {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000742 {"encrypt", (PyCFunction)PyRotor_Encrypt},
743 {"encryptmore", (PyCFunction)PyRotor_EncryptMore},
744 {"decrypt", (PyCFunction)PyRotor_Decrypt},
745 {"decryptmore", (PyCFunction)PyRotor_DecryptMore},
746 {"setkey", (PyCFunction)PyRotor_SetKey},
Guido van Rossum50098201992-07-31 15:10:13 +0000747 {NULL, NULL} /* sentinel */
748};
749
750
751/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000752static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000753PyRotor_GetAttr(s, name)
754 PyRotorObject *s;
Guido van Rossum50098201992-07-31 15:10:13 +0000755 char *name;
756{
Guido van Rossumf6971e21994-08-30 12:25:20 +0000757 return Py_FindMethod(PyRotor_Methods, (PyObject * ) s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000758}
759
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000760static PyTypeObject PyRotor_Type = {
761 PyObject_HEAD_INIT(&Typetype)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000762 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000763 "rotor", /*tp_name*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000764 sizeof(PyRotorObject), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000765 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000766 /* methods */
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000767 (destructor)PyRotor_Dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000768 0, /*tp_print*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000769 (getattrfunc)PyRotor_GetAttr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000770 0, /*tp_setattr*/
771 0, /*tp_compare*/
772 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000773 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000774};
775
776
Guido van Rossumf6971e21994-08-30 12:25:20 +0000777static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000778PyRotor_Rotor(self, args)
Guido van Rossumf6971e21994-08-30 12:25:20 +0000779 PyObject * self;
780 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000781{
782 char *string;
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000783 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000784 int len;
785 int num_rotors;
786
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000787 if (PyArg_Parse(args,"s#", &string, &len)) {
Guido van Rossum50098201992-07-31 15:10:13 +0000788 num_rotors = 6;
789 } else {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000790 PyErr_Clear();
791 if (!PyArg_Parse(args,"(s#i)", &string, &len, &num_rotors))
Guido van Rossum50098201992-07-31 15:10:13 +0000792 return NULL;
793 }
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000794 r = PyRotor_New(num_rotors, string);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000795 return (PyObject * )r;
Guido van Rossum50098201992-07-31 15:10:13 +0000796}
797
Guido van Rossumf6971e21994-08-30 12:25:20 +0000798static struct methodlist PyRotor_Rotor_Methods[] = {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000799 {"newrotor", (PyCFunction)PyRotor_Rotor},
Guido van Rossum50098201992-07-31 15:10:13 +0000800 {NULL, NULL} /* Sentinel */
801};
802
803
804/* Initialize this module.
805 This is called when the first 'import rotor' is done,
806 via a table in config.c, if config.c is compiled with USE_ROTOR
807 defined. */
808
809void
810initrotor()
811{
Guido van Rossumf6971e21994-08-30 12:25:20 +0000812 PyObject * m;
Guido van Rossum50098201992-07-31 15:10:13 +0000813
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000814 m = Py_InitModule("rotor", PyRotor_Rotor_Methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000815}