blob: b1fef3938b7f159b9b595d3d0a1c609148f86362 [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 Rossum19a6c8a1997-05-20 15:58:36 +000061#ifndef TRUE
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000062#define TRUE 1
Guido van Rossum19a6c8a1997-05-20 15:58:36 +000063#endif
64#ifndef FALSE
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000065#define FALSE 0
Guido van Rossum19a6c8a1997-05-20 15:58:36 +000066#endif
Guido van Rossum50098201992-07-31 15:10:13 +000067
68typedef 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;
Barry Warsawaeb207c1996-12-23 23:36:24 +000076 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] */
80} Rotorobj;
Guido van Rossum50098201992-07-31 15:10:13 +000081
Barry Warsawaeb207c1996-12-23 23:36:24 +000082staticforward PyTypeObject Rotor_Type;
Guido van Rossum50098201992-07-31 15:10:13 +000083
Barry Warsawaeb207c1996-12-23 23:36:24 +000084#define is_rotor(v) ((v)->ob_type == &Rotor_Type)
Guido van Rossum50098201992-07-31 15:10:13 +000085
Barry Warsaw47d35001997-01-16 16:49:44 +000086
87/* This defines the necessary routines to manage rotor objects */
Guido van Rossum50098201992-07-31 15:10:13 +000088
Barry Warsawaeb207c1996-12-23 23:36:24 +000089static void
90set_seed(r)
91 Rotorobj *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) */
Guido van Rossum7844e381997-04-11 20:44:04 +0000100static double
Barry Warsawaeb207c1996-12-23 23:36:24 +0000101r_random(r)
102 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000103{
104 int x, y, z;
Guido van Rossum7844e381997-04-11 20:44:04 +0000105 double val, term;
Guido van Rossum50098201992-07-31 15:10:13 +0000106
107 x = r->seed[0];
108 y = r->seed[1];
109 z = r->seed[2];
110
111 x = 171 * (x % 177) - 2 * (x/177);
112 y = 172 * (y % 176) - 35 * (y/176);
113 z = 170 * (z % 178) - 63 * (z/178);
114
115 if (x < 0) x = x + 30269;
116 if (y < 0) y = y + 30307;
117 if (z < 0) z = z + 30323;
118
119 r->seed[0] = x;
120 r->seed[1] = y;
121 r->seed[2] = z;
122
Guido van Rossum7844e381997-04-11 20:44:04 +0000123 term = (double)(
124 (((double)x)/(double)30269.0) +
125 (((double)y)/(double)30307.0) +
126 (((double)z)/(double)30323.0)
Barry Warsawaeb207c1996-12-23 23:36:24 +0000127 );
Guido van Rossum7844e381997-04-11 20:44:04 +0000128 val = term - (double)floor((double)term);
Guido van Rossum50098201992-07-31 15:10:13 +0000129
Barry Warsawaeb207c1996-12-23 23:36:24 +0000130 if (val >= 1.0)
131 val = 0.0;
Guido van Rossum50098201992-07-31 15:10:13 +0000132
133 return val;
134}
135
Barry Warsawaeb207c1996-12-23 23:36:24 +0000136static short
137r_rand(r, s)
138 Rotorobj *r;
139 short s;
Guido van Rossum50098201992-07-31 15:10:13 +0000140{
Guido van Rossum7844e381997-04-11 20:44:04 +0000141 return (short)((short)(r_random(r) * (double)s) % s);
Guido van Rossum50098201992-07-31 15:10:13 +0000142}
143
Barry Warsawaeb207c1996-12-23 23:36:24 +0000144static void
145set_key(r, key)
146 Rotorobj *r;
147 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000148{
Guido van Rossume77a7571993-11-03 15:01:26 +0000149 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossum50098201992-07-31 15:10:13 +0000150 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000151 int len = strlen(key);
Barry Warsaw47d35001997-01-16 16:49:44 +0000152
Barry Warsawaeb207c1996-12-23 23:36:24 +0000153 for (i = 0; i < len; i++) {
Barry Warsaw47d35001997-01-16 16:49:44 +0000154 unsigned short ki = Py_CHARMASK(key[i]);
155
156 k1 = (((k1<<3 | k1>>13) + ki) & 65535);
157 k2 = (((k2<<3 | k2>>13) ^ ki) & 65535);
158 k3 = (((k3<<3 | k3>>13) - ki) & 65535);
159 k4 = ((ki - (k4<<3 | k4>>13)) & 65535);
160 k5 = (((k5<<3 | k5>>13) ^ ~ki) & 65535);
Guido van Rossum50098201992-07-31 15:10:13 +0000161 }
162 r->key[0] = (short)k1;
163 r->key[1] = (short)(k2|1);
164 r->key[2] = (short)k3;
165 r->key[3] = (short)k4;
166 r->key[4] = (short)k5;
167
168 set_seed(r);
169}
170
Barry Warsaw47d35001997-01-16 16:49:44 +0000171
172
Guido van Rossum50098201992-07-31 15:10:13 +0000173/* These define the interface to a rotor object */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000174static Rotorobj *
175rotorobj_new(num_rotors, key)
Guido van Rossum50098201992-07-31 15:10:13 +0000176 int num_rotors;
177 char *key;
178{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000179 Rotorobj *xp;
180
181 xp = PyObject_NEW(Rotorobj, &Rotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000182 if (xp == NULL)
183 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000184 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000185
186 xp->size = 256;
187 xp->size_mask = xp->size - 1;
188 xp->size_mask = 0;
189 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000190 xp->e_rotor = NULL;
191 xp->d_rotor = NULL;
192 xp->positions = NULL;
193 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000194
Barry Warsawaeb207c1996-12-23 23:36:24 +0000195 if (!(xp->e_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
196 goto finally;
197 if (!(xp->d_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
198 goto finally;
199 if (!(xp->positions = PyMem_NEW(unsigned char, num_rotors)))
200 goto finally;
201 if (!(xp->advances = PyMem_NEW(unsigned char, num_rotors)))
202 goto finally;
203
Guido van Rossum50098201992-07-31 15:10:13 +0000204 return xp;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000205
206 finally:
207 PyMem_XDEL(xp->e_rotor);
208 PyMem_XDEL(xp->d_rotor);
209 PyMem_XDEL(xp->positions);
210 PyMem_XDEL(xp->advances);
Guido van Rossuma597dde1995-01-10 20:56:29 +0000211 Py_DECREF(xp);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000212 return (Rotorobj*)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000213}
214
Barry Warsaw47d35001997-01-16 16:49:44 +0000215
Guido van Rossum50098201992-07-31 15:10:13 +0000216/* These routines impliment the rotor itself */
217
Barry Warsaw47d35001997-01-16 16:49:44 +0000218/* Here is a fairly sophisticated {en,de}cryption system. It is based on
219 the idea of a "rotor" machine. A bunch of rotors, each with a
Barry Warsawaeb207c1996-12-23 23:36:24 +0000220 different permutation of the alphabet, rotate around a different amount
221 after encrypting one character. The current state of the rotors is
222 used to encrypt one character.
Guido van Rossum50098201992-07-31 15:10:13 +0000223
Barry Warsawaeb207c1996-12-23 23:36:24 +0000224 The code is smart enought to tell if your alphabet has a number of
225 characters equal to a power of two. If it does, it uses logical
226 operations, if not it uses div and mod (both require a division).
Guido van Rossum50098201992-07-31 15:10:13 +0000227
Barry Warsawaeb207c1996-12-23 23:36:24 +0000228 You will need to make two changes to the code 1) convert to c, and
229 customize for an alphabet of 255 chars 2) add a filter at the begining,
230 and end, which subtracts one on the way in, and adds one on the way
231 out.
Guido van Rossum50098201992-07-31 15:10:13 +0000232
Barry Warsawaeb207c1996-12-23 23:36:24 +0000233 You might wish to do some timing studies. Another viable alternative
234 is to "byte stuff" the encrypted data of a normal (perhaps this one)
235 encryption routine.
Guido van Rossum50098201992-07-31 15:10:13 +0000236
Barry Warsawaeb207c1996-12-23 23:36:24 +0000237 j'
Guido van Rossum50098201992-07-31 15:10:13 +0000238
Barry Warsaw47d35001997-01-16 16:49:44 +0000239 */
240
241/* Note: the C code here is a fairly straightforward transliteration of a
242 * rotor implemented in lisp. The original lisp code has been removed from
243 * this file to for simplification, but I've kept the docstrings as
244 * comments in front of the functions.
245 */
246
247
248/* Set ROTOR to the identity permutation */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000249static void
250RTR_make_id_rotor(r, rtr)
251 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000252 unsigned char *rtr;
253{
254 register int j;
255 register int size = r->size;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000256 for (j = 0; j < size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000257 rtr[j] = (unsigned char)j;
258 }
259}
260
261
Barry Warsaw47d35001997-01-16 16:49:44 +0000262/* The current set of encryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000263static void
264RTR_e_rotors(r)
265 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000266{
267 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000268 for (i = 0; i < r->rotors; i++) {
269 RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000270 }
271}
272
Barry Warsaw47d35001997-01-16 16:49:44 +0000273/* The current set of decryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000274static void
275RTR_d_rotors(r)
276 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000277{
278 register int i, j;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000279 for (i = 0; i < r->rotors; i++) {
280 for (j = 0; j < r->size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000281 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
282 }
283 }
284}
285
Barry Warsaw47d35001997-01-16 16:49:44 +0000286/* The positions of the rotors at this time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000287static void
288RTR_positions(r)
289 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000290{
291 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000292 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000293 r->positions[i] = 1;
294 }
295}
296
Barry Warsaw47d35001997-01-16 16:49:44 +0000297/* The number of positions to advance the rotors at a time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000298static void
299RTR_advances(r)
300 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000301{
302 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000303 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000304 r->advances[i] = 1;
305 }
306}
307
Barry Warsaw47d35001997-01-16 16:49:44 +0000308/* Permute the E rotor, and make the D rotor its inverse
309 * see Knuth for explanation of algorithm.
310 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000311static void
312RTR_permute_rotor(r, e, d)
313 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000314 unsigned char *e;
315 unsigned char *d;
316{
317 short i = r->size;
318 short q;
319 unsigned char j;
320 RTR_make_id_rotor(r,e);
321 while (2 <= i) {
322 q = r_rand(r,i);
323 i--;
324 j = e[q];
325 e[q] = (unsigned char)e[i];
326 e[i] = (unsigned char)j;
327 d[j] = (unsigned char)i;
328 }
329 e[0] = (unsigned char)e[0];
330 d[(e[0])] = (unsigned char)0;
331}
332
Barry Warsaw47d35001997-01-16 16:49:44 +0000333/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
334 * Set the advancement, position, and permutation of the rotors
335 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000336static void
337RTR_init(r)
338 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000339{
340 int i;
341 set_seed(r);
342 RTR_positions(r);
343 RTR_advances(r);
344 RTR_e_rotors(r);
345 RTR_d_rotors(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000346 for (i = 0; i < r->rotors; i++) {
Guido van Rossum7844e381997-04-11 20:44:04 +0000347 r->positions[i] = (unsigned char) r_rand(r,r->size);
Guido van Rossum50098201992-07-31 15:10:13 +0000348 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
Barry Warsawaeb207c1996-12-23 23:36:24 +0000349 RTR_permute_rotor(r,
350 &(r->e_rotor[(i*r->size)]),
351 &(r->d_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000352 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000353 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000354}
355
Barry Warsaw47d35001997-01-16 16:49:44 +0000356/* Change the RTR-positions vector, using the RTR-advances vector */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000357static void
358RTR_advance(r)
359 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000360{
361 register int i=0, temp=0;
362 if (r->size_mask) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000363 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000364 temp = r->positions[i] + r->advances[i];
365 r->positions[i] = temp & r->size_mask;
366 if ((temp >= r->size) && (i < (r->rotors - 1))) {
367 r->positions[(i+1)] = 1 + r->positions[(i+1)];
368 }
369 i++;
370 }
371 } else {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000372 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000373 temp = r->positions[i] + r->advances[i];
374 r->positions[i] = temp%r->size;
375 if ((temp >= r->size) && (i < (r->rotors - 1))) {
376 r->positions[(i+1)] = 1 + r->positions[(i+1)];
377 }
378 i++;
379 }
380 }
381}
382
Barry Warsaw47d35001997-01-16 16:49:44 +0000383/* Encrypt the character P with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000384static unsigned char
385RTR_e_char(r, p)
386 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000387 unsigned char p;
388{
389 register int i=0;
390 register unsigned char tp=p;
391 if (r->size_mask) {
392 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000393 tp = r->e_rotor[(i*r->size) +
394 (((r->positions[i] ^ tp) &
395 r->size_mask))];
Guido van Rossum50098201992-07-31 15:10:13 +0000396 i++;
397 }
398 } else {
399 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000400 tp = r->e_rotor[(i*r->size) +
401 (((r->positions[i] ^ tp) %
402 (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000403 i++;
404 }
405 }
406 RTR_advance(r);
407 return ((unsigned char)tp);
408}
409
Barry Warsaw47d35001997-01-16 16:49:44 +0000410/* Decrypt the character C with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000411static unsigned char
412RTR_d_char(r, c)
413 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000414 unsigned char c;
415{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000416 register int i = r->rotors - 1;
417 register unsigned char tc = c;
418
Guido van Rossum50098201992-07-31 15:10:13 +0000419 if (r->size_mask) {
420 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000421 tc = (r->positions[i] ^
422 r->d_rotor[(i*r->size)+tc]) & r->size_mask;
Guido van Rossum50098201992-07-31 15:10:13 +0000423 i--;
424 }
425 } else {
426 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000427 tc = (r->positions[i] ^
428 r->d_rotor[(i*r->size)+tc]) %
429 (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000430 i--;
431 }
432 }
433 RTR_advance(r);
434 return(tc);
435}
436
Barry Warsaw47d35001997-01-16 16:49:44 +0000437/* Perform a rotor encryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000438static void
439RTR_e_region(r, beg, len, doinit)
440 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000441 unsigned char *beg;
442 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000443 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000444{
445 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000446 if (doinit || r->isinited == FALSE)
447 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000448 for (i = 0; i < len; i++) {
449 beg[i] = RTR_e_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000450 }
451}
452
Barry Warsaw47d35001997-01-16 16:49:44 +0000453/* Perform a rotor decryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000454static void
455RTR_d_region(r, beg, len, doinit)
456 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000457 unsigned char *beg;
458 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000459 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000460{
461 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000462 if (doinit || r->isinited == FALSE)
463 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000464 for (i = 0; i < len; i++) {
465 beg[i] = RTR_d_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000466 }
467}
468
469
Barry Warsaw47d35001997-01-16 16:49:44 +0000470
Guido van Rossum50098201992-07-31 15:10:13 +0000471/* Rotor methods */
Guido van Rossum50098201992-07-31 15:10:13 +0000472static void
Barry Warsawaeb207c1996-12-23 23:36:24 +0000473rotor_dealloc(xp)
474 Rotorobj *xp;
Guido van Rossum50098201992-07-31 15:10:13 +0000475{
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000476 PyMem_XDEL(xp->e_rotor);
477 PyMem_XDEL(xp->d_rotor);
478 PyMem_XDEL(xp->positions);
479 PyMem_XDEL(xp->advances);
480 PyMem_DEL(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000481}
482
Guido van Rossumf6971e21994-08-30 12:25:20 +0000483static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000484rotorobj_encrypt(self, args)
485 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000486 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000487{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000488 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000489 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000490 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000491 char *tmp;
492
Barry Warsawaeb207c1996-12-23 23:36:24 +0000493 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000494 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000495 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000496 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000497 return NULL;
498 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000499 memset(tmp, '\0', len+1);
500 memcpy(tmp, string, len);
501 RTR_e_region(self, (unsigned char *)tmp, len, TRUE);
502 rtn = PyString_FromStringAndSize(tmp, len);
503 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000504 return(rtn);
505}
506
Guido van Rossumf6971e21994-08-30 12:25:20 +0000507static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000508rotorobj_encrypt_more(self, args)
509 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000510 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000511{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000512 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000513 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000514 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000515 char *tmp;
516
Barry Warsawaeb207c1996-12-23 23:36:24 +0000517 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000518 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000519 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000520 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000521 return NULL;
522 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000523 memset(tmp, '\0', len+1);
524 memcpy(tmp, string, len);
525 RTR_e_region(self, (unsigned char *)tmp, len, FALSE);
526 rtn = PyString_FromStringAndSize(tmp, len);
527 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000528 return(rtn);
529}
530
Guido van Rossumf6971e21994-08-30 12:25:20 +0000531static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000532rotorobj_decrypt(self, args)
533 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000534 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000535{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000536 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000537 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000538 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000539 char *tmp;
540
Barry Warsawaeb207c1996-12-23 23:36:24 +0000541 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000542 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000543 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000544 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000545 return NULL;
546 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000547 memset(tmp, '\0', len+1);
548 memcpy(tmp, string, len);
549 RTR_d_region(self, (unsigned char *)tmp, len, TRUE);
550 rtn = PyString_FromStringAndSize(tmp, len);
551 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000552 return(rtn);
553}
554
Guido van Rossumf6971e21994-08-30 12:25:20 +0000555static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000556rotorobj_decrypt_more(self, args)
557 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000558 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000559{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000560 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000561 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000562 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000563 char *tmp;
564
Barry Warsawaeb207c1996-12-23 23:36:24 +0000565 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000566 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000567 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000568 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000569 return NULL;
570 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000571 memset(tmp, '\0', len+1);
572 memcpy(tmp, string, len);
573 RTR_d_region(self, (unsigned char *)tmp, len, FALSE);
574 rtn = PyString_FromStringAndSize(tmp, len);
575 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000576 return(rtn);
577}
578
Guido van Rossumf6971e21994-08-30 12:25:20 +0000579static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000580rotorobj_setkey(self, args)
581 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000582 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000583{
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000584 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000585
Guido van Rossum43713e52000-02-29 13:59:29 +0000586 if (!PyArg_ParseTuple(args, "s:setkey", &key))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000587 return NULL;
588
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000589 set_key(self, key);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000590 Py_INCREF(Py_None);
591 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000592}
593
Barry Warsawaeb207c1996-12-23 23:36:24 +0000594static struct PyMethodDef
595rotorobj_methods[] = {
596 {"encrypt", (PyCFunction)rotorobj_encrypt},
597 {"encryptmore", (PyCFunction)rotorobj_encrypt_more},
598 {"decrypt", (PyCFunction)rotorobj_decrypt},
599 {"decryptmore", (PyCFunction)rotorobj_decrypt_more},
600 {"setkey", (PyCFunction)rotorobj_setkey, 1},
Guido van Rossum50098201992-07-31 15:10:13 +0000601 {NULL, NULL} /* sentinel */
602};
603
604
605/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000606static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000607rotorobj_getattr(s, name)
608 Rotorobj *s;
Guido van Rossum50098201992-07-31 15:10:13 +0000609 char *name;
610{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000611 return Py_FindMethod(rotorobj_methods, (PyObject*)s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000612}
613
Barry Warsawaeb207c1996-12-23 23:36:24 +0000614
615statichere PyTypeObject Rotor_Type = {
Guido van Rossuma597dde1995-01-10 20:56:29 +0000616 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000617 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000618 "rotor", /*tp_name*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000619 sizeof(Rotorobj), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000620 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000621 /* methods */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000622 (destructor)rotor_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000623 0, /*tp_print*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000624 (getattrfunc)rotorobj_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000625 0, /*tp_setattr*/
626 0, /*tp_compare*/
627 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000628 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000629};
630
631
Guido van Rossumf6971e21994-08-30 12:25:20 +0000632static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000633rotor_rotor(self, args)
Guido van Rossumf6971e21994-08-30 12:25:20 +0000634 PyObject * self;
635 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000636{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000637 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000638 char *string;
Guido van Rossum50098201992-07-31 15:10:13 +0000639 int len;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000640 int num_rotors = 6;
Guido van Rossum50098201992-07-31 15:10:13 +0000641
Guido van Rossum43713e52000-02-29 13:59:29 +0000642 if (!PyArg_ParseTuple(args, "s#|i:newrotor", &string, &len, &num_rotors))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000643 return NULL;
644
645 r = rotorobj_new(num_rotors, string);
646 return (PyObject *)r;
Guido van Rossum50098201992-07-31 15:10:13 +0000647}
648
Barry Warsawaeb207c1996-12-23 23:36:24 +0000649
Barry Warsaw47d35001997-01-16 16:49:44 +0000650
Barry Warsawaeb207c1996-12-23 23:36:24 +0000651static struct PyMethodDef
652rotor_methods[] = {
653 {"newrotor", rotor_rotor, 1},
654 {NULL, NULL} /* sentinel */
Guido van Rossum50098201992-07-31 15:10:13 +0000655};
656
657
Guido van Rossum3886bb61998-12-04 18:50:17 +0000658DL_EXPORT(void)
Guido van Rossum50098201992-07-31 15:10:13 +0000659initrotor()
660{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000661 (void)Py_InitModule("rotor", rotor_methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000662}