blob: 65c175871547b81cfb2968605a3c8885b4495d8e [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"
Guido van Rossuma320fd31995-03-09 12:14:15 +000059#include "mymath.h"
Guido van Rossuma597dde1995-01-10 20:56:29 +000060
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000061#define TRUE 1
62#define FALSE 0
Guido van Rossum50098201992-07-31 15:10:13 +000063
64typedef struct {
Guido van Rossum7b1e9741994-08-29 10:46:42 +000065 PyObject_HEAD
Guido van Rossum50098201992-07-31 15:10:13 +000066 int seed[3];
67 short key[5];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000068 int isinited;
Guido van Rossum50098201992-07-31 15:10:13 +000069 int size;
70 int size_mask;
71 int rotors;
Barry Warsawaeb207c1996-12-23 23:36:24 +000072 unsigned char *e_rotor; /* [num_rotors][size] */
73 unsigned char *d_rotor; /* [num_rotors][size] */
74 unsigned char *positions; /* [num_rotors] */
75 unsigned char *advances; /* [num_rotors] */
76} Rotorobj;
Guido van Rossum50098201992-07-31 15:10:13 +000077
Barry Warsawaeb207c1996-12-23 23:36:24 +000078staticforward PyTypeObject Rotor_Type;
Guido van Rossum50098201992-07-31 15:10:13 +000079
Barry Warsawaeb207c1996-12-23 23:36:24 +000080#define is_rotor(v) ((v)->ob_type == &Rotor_Type)
Guido van Rossum50098201992-07-31 15:10:13 +000081
Barry Warsaw47d35001997-01-16 16:49:44 +000082
83/* This defines the necessary routines to manage rotor objects */
Guido van Rossum50098201992-07-31 15:10:13 +000084
Barry Warsawaeb207c1996-12-23 23:36:24 +000085static void
86set_seed(r)
87 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +000088{
89 r->seed[0] = r->key[0];
90 r->seed[1] = r->key[1];
91 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000092 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +000093}
94
95/* Return the next random number in the range [0.0 .. 1.0) */
Guido van Rossum7844e381997-04-11 20:44:04 +000096static double
Barry Warsawaeb207c1996-12-23 23:36:24 +000097r_random(r)
98 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +000099{
100 int x, y, z;
Guido van Rossum7844e381997-04-11 20:44:04 +0000101 double val, term;
Guido van Rossum50098201992-07-31 15:10:13 +0000102
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
Guido van Rossum7844e381997-04-11 20:44:04 +0000119 term = (double)(
120 (((double)x)/(double)30269.0) +
121 (((double)y)/(double)30307.0) +
122 (((double)z)/(double)30323.0)
Barry Warsawaeb207c1996-12-23 23:36:24 +0000123 );
Guido van Rossum7844e381997-04-11 20:44:04 +0000124 val = term - (double)floor((double)term);
Guido van Rossum50098201992-07-31 15:10:13 +0000125
Barry Warsawaeb207c1996-12-23 23:36:24 +0000126 if (val >= 1.0)
127 val = 0.0;
Guido van Rossum50098201992-07-31 15:10:13 +0000128
129 return val;
130}
131
Barry Warsawaeb207c1996-12-23 23:36:24 +0000132static short
133r_rand(r, s)
134 Rotorobj *r;
135 short s;
Guido van Rossum50098201992-07-31 15:10:13 +0000136{
Guido van Rossum7844e381997-04-11 20:44:04 +0000137 return (short)((short)(r_random(r) * (double)s) % s);
Guido van Rossum50098201992-07-31 15:10:13 +0000138}
139
Barry Warsawaeb207c1996-12-23 23:36:24 +0000140static void
141set_key(r, key)
142 Rotorobj *r;
143 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000144{
Guido van Rossume77a7571993-11-03 15:01:26 +0000145 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossum50098201992-07-31 15:10:13 +0000146 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000147 int len = strlen(key);
Barry Warsaw47d35001997-01-16 16:49:44 +0000148
Barry Warsawaeb207c1996-12-23 23:36:24 +0000149 for (i = 0; i < len; i++) {
Barry Warsaw47d35001997-01-16 16:49:44 +0000150 unsigned short ki = Py_CHARMASK(key[i]);
151
152 k1 = (((k1<<3 | k1>>13) + ki) & 65535);
153 k2 = (((k2<<3 | k2>>13) ^ ki) & 65535);
154 k3 = (((k3<<3 | k3>>13) - ki) & 65535);
155 k4 = ((ki - (k4<<3 | k4>>13)) & 65535);
156 k5 = (((k5<<3 | k5>>13) ^ ~ki) & 65535);
Guido van Rossum50098201992-07-31 15:10:13 +0000157 }
158 r->key[0] = (short)k1;
159 r->key[1] = (short)(k2|1);
160 r->key[2] = (short)k3;
161 r->key[3] = (short)k4;
162 r->key[4] = (short)k5;
163
164 set_seed(r);
165}
166
Barry Warsaw47d35001997-01-16 16:49:44 +0000167
168
Guido van Rossum50098201992-07-31 15:10:13 +0000169/* These define the interface to a rotor object */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000170static Rotorobj *
171rotorobj_new(num_rotors, key)
Guido van Rossum50098201992-07-31 15:10:13 +0000172 int num_rotors;
173 char *key;
174{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000175 Rotorobj *xp;
176
177 xp = PyObject_NEW(Rotorobj, &Rotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000178 if (xp == NULL)
179 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000180 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000181
182 xp->size = 256;
183 xp->size_mask = xp->size - 1;
184 xp->size_mask = 0;
185 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000186 xp->e_rotor = NULL;
187 xp->d_rotor = NULL;
188 xp->positions = NULL;
189 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000190
Barry Warsawaeb207c1996-12-23 23:36:24 +0000191 if (!(xp->e_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
192 goto finally;
193 if (!(xp->d_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
194 goto finally;
195 if (!(xp->positions = PyMem_NEW(unsigned char, num_rotors)))
196 goto finally;
197 if (!(xp->advances = PyMem_NEW(unsigned char, num_rotors)))
198 goto finally;
199
Guido van Rossum50098201992-07-31 15:10:13 +0000200 return xp;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000201
202 finally:
203 PyMem_XDEL(xp->e_rotor);
204 PyMem_XDEL(xp->d_rotor);
205 PyMem_XDEL(xp->positions);
206 PyMem_XDEL(xp->advances);
Guido van Rossuma597dde1995-01-10 20:56:29 +0000207 Py_DECREF(xp);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000208 return (Rotorobj*)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000209}
210
Barry Warsaw47d35001997-01-16 16:49:44 +0000211
Guido van Rossum50098201992-07-31 15:10:13 +0000212/* These routines impliment the rotor itself */
213
Barry Warsaw47d35001997-01-16 16:49:44 +0000214/* Here is a fairly sophisticated {en,de}cryption system. It is based on
215 the idea of a "rotor" machine. A bunch of rotors, each with a
Barry Warsawaeb207c1996-12-23 23:36:24 +0000216 different permutation of the alphabet, rotate around a different amount
217 after encrypting one character. The current state of the rotors is
218 used to encrypt one character.
Guido van Rossum50098201992-07-31 15:10:13 +0000219
Barry Warsawaeb207c1996-12-23 23:36:24 +0000220 The code is smart enought to tell if your alphabet has a number of
221 characters equal to a power of two. If it does, it uses logical
222 operations, if not it uses div and mod (both require a division).
Guido van Rossum50098201992-07-31 15:10:13 +0000223
Barry Warsawaeb207c1996-12-23 23:36:24 +0000224 You will need to make two changes to the code 1) convert to c, and
225 customize for an alphabet of 255 chars 2) add a filter at the begining,
226 and end, which subtracts one on the way in, and adds one on the way
227 out.
Guido van Rossum50098201992-07-31 15:10:13 +0000228
Barry Warsawaeb207c1996-12-23 23:36:24 +0000229 You might wish to do some timing studies. Another viable alternative
230 is to "byte stuff" the encrypted data of a normal (perhaps this one)
231 encryption routine.
Guido van Rossum50098201992-07-31 15:10:13 +0000232
Barry Warsawaeb207c1996-12-23 23:36:24 +0000233 j'
Guido van Rossum50098201992-07-31 15:10:13 +0000234
Barry Warsaw47d35001997-01-16 16:49:44 +0000235 */
236
237/* Note: the C code here is a fairly straightforward transliteration of a
238 * rotor implemented in lisp. The original lisp code has been removed from
239 * this file to for simplification, but I've kept the docstrings as
240 * comments in front of the functions.
241 */
242
243
244/* Set ROTOR to the identity permutation */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000245static void
246RTR_make_id_rotor(r, rtr)
247 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000248 unsigned char *rtr;
249{
250 register int j;
251 register int size = r->size;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000252 for (j = 0; j < size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000253 rtr[j] = (unsigned char)j;
254 }
255}
256
257
Barry Warsaw47d35001997-01-16 16:49:44 +0000258/* The current set of encryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000259static void
260RTR_e_rotors(r)
261 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000262{
263 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000264 for (i = 0; i < r->rotors; i++) {
265 RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000266 }
267}
268
Barry Warsaw47d35001997-01-16 16:49:44 +0000269/* The current set of decryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000270static void
271RTR_d_rotors(r)
272 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000273{
274 register int i, j;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000275 for (i = 0; i < r->rotors; i++) {
276 for (j = 0; j < r->size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000277 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
278 }
279 }
280}
281
Barry Warsaw47d35001997-01-16 16:49:44 +0000282/* The positions of the rotors at this time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000283static void
284RTR_positions(r)
285 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000286{
287 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000288 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000289 r->positions[i] = 1;
290 }
291}
292
Barry Warsaw47d35001997-01-16 16:49:44 +0000293/* The number of positions to advance the rotors at a time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000294static void
295RTR_advances(r)
296 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000297{
298 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000299 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000300 r->advances[i] = 1;
301 }
302}
303
Barry Warsaw47d35001997-01-16 16:49:44 +0000304/* Permute the E rotor, and make the D rotor its inverse
305 * see Knuth for explanation of algorithm.
306 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000307static void
308RTR_permute_rotor(r, e, d)
309 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000310 unsigned char *e;
311 unsigned char *d;
312{
313 short i = r->size;
314 short q;
315 unsigned char j;
316 RTR_make_id_rotor(r,e);
317 while (2 <= i) {
318 q = r_rand(r,i);
319 i--;
320 j = e[q];
321 e[q] = (unsigned char)e[i];
322 e[i] = (unsigned char)j;
323 d[j] = (unsigned char)i;
324 }
325 e[0] = (unsigned char)e[0];
326 d[(e[0])] = (unsigned char)0;
327}
328
Barry Warsaw47d35001997-01-16 16:49:44 +0000329/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
330 * Set the advancement, position, and permutation of the rotors
331 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000332static void
333RTR_init(r)
334 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000335{
336 int i;
337 set_seed(r);
338 RTR_positions(r);
339 RTR_advances(r);
340 RTR_e_rotors(r);
341 RTR_d_rotors(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000342 for (i = 0; i < r->rotors; i++) {
Guido van Rossum7844e381997-04-11 20:44:04 +0000343 r->positions[i] = (unsigned char) r_rand(r,r->size);
Guido van Rossum50098201992-07-31 15:10:13 +0000344 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
Barry Warsawaeb207c1996-12-23 23:36:24 +0000345 RTR_permute_rotor(r,
346 &(r->e_rotor[(i*r->size)]),
347 &(r->d_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000348 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000349 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000350}
351
Barry Warsaw47d35001997-01-16 16:49:44 +0000352/* Change the RTR-positions vector, using the RTR-advances vector */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000353static void
354RTR_advance(r)
355 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000356{
357 register int i=0, temp=0;
358 if (r->size_mask) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000359 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000360 temp = r->positions[i] + r->advances[i];
361 r->positions[i] = temp & r->size_mask;
362 if ((temp >= r->size) && (i < (r->rotors - 1))) {
363 r->positions[(i+1)] = 1 + r->positions[(i+1)];
364 }
365 i++;
366 }
367 } else {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000368 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000369 temp = r->positions[i] + r->advances[i];
370 r->positions[i] = temp%r->size;
371 if ((temp >= r->size) && (i < (r->rotors - 1))) {
372 r->positions[(i+1)] = 1 + r->positions[(i+1)];
373 }
374 i++;
375 }
376 }
377}
378
Barry Warsaw47d35001997-01-16 16:49:44 +0000379/* Encrypt the character P with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000380static unsigned char
381RTR_e_char(r, p)
382 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000383 unsigned char p;
384{
385 register int i=0;
386 register unsigned char tp=p;
387 if (r->size_mask) {
388 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000389 tp = r->e_rotor[(i*r->size) +
390 (((r->positions[i] ^ tp) &
391 r->size_mask))];
Guido van Rossum50098201992-07-31 15:10:13 +0000392 i++;
393 }
394 } else {
395 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000396 tp = r->e_rotor[(i*r->size) +
397 (((r->positions[i] ^ tp) %
398 (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000399 i++;
400 }
401 }
402 RTR_advance(r);
403 return ((unsigned char)tp);
404}
405
Barry Warsaw47d35001997-01-16 16:49:44 +0000406/* Decrypt the character C with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000407static unsigned char
408RTR_d_char(r, c)
409 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000410 unsigned char c;
411{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000412 register int i = r->rotors - 1;
413 register unsigned char tc = c;
414
Guido van Rossum50098201992-07-31 15:10:13 +0000415 if (r->size_mask) {
416 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000417 tc = (r->positions[i] ^
418 r->d_rotor[(i*r->size)+tc]) & r->size_mask;
Guido van Rossum50098201992-07-31 15:10:13 +0000419 i--;
420 }
421 } else {
422 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000423 tc = (r->positions[i] ^
424 r->d_rotor[(i*r->size)+tc]) %
425 (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000426 i--;
427 }
428 }
429 RTR_advance(r);
430 return(tc);
431}
432
Barry Warsaw47d35001997-01-16 16:49:44 +0000433/* Perform a rotor encryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000434static void
435RTR_e_region(r, beg, len, doinit)
436 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000437 unsigned char *beg;
438 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000439 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000440{
441 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000442 if (doinit || r->isinited == FALSE)
443 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000444 for (i = 0; i < len; i++) {
445 beg[i] = RTR_e_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000446 }
447}
448
Barry Warsaw47d35001997-01-16 16:49:44 +0000449/* Perform a rotor decryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000450static void
451RTR_d_region(r, beg, len, doinit)
452 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000453 unsigned char *beg;
454 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000455 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000456{
457 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000458 if (doinit || r->isinited == FALSE)
459 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000460 for (i = 0; i < len; i++) {
461 beg[i] = RTR_d_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000462 }
463}
464
465
Barry Warsaw47d35001997-01-16 16:49:44 +0000466
Guido van Rossum50098201992-07-31 15:10:13 +0000467/* Rotor methods */
Guido van Rossum50098201992-07-31 15:10:13 +0000468static void
Barry Warsawaeb207c1996-12-23 23:36:24 +0000469rotor_dealloc(xp)
470 Rotorobj *xp;
Guido van Rossum50098201992-07-31 15:10:13 +0000471{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000472 PyMem_XDEL(xp->e_rotor);
473 PyMem_XDEL(xp->d_rotor);
474 PyMem_XDEL(xp->positions);
475 PyMem_XDEL(xp->advances);
476 PyMem_DEL(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000477}
478
Guido van Rossumf6971e21994-08-30 12:25:20 +0000479static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000480rotorobj_encrypt(self, args)
481 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000482 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000483{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000484 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000485 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000486 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000487 char *tmp;
488
Barry Warsawaeb207c1996-12-23 23:36:24 +0000489 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000490 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000491 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000492 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000493 return NULL;
494 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000495 memset(tmp, '\0', len+1);
496 memcpy(tmp, string, len);
497 RTR_e_region(self, (unsigned char *)tmp, len, TRUE);
498 rtn = PyString_FromStringAndSize(tmp, len);
499 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000500 return(rtn);
501}
502
Guido van Rossumf6971e21994-08-30 12:25:20 +0000503static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000504rotorobj_encrypt_more(self, args)
505 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000506 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000507{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000508 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000509 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000510 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000511 char *tmp;
512
Barry Warsawaeb207c1996-12-23 23:36:24 +0000513 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000514 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000515 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000516 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000517 return NULL;
518 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000519 memset(tmp, '\0', len+1);
520 memcpy(tmp, string, len);
521 RTR_e_region(self, (unsigned char *)tmp, len, FALSE);
522 rtn = PyString_FromStringAndSize(tmp, len);
523 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000524 return(rtn);
525}
526
Guido van Rossumf6971e21994-08-30 12:25:20 +0000527static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000528rotorobj_decrypt(self, args)
529 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000530 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000531{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000532 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000533 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000534 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000535 char *tmp;
536
Barry Warsawaeb207c1996-12-23 23:36:24 +0000537 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000538 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000539 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000540 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000541 return NULL;
542 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000543 memset(tmp, '\0', len+1);
544 memcpy(tmp, string, len);
545 RTR_d_region(self, (unsigned char *)tmp, len, TRUE);
546 rtn = PyString_FromStringAndSize(tmp, len);
547 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000548 return(rtn);
549}
550
Guido van Rossumf6971e21994-08-30 12:25:20 +0000551static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000552rotorobj_decrypt_more(self, args)
553 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000554 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000555{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000556 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000557 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000558 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000559 char *tmp;
560
Barry Warsawaeb207c1996-12-23 23:36:24 +0000561 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000562 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000563 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000564 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000565 return NULL;
566 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000567 memset(tmp, '\0', len+1);
568 memcpy(tmp, string, len);
569 RTR_d_region(self, (unsigned char *)tmp, len, FALSE);
570 rtn = PyString_FromStringAndSize(tmp, len);
571 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000572 return(rtn);
573}
574
Guido van Rossumf6971e21994-08-30 12:25:20 +0000575static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000576rotorobj_setkey(self, args)
577 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000578 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000579{
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000580 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000581
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000582 if (!PyArg_ParseTuple(args, "s", &key))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000583 return NULL;
584
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000585 set_key(self, key);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000586 Py_INCREF(Py_None);
587 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000588}
589
Barry Warsawaeb207c1996-12-23 23:36:24 +0000590static struct PyMethodDef
591rotorobj_methods[] = {
592 {"encrypt", (PyCFunction)rotorobj_encrypt},
593 {"encryptmore", (PyCFunction)rotorobj_encrypt_more},
594 {"decrypt", (PyCFunction)rotorobj_decrypt},
595 {"decryptmore", (PyCFunction)rotorobj_decrypt_more},
596 {"setkey", (PyCFunction)rotorobj_setkey, 1},
Guido van Rossum50098201992-07-31 15:10:13 +0000597 {NULL, NULL} /* sentinel */
598};
599
600
601/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000602static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000603rotorobj_getattr(s, name)
604 Rotorobj *s;
Guido van Rossum50098201992-07-31 15:10:13 +0000605 char *name;
606{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000607 return Py_FindMethod(rotorobj_methods, (PyObject*)s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000608}
609
Barry Warsawaeb207c1996-12-23 23:36:24 +0000610
611statichere PyTypeObject Rotor_Type = {
Guido van Rossuma597dde1995-01-10 20:56:29 +0000612 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000613 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000614 "rotor", /*tp_name*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000615 sizeof(Rotorobj), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000616 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000617 /* methods */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000618 (destructor)rotor_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000619 0, /*tp_print*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000620 (getattrfunc)rotorobj_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000621 0, /*tp_setattr*/
622 0, /*tp_compare*/
623 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000624 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000625};
626
627
Guido van Rossumf6971e21994-08-30 12:25:20 +0000628static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000629rotor_rotor(self, args)
Guido van Rossumf6971e21994-08-30 12:25:20 +0000630 PyObject * self;
631 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000632{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000633 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000634 char *string;
Guido van Rossum50098201992-07-31 15:10:13 +0000635 int len;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000636 int num_rotors = 6;
Guido van Rossum50098201992-07-31 15:10:13 +0000637
Barry Warsawaeb207c1996-12-23 23:36:24 +0000638 if (!PyArg_ParseTuple(args, "s#|i", &string, &len, &num_rotors))
639 return NULL;
640
641 r = rotorobj_new(num_rotors, string);
642 return (PyObject *)r;
Guido van Rossum50098201992-07-31 15:10:13 +0000643}
644
Barry Warsawaeb207c1996-12-23 23:36:24 +0000645
Barry Warsaw47d35001997-01-16 16:49:44 +0000646
Barry Warsawaeb207c1996-12-23 23:36:24 +0000647static struct PyMethodDef
648rotor_methods[] = {
649 {"newrotor", rotor_rotor, 1},
650 {NULL, NULL} /* sentinel */
Guido van Rossum50098201992-07-31 15:10:13 +0000651};
652
653
Guido van Rossum50098201992-07-31 15:10:13 +0000654void
655initrotor()
656{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000657 (void)Py_InitModule("rotor", rotor_methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000658}