blob: 6988f881a515c631ba82df89592154e09bcaa314 [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
Guido van Rossum602099a1994-09-14 13:32:22 +000058#include "Python.h"
59
Guido van Rossuma320fd31995-03-09 12:14:15 +000060#include "mymath.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000061
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
65typedef struct {
Guido van Rossum7b1e9741994-08-29 10:46:42 +000066 PyObject_HEAD
Guido van Rossum50098201992-07-31 15:10:13 +000067 int seed[3];
68 short key[5];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000069 int isinited;
Guido van Rossum50098201992-07-31 15:10:13 +000070 int size;
71 int size_mask;
72 int rotors;
73 unsigned char *e_rotor; /* [num_rotors][size] */
74 unsigned char *d_rotor; /* [num_rotors][size] */
75 unsigned char *positions; /* [num_rotors] */
76 unsigned char *advances; /* [num_rotors] */
Guido van Rossum7b1e9741994-08-29 10:46:42 +000077} PyRotorObject;
Guido van Rossum50098201992-07-31 15:10:13 +000078
Guido van Rossum7b1e9741994-08-29 10:46:42 +000079staticforward PyTypeObject PyRotor_Type;
Guido van Rossum50098201992-07-31 15:10:13 +000080
Guido van Rossum7b1e9741994-08-29 10:46:42 +000081#define PyRotor_Check(v) ((v)->ob_type == &PyRotor_Type)
Guido van Rossum50098201992-07-31 15:10:13 +000082
83/*
84 This defines the necessary routines to manage rotor objects
85*/
86
87static void set_seed( r )
Guido van Rossum7b1e9741994-08-29 10:46:42 +000088PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +000089{
90 r->seed[0] = r->key[0];
91 r->seed[1] = r->key[1];
92 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000093 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +000094}
95
96/* Return the next random number in the range [0.0 .. 1.0) */
97static float r_random( r )
Guido van Rossum7b1e9741994-08-29 10:46:42 +000098PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +000099{
100 int x, y, z;
101 float val, term;
102
103 x = r->seed[0];
104 y = r->seed[1];
105 z = r->seed[2];
106
107 x = 171 * (x % 177) - 2 * (x/177);
108 y = 172 * (y % 176) - 35 * (y/176);
109 z = 170 * (z % 178) - 63 * (z/178);
110
111 if (x < 0) x = x + 30269;
112 if (y < 0) y = y + 30307;
113 if (z < 0) z = z + 30323;
114
115 r->seed[0] = x;
116 r->seed[1] = y;
117 r->seed[2] = z;
118
119 term = (float)(
120 (((float)x)/(float)30269.0) +
121 (((float)y)/(float)30307.0) +
122 (((float)z)/(float)30323.0)
123 );
124 val = term - (float)floor((double)term);
125
126 if (val >= 1.0) val = 0.0;
127
128 return val;
129}
130
131static short r_rand(r,s)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000132PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000133short s;
134{
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000135 /*short tmp = (short)((int)(r_random(r) * (float)32768.0) % 32768);*/
Guido van Rossum50098201992-07-31 15:10:13 +0000136 short tmp = (short)((short)(r_random(r) * (float)s) % s);
137 return tmp;
138}
139
140static void set_key(r, key)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000141PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000142char *key;
143{
Guido van Rossume77a7571993-11-03 15:01:26 +0000144#ifdef BUGGY_CODE_BW_COMPAT
145 /* See comments below */
Guido van Rossum50098201992-07-31 15:10:13 +0000146 int k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossume77a7571993-11-03 15:01:26 +0000147#else
148 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
149#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000150 int i;
151 int len=strlen(key);
152 for (i=0;i<len;i++) {
Guido van Rossum06676261993-11-01 16:20:18 +0000153#ifdef BUGGY_CODE_BW_COMPAT
154 /* This is the code as it was originally released.
155 It causes warnings on many systems and can generate
156 different results as well. If you have files
157 encrypted using an older version you may want to
158 #define BUGGY_CODE_BW_COMPAT so as to be able to
159 decrypt them... */
Guido van Rossum50098201992-07-31 15:10:13 +0000160 k1 = (((k1<<3 | k1<<-13) + key[i]) & 65535);
161 k2 = (((k2<<3 | k2<<-13) ^ key[i]) & 65535);
162 k3 = (((k3<<3 | k3<<-13) - key[i]) & 65535);
163 k4 = ((key[i] - (k4<<3 | k4<<-13)) & 65535);
164 k5 = (((k5<<3 | k5<<-13) ^ ~key[i]) & 65535);
Guido van Rossum06676261993-11-01 16:20:18 +0000165#else
166 /* This code should be more portable */
167 k1 = (((k1<<3 | k1>>13) + key[i]) & 65535);
168 k2 = (((k2<<3 | k2>>13) ^ key[i]) & 65535);
169 k3 = (((k3<<3 | k3>>13) - key[i]) & 65535);
170 k4 = ((key[i] - (k4<<3 | k4>>13)) & 65535);
171 k5 = (((k5<<3 | k5>>13) ^ ~key[i]) & 65535);
172#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000173 }
174 r->key[0] = (short)k1;
175 r->key[1] = (short)(k2|1);
176 r->key[2] = (short)k3;
177 r->key[3] = (short)k4;
178 r->key[4] = (short)k5;
179
180 set_seed(r);
181}
182
183/* These define the interface to a rotor object */
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000184static PyRotorObject *
185PyRotor_New(num_rotors, key)
Guido van Rossum50098201992-07-31 15:10:13 +0000186 int num_rotors;
187 char *key;
188{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000189 PyRotorObject *xp;
190 xp = PyObject_NEW(PyRotorObject, &PyRotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000191 if (xp == NULL)
192 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000193 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000194
195 xp->size = 256;
196 xp->size_mask = xp->size - 1;
197 xp->size_mask = 0;
198 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000199 xp->e_rotor = NULL;
200 xp->d_rotor = NULL;
201 xp->positions = NULL;
202 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000203
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000204 xp->e_rotor =
205 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
206 if (xp->e_rotor == (unsigned char *)NULL)
207 goto fail;
208 xp->d_rotor =
209 (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
210 if (xp->d_rotor == (unsigned char *)NULL)
211 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000212 xp->positions = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000213 if (xp->positions == (unsigned char *)NULL)
214 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000215 xp->advances = (unsigned char *)malloc(num_rotors * sizeof(char));
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000216 if (xp->advances == (unsigned char *)NULL)
217 goto fail;
Guido van Rossum50098201992-07-31 15:10:13 +0000218 return xp;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000219fail:
Guido van Rossuma597dde1995-01-10 20:56:29 +0000220 Py_DECREF(xp);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000221 return (PyRotorObject *)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000222}
223
224/* These routines impliment the rotor itself */
225
226/* Here is a fairly sofisticated {en,de}cryption system. It is bassed
227on the idea of a "rotor" machine. A bunch of rotors, each with a
228different permutation of the alphabet, rotate around a different
229amount after encrypting one character. The current state of the
230rotors is used to encrypt one character.
231
232 The code is smart enought to tell if your alphabet has a number of
233characters equal to a power of two. If it does, it uses logical
234operations, if not it uses div and mod (both require a division).
235
236 You will need to make two changes to the code 1) convert to c, and
237customize for an alphabet of 255 chars 2) add a filter at the
238begining, and end, which subtracts one on the way in, and adds one on
239the way out.
240
241 You might wish to do some timing studies. Another viable
242alternative is to "byte stuff" the encrypted data of a normal (perhaps
243this one) encryption routine.
244
245j'
246*/
247
248/*(defun RTR-make-id-rotor (rotor)
249 "Set ROTOR to the identity permutation"
250 (let ((j 0))
251 (while (< j RTR-size)
252 (aset rotor j j)
253 (setq j (+ 1 j)))
254 rotor))*/
255static void RTR_make_id_rotor(r, rtr)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000256 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000257 unsigned char *rtr;
258{
259 register int j;
260 register int size = r->size;
261 for (j=0;j<size;j++) {
262 rtr[j] = (unsigned char)j;
263 }
264}
265
266
267/*(defvar RTR-e-rotors
268 (let ((rv (make-vector RTR-number-of-rotors 0))
269 (i 0)
270 tr)
271 (while (< i RTR-number-of-rotors)
272 (setq tr (make-vector RTR-size 0))
273 (RTR-make-id-rotor tr)
274 (aset rv i tr)
275 (setq i (+ 1 i)))
276 rv)
277 "The current set of encryption rotors")*/
278static void RTR_e_rotors(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000279 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000280{
281 int i;
282 for (i=0;i<r->rotors;i++) {
283 RTR_make_id_rotor(r,&(r->e_rotor[(i*r->size)]));
284 }
285}
286
287/*(defvar RTR-d-rotors
288 (let ((rv (make-vector RTR-number-of-rotors 0))
289 (i 0)
290 tr)
291 (while (< i RTR-number-of-rotors)
292 (setq tr (make-vector RTR-size 0))
293 (setq j 0)
294 (while (< j RTR-size)
295 (aset tr j j)
296 (setq j (+ 1 j)))
297 (aset rv i tr)
298 (setq i (+ 1 i)))
299 rv)
300 "The current set of decryption rotors")*/
301static void RTR_d_rotors(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000302 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000303{
304 register int i, j;
305 for (i=0;i<r->rotors;i++) {
306 for (j=0;j<r->size;j++) {
307 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
308 }
309 }
310}
311
312/*(defvar RTR-positions (make-vector RTR-number-of-rotors 1)
313 "The positions of the rotors at this time")*/
314static void RTR_positions(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000315 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000316{
317 int i;
318 for (i=0;i<r->rotors;i++) {
319 r->positions[i] = 1;
320 }
321}
322
323/*(defvar RTR-advances (make-vector RTR-number-of-rotors 1)
324 "The number of positions to advance the rotors at a time")*/
325static void RTR_advances(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000326 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000327{
328 int i;
329 for (i=0;i<r->rotors;i++) {
330 r->advances[i] = 1;
331 }
332}
333
334/*(defun RTR-permute-rotor (e d)
335 "Permute the E rotor, and make the D rotor its inverse"
336 ;; see Knuth for explaination of algorythm.
337 (RTR-make-id-rotor e)
338 (let ((i RTR-size)
339 q j)
340 (while (<= 2 i)
341 (setq q (fair16 i)) ; a little tricky, decrement here
342 (setq i (- i 1)) ; since we have origin 0 array's
343 (setq j (aref e q))
344 (aset e q (aref e i))
345 (aset e i j)
346 (aset d j i))
347 (aset e 0 (aref e 0)) ; don't forget e[0] and d[0]
348 (aset d (aref e 0) 0)))*/
349static void RTR_permute_rotor(r, e, d)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000350 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000351 unsigned char *e;
352 unsigned char *d;
353{
354 short i = r->size;
355 short q;
356 unsigned char j;
357 RTR_make_id_rotor(r,e);
358 while (2 <= i) {
359 q = r_rand(r,i);
360 i--;
361 j = e[q];
362 e[q] = (unsigned char)e[i];
363 e[i] = (unsigned char)j;
364 d[j] = (unsigned char)i;
365 }
366 e[0] = (unsigned char)e[0];
367 d[(e[0])] = (unsigned char)0;
368}
369
370/*(defun RTR-init (key)
371 "Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
372Set the advancement, position, and permutation of the rotors"
373 (R16-set-state key)
374 (let (i)
375 (setq i 0)
376 (while (< i RTR-number-of-rotors)
377 (aset RTR-positions i (fair16 RTR-size))
378 (aset RTR-advances i (+ 1 (* 2 (fair16 (/ RTR-size 2)))))
379 (message "Initializing rotor %d..." i)
380 (RTR-permute-rotor (aref RTR-e-rotors i) (aref RTR-d-rotors i))
381 (setq i (+ 1 i)))))*/
382static void RTR_init(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000383 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000384{
385 int i;
386 set_seed(r);
387 RTR_positions(r);
388 RTR_advances(r);
389 RTR_e_rotors(r);
390 RTR_d_rotors(r);
391 for(i=0;i<r->rotors;i++) {
392 r->positions[i] = r_rand(r,r->size);
393 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
394 RTR_permute_rotor(r,&(r->e_rotor[(i*r->size)]),&(r->d_rotor[(i*r->size)]));
395 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000396 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000397}
398
399/*(defun RTR-advance ()
400 "Change the RTR-positions vector, using the RTR-advances vector"
401 (let ((i 0)
402 (temp 0))
403 (if RTR-size-mask
404 (while (< i RTR-number-of-rotors)
405 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
406 (aset RTR-positions i (logand temp RTR-size-mask))
407 (if (and (>= temp RTR-size)
408 (< i (- RTR-number-of-rotors 1)))
409 (aset RTR-positions (+ i 1)
410 (+ 1 (aref RTR-positions (+ i 1)))))
411 (setq i (+ i 1)))
412 (while (< i RTR-number-of-rotors)
413 (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
414 (aset RTR-positions i (% temp RTR-size))
415 (if (and (>= temp RTR-size)
416 (< i (- RTR-number-of-rotors 1)))
417 (aset RTR-positions (+ i 1)
418 (+ 1 (aref RTR-positions (+ i 1)))))
419 (setq i (+ i 1))))))*/
420static void RTR_advance(r)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000421 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000422{
423 register int i=0, temp=0;
424 if (r->size_mask) {
425 while (i<r->rotors) {
426 temp = r->positions[i] + r->advances[i];
427 r->positions[i] = temp & r->size_mask;
428 if ((temp >= r->size) && (i < (r->rotors - 1))) {
429 r->positions[(i+1)] = 1 + r->positions[(i+1)];
430 }
431 i++;
432 }
433 } else {
434 while (i<r->rotors) {
435 temp = r->positions[i] + r->advances[i];
436 r->positions[i] = temp%r->size;
437 if ((temp >= r->size) && (i < (r->rotors - 1))) {
438 r->positions[(i+1)] = 1 + r->positions[(i+1)];
439 }
440 i++;
441 }
442 }
443}
444
445/*(defun RTR-e-char (p)
446 "Encrypt the character P with the current rotor machine"
447 (let ((i 0))
448 (if RTR-size-mask
449 (while (< i RTR-number-of-rotors)
450 (setq p (aref (aref RTR-e-rotors i)
451 (logand (logxor (aref RTR-positions i)
452 p)
453 RTR-size-mask)))
454 (setq i (+ 1 i)))
455 (while (< i RTR-number-of-rotors)
456 (setq p (aref (aref RTR-e-rotors i)
457 (% (logxor (aref RTR-positions i)
458 p)
459 RTR-size)))
460 (setq i (+ 1 i))))
461 (RTR-advance)
462 p))*/
463static unsigned char RTR_e_char(r, p)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000464 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000465 unsigned char p;
466{
467 register int i=0;
468 register unsigned char tp=p;
469 if (r->size_mask) {
470 while (i < r->rotors) {
471 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) & r->size_mask))];
472 i++;
473 }
474 } else {
475 while (i < r->rotors) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000476 tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) % (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000477 i++;
478 }
479 }
480 RTR_advance(r);
481 return ((unsigned char)tp);
482}
483
484/*(defun RTR-d-char (c)
485 "Decrypt the character C with the current rotor machine"
486 (let ((i (- RTR-number-of-rotors 1)))
487 (if RTR-size-mask
488 (while (<= 0 i)
489 (setq c (logand (logxor (aref RTR-positions i)
490 (aref (aref RTR-d-rotors i)
491 c))
492 RTR-size-mask))
493 (setq i (- i 1)))
494 (while (<= 0 i)
495 (setq c (% (logxor (aref RTR-positions i)
496 (aref (aref RTR-d-rotors i)
497 c))
498 RTR-size))
499 (setq i (- i 1))))
500 (RTR-advance)
501 c))*/
502static unsigned char RTR_d_char(r, c)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000503 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000504 unsigned char c;
505{
506 register int i=r->rotors - 1;
507 register unsigned char tc=c;
508 if (r->size_mask) {
509 while (0 <= i) {
510 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) & r->size_mask;
511 i--;
512 }
513 } else {
514 while (0 <= i) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000515 tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) % (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000516 i--;
517 }
518 }
519 RTR_advance(r);
520 return(tc);
521}
522
523/*(defun RTR-e-region (beg end key)
524 "Perform a rotor encryption of the region from BEG to END by KEY"
525 (save-excursion
526 (let ((tenth (/ (- end beg) 10)))
527 (RTR-init key)
528 (goto-char beg)
529 ;; ### make it stop evry 10% or so to tell us
530 (while (< (point) end)
531 (let ((fc (following-char)))
532 (insert-char (RTR-e-char fc) 1)
533 (delete-char 1))))))*/
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000534static void RTR_e_region(r, beg, len, doinit)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000535 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000536 unsigned char *beg;
537 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000538 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000539{
540 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000541 if (doinit || r->isinited == FALSE)
542 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000543 for (i=0;i<len;i++) {
544 beg[i]=RTR_e_char(r,beg[i]);
545 }
546}
547
548/*(defun RTR-d-region (beg end key)
549 "Perform a rotor decryption of the region from BEG to END by KEY"
550 (save-excursion
551 (progn
552 (RTR-init key)
553 (goto-char beg)
554 (while (< (point) end)
555 (let ((fc (following-char)))
556 (insert-char (RTR-d-char fc) 1)
557 (delete-char 1))))))*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000558static void RTR_d_region(r, beg, len, doinit)
559 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000560 unsigned char *beg;
561 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000562 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000563{
564 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000565 if (doinit || r->isinited == FALSE)
566 RTR_init(r);
Guido van Rossum50098201992-07-31 15:10:13 +0000567 for (i=0;i<len;i++) {
568 beg[i]=RTR_d_char(r,beg[i]);
569 }
570}
571
572
573/*(defun RTR-key-string-to-ints (key)
574 "Convert a string into a list of 4 numbers"
575 (let ((k1 995)
576 (k2 576)
577 (k3 767)
578 (k4 671)
579 (k5 463)
580 (i 0))
581 (while (< i (length key))
582 (setq k1 (logand (+ (logior (lsh k1 3) (lsh k1 -13)) (aref key i)) 65535))
583 (setq k2 (logand (logxor (logior (lsh k2 3) (lsh k2 -13)) (aref key i)) 65535))
584 (setq k3 (logand (- (logior (lsh k3 3) (lsh k3 -13)) (aref key i)) 65535))
585 (setq k4 (logand (- (aref key i) (logior (lsh k4 3) (lsh k4 -13))) 65535))
586 (setq k5 (logand (logxor (logior (lsh k5 3) (lsh k5 -13)) (lognot (aref key i))) 65535))
587 (setq i (+ i 1)))
588 (list k1 (logior 1 k2) k3 k4 k5)))*/
589/* This is done in set_key() above */
590
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000591#if 0
Guido van Rossum50098201992-07-31 15:10:13 +0000592/*(defun encrypt-region (beg end key)
593 "Interactivly encrypt the region"
594 (interactive "r\nsKey:")
595 (RTR-e-region beg end (RTR-key-string-to-ints key)))*/
596static void encrypt_region(r, region, len)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000597 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000598 unsigned char *region;
599 int len;
600{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000601 RTR_e_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000602}
603
604/*(defun decrypt-region (beg end key)
605 "Interactivly decrypt the region"
606 (interactive "r\nsKey:")
607 (RTR-d-region beg end (RTR-key-string-to-ints key)))*/
608static void decrypt_region(r, region, len)
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000609 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000610 unsigned char *region;
611 int len;
612{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000613 RTR_d_region(r,region,len,TRUE);
Guido van Rossum50098201992-07-31 15:10:13 +0000614}
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000615#endif
Guido van Rossum50098201992-07-31 15:10:13 +0000616
617/* Rotor methods */
618
619static void
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000620PyRotor_Dealloc(xp)
621 PyRotorObject *xp;
Guido van Rossum50098201992-07-31 15:10:13 +0000622{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000623 PyMem_XDEL(xp->e_rotor);
624 PyMem_XDEL(xp->d_rotor);
625 PyMem_XDEL(xp->positions);
626 PyMem_XDEL(xp->advances);
627 PyMem_DEL(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000628}
629
Guido van Rossumf6971e21994-08-30 12:25:20 +0000630static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000631PyRotor_Encrypt(self, args)
632 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000633 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000634{
635 char *string = (char *)NULL;
636 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000637 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000638 char *tmp;
639
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000640 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000641 return NULL;
642 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000643 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000644 return NULL;
645 }
646 memset(tmp,'\0',len+1);
647 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000648 RTR_e_region(self,(unsigned char *)tmp,len, TRUE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000649 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000650 free(tmp);
651 return(rtn);
652}
653
Guido van Rossumf6971e21994-08-30 12:25:20 +0000654static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000655PyRotor_EncryptMore(self, args)
656 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000657 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000658{
659 char *string = (char *)NULL;
660 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000661 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000662 char *tmp;
663
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000664 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000665 return NULL;
666 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000667 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000668 return NULL;
669 }
670 memset(tmp,'\0',len+1);
671 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000672 RTR_e_region(self,(unsigned char *)tmp,len, FALSE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000673 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum50098201992-07-31 15:10:13 +0000674 free(tmp);
675 return(rtn);
676}
677
Guido van Rossumf6971e21994-08-30 12:25:20 +0000678static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000679PyRotor_Decrypt(self, args)
680 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000681 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000682{
683 char *string = (char *)NULL;
684 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000685 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000686 char *tmp;
687
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000688 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000689 return NULL;
690 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000691 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000692 return NULL;
693 }
694 memset(tmp,'\0',len+1);
695 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000696 RTR_d_region(self,(unsigned char *)tmp,len, TRUE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000697 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000698 free(tmp);
699 return(rtn);
700}
701
Guido van Rossumf6971e21994-08-30 12:25:20 +0000702static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000703PyRotor_DecryptMore(self, args)
704 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000705 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000706{
707 char *string = (char *)NULL;
708 int len = 0;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000709 PyObject * rtn = (PyObject * )NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000710 char *tmp;
711
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000712 if (!PyArg_Parse(args,"s#",&string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000713 return NULL;
714 if (!(tmp = (char *)malloc(len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000715 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000716 return NULL;
717 }
718 memset(tmp,'\0',len+1);
719 memcpy(tmp,string,len);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000720 RTR_d_region(self,(unsigned char *)tmp,len, FALSE);
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000721 rtn = PyString_FromStringAndSize(tmp,len);
Guido van Rossum50098201992-07-31 15:10:13 +0000722 free(tmp);
723 return(rtn);
724}
725
Guido van Rossumf6971e21994-08-30 12:25:20 +0000726static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000727PyRotor_SetKey(self, args)
728 PyRotorObject *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000729 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000730{
Guido van Rossum50098201992-07-31 15:10:13 +0000731 char *string;
732
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000733 if (PyArg_Parse(args,"s",&string))
Guido van Rossum50098201992-07-31 15:10:13 +0000734 set_key(self,string);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000735 Py_INCREF(Py_None);
736 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000737}
738
Guido van Rossuma597dde1995-01-10 20:56:29 +0000739static struct PyMethodDef PyRotor_Methods[] = {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000740 {"encrypt", (PyCFunction)PyRotor_Encrypt},
741 {"encryptmore", (PyCFunction)PyRotor_EncryptMore},
742 {"decrypt", (PyCFunction)PyRotor_Decrypt},
743 {"decryptmore", (PyCFunction)PyRotor_DecryptMore},
744 {"setkey", (PyCFunction)PyRotor_SetKey},
Guido van Rossum50098201992-07-31 15:10:13 +0000745 {NULL, NULL} /* sentinel */
746};
747
748
749/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000750static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000751PyRotor_GetAttr(s, name)
752 PyRotorObject *s;
Guido van Rossum50098201992-07-31 15:10:13 +0000753 char *name;
754{
Guido van Rossumf6971e21994-08-30 12:25:20 +0000755 return Py_FindMethod(PyRotor_Methods, (PyObject * ) s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000756}
757
Guido van Rossuma320fd31995-03-09 12:14:15 +0000758statichere PyTypeObject PyRotor_Type = {
Guido van Rossuma597dde1995-01-10 20:56:29 +0000759 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000760 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000761 "rotor", /*tp_name*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000762 sizeof(PyRotorObject), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000763 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000764 /* methods */
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000765 (destructor)PyRotor_Dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000766 0, /*tp_print*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000767 (getattrfunc)PyRotor_GetAttr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000768 0, /*tp_setattr*/
769 0, /*tp_compare*/
770 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000771 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000772};
773
774
Guido van Rossumf6971e21994-08-30 12:25:20 +0000775static PyObject *
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000776PyRotor_Rotor(self, args)
Guido van Rossumf6971e21994-08-30 12:25:20 +0000777 PyObject * self;
778 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000779{
780 char *string;
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000781 PyRotorObject *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000782 int len;
783 int num_rotors;
784
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000785 if (PyArg_Parse(args,"s#", &string, &len)) {
Guido van Rossum50098201992-07-31 15:10:13 +0000786 num_rotors = 6;
787 } else {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000788 PyErr_Clear();
789 if (!PyArg_Parse(args,"(s#i)", &string, &len, &num_rotors))
Guido van Rossum50098201992-07-31 15:10:13 +0000790 return NULL;
791 }
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000792 r = PyRotor_New(num_rotors, string);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000793 return (PyObject * )r;
Guido van Rossum50098201992-07-31 15:10:13 +0000794}
795
Guido van Rossuma597dde1995-01-10 20:56:29 +0000796static struct PyMethodDef PyRotor_Rotor_Methods[] = {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000797 {"newrotor", (PyCFunction)PyRotor_Rotor},
Guido van Rossum50098201992-07-31 15:10:13 +0000798 {NULL, NULL} /* Sentinel */
799};
800
801
802/* Initialize this module.
803 This is called when the first 'import rotor' is done,
804 via a table in config.c, if config.c is compiled with USE_ROTOR
805 defined. */
806
807void
808initrotor()
809{
Guido van Rossumf6971e21994-08-30 12:25:20 +0000810 PyObject * m;
Guido van Rossum50098201992-07-31 15:10:13 +0000811
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000812 m = Py_InitModule("rotor", PyRotor_Rotor_Methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000813}