blob: 3d570f7751c61e3e2e91c9d877a1cafa666483a5 [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
Guido van Rossumb18618d2000-05-03 23:44:39 +0000181 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:
Guido van Rossumb18618d2000-05-03 23:44:39 +0000207 if (xp->e_rotor)
208 PyMem_DEL(xp->e_rotor);
209 if (xp->d_rotor)
210 PyMem_DEL(xp->d_rotor);
211 if (xp->positions)
212 PyMem_DEL(xp->positions);
213 if (xp->advances)
214 PyMem_DEL(xp->advances);
Guido van Rossuma597dde1995-01-10 20:56:29 +0000215 Py_DECREF(xp);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000216 return (Rotorobj*)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000217}
218
Barry Warsaw47d35001997-01-16 16:49:44 +0000219
Guido van Rossum50098201992-07-31 15:10:13 +0000220/* These routines impliment the rotor itself */
221
Barry Warsaw47d35001997-01-16 16:49:44 +0000222/* Here is a fairly sophisticated {en,de}cryption system. It is based on
223 the idea of a "rotor" machine. A bunch of rotors, each with a
Barry Warsawaeb207c1996-12-23 23:36:24 +0000224 different permutation of the alphabet, rotate around a different amount
225 after encrypting one character. The current state of the rotors is
226 used to encrypt one character.
Guido van Rossum50098201992-07-31 15:10:13 +0000227
Barry Warsawaeb207c1996-12-23 23:36:24 +0000228 The code is smart enought to tell if your alphabet has a number of
229 characters equal to a power of two. If it does, it uses logical
230 operations, if not it uses div and mod (both require a division).
Guido van Rossum50098201992-07-31 15:10:13 +0000231
Barry Warsawaeb207c1996-12-23 23:36:24 +0000232 You will need to make two changes to the code 1) convert to c, and
233 customize for an alphabet of 255 chars 2) add a filter at the begining,
234 and end, which subtracts one on the way in, and adds one on the way
235 out.
Guido van Rossum50098201992-07-31 15:10:13 +0000236
Barry Warsawaeb207c1996-12-23 23:36:24 +0000237 You might wish to do some timing studies. Another viable alternative
238 is to "byte stuff" the encrypted data of a normal (perhaps this one)
239 encryption routine.
Guido van Rossum50098201992-07-31 15:10:13 +0000240
Barry Warsawaeb207c1996-12-23 23:36:24 +0000241 j'
Guido van Rossum50098201992-07-31 15:10:13 +0000242
Barry Warsaw47d35001997-01-16 16:49:44 +0000243 */
244
245/* Note: the C code here is a fairly straightforward transliteration of a
246 * rotor implemented in lisp. The original lisp code has been removed from
247 * this file to for simplification, but I've kept the docstrings as
248 * comments in front of the functions.
249 */
250
251
252/* Set ROTOR to the identity permutation */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000253static void
254RTR_make_id_rotor(r, rtr)
255 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000256 unsigned char *rtr;
257{
258 register int j;
259 register int size = r->size;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000260 for (j = 0; j < size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000261 rtr[j] = (unsigned char)j;
262 }
263}
264
265
Barry Warsaw47d35001997-01-16 16:49:44 +0000266/* The current set of encryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000267static void
268RTR_e_rotors(r)
269 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000270{
271 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000272 for (i = 0; i < r->rotors; i++) {
273 RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000274 }
275}
276
Barry Warsaw47d35001997-01-16 16:49:44 +0000277/* The current set of decryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000278static void
279RTR_d_rotors(r)
280 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000281{
282 register int i, j;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000283 for (i = 0; i < r->rotors; i++) {
284 for (j = 0; j < r->size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000285 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
286 }
287 }
288}
289
Barry Warsaw47d35001997-01-16 16:49:44 +0000290/* The positions of the rotors at this time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000291static void
292RTR_positions(r)
293 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000294{
295 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000296 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000297 r->positions[i] = 1;
298 }
299}
300
Barry Warsaw47d35001997-01-16 16:49:44 +0000301/* The number of positions to advance the rotors at a time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000302static void
303RTR_advances(r)
304 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000305{
306 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000307 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000308 r->advances[i] = 1;
309 }
310}
311
Barry Warsaw47d35001997-01-16 16:49:44 +0000312/* Permute the E rotor, and make the D rotor its inverse
313 * see Knuth for explanation of algorithm.
314 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000315static void
316RTR_permute_rotor(r, e, d)
317 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000318 unsigned char *e;
319 unsigned char *d;
320{
321 short i = r->size;
322 short q;
323 unsigned char j;
324 RTR_make_id_rotor(r,e);
325 while (2 <= i) {
326 q = r_rand(r,i);
327 i--;
328 j = e[q];
329 e[q] = (unsigned char)e[i];
330 e[i] = (unsigned char)j;
331 d[j] = (unsigned char)i;
332 }
333 e[0] = (unsigned char)e[0];
334 d[(e[0])] = (unsigned char)0;
335}
336
Barry Warsaw47d35001997-01-16 16:49:44 +0000337/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
338 * Set the advancement, position, and permutation of the rotors
339 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000340static void
341RTR_init(r)
342 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000343{
344 int i;
345 set_seed(r);
346 RTR_positions(r);
347 RTR_advances(r);
348 RTR_e_rotors(r);
349 RTR_d_rotors(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000350 for (i = 0; i < r->rotors; i++) {
Guido van Rossum7844e381997-04-11 20:44:04 +0000351 r->positions[i] = (unsigned char) r_rand(r,r->size);
Guido van Rossum50098201992-07-31 15:10:13 +0000352 r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
Barry Warsawaeb207c1996-12-23 23:36:24 +0000353 RTR_permute_rotor(r,
354 &(r->e_rotor[(i*r->size)]),
355 &(r->d_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000356 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000357 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000358}
359
Barry Warsaw47d35001997-01-16 16:49:44 +0000360/* Change the RTR-positions vector, using the RTR-advances vector */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000361static void
362RTR_advance(r)
363 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000364{
365 register int i=0, temp=0;
366 if (r->size_mask) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000367 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000368 temp = r->positions[i] + r->advances[i];
369 r->positions[i] = temp & r->size_mask;
370 if ((temp >= r->size) && (i < (r->rotors - 1))) {
371 r->positions[(i+1)] = 1 + r->positions[(i+1)];
372 }
373 i++;
374 }
375 } else {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000376 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000377 temp = r->positions[i] + r->advances[i];
378 r->positions[i] = temp%r->size;
379 if ((temp >= r->size) && (i < (r->rotors - 1))) {
380 r->positions[(i+1)] = 1 + r->positions[(i+1)];
381 }
382 i++;
383 }
384 }
385}
386
Barry Warsaw47d35001997-01-16 16:49:44 +0000387/* Encrypt the character P with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000388static unsigned char
389RTR_e_char(r, p)
390 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000391 unsigned char p;
392{
393 register int i=0;
394 register unsigned char tp=p;
395 if (r->size_mask) {
396 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000397 tp = r->e_rotor[(i*r->size) +
398 (((r->positions[i] ^ tp) &
399 r->size_mask))];
Guido van Rossum50098201992-07-31 15:10:13 +0000400 i++;
401 }
402 } else {
403 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000404 tp = r->e_rotor[(i*r->size) +
405 (((r->positions[i] ^ tp) %
406 (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000407 i++;
408 }
409 }
410 RTR_advance(r);
411 return ((unsigned char)tp);
412}
413
Barry Warsaw47d35001997-01-16 16:49:44 +0000414/* Decrypt the character C with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000415static unsigned char
416RTR_d_char(r, c)
417 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000418 unsigned char c;
419{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000420 register int i = r->rotors - 1;
421 register unsigned char tc = c;
422
Guido van Rossum50098201992-07-31 15:10:13 +0000423 if (r->size_mask) {
424 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000425 tc = (r->positions[i] ^
426 r->d_rotor[(i*r->size)+tc]) & r->size_mask;
Guido van Rossum50098201992-07-31 15:10:13 +0000427 i--;
428 }
429 } else {
430 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000431 tc = (r->positions[i] ^
432 r->d_rotor[(i*r->size)+tc]) %
433 (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000434 i--;
435 }
436 }
437 RTR_advance(r);
438 return(tc);
439}
440
Barry Warsaw47d35001997-01-16 16:49:44 +0000441/* Perform a rotor encryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000442static void
443RTR_e_region(r, beg, len, doinit)
444 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000445 unsigned char *beg;
446 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000447 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000448{
449 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000450 if (doinit || r->isinited == FALSE)
451 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000452 for (i = 0; i < len; i++) {
453 beg[i] = RTR_e_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000454 }
455}
456
Barry Warsaw47d35001997-01-16 16:49:44 +0000457/* Perform a rotor decryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000458static void
459RTR_d_region(r, beg, len, doinit)
460 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000461 unsigned char *beg;
462 int len;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000463 int doinit;
Guido van Rossum50098201992-07-31 15:10:13 +0000464{
465 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000466 if (doinit || r->isinited == FALSE)
467 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000468 for (i = 0; i < len; i++) {
469 beg[i] = RTR_d_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000470 }
471}
472
473
Barry Warsaw47d35001997-01-16 16:49:44 +0000474
Guido van Rossum50098201992-07-31 15:10:13 +0000475/* Rotor methods */
Guido van Rossum50098201992-07-31 15:10:13 +0000476static void
Barry Warsawaeb207c1996-12-23 23:36:24 +0000477rotor_dealloc(xp)
478 Rotorobj *xp;
Guido van Rossum50098201992-07-31 15:10:13 +0000479{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000480 if (xp->e_rotor)
481 PyMem_DEL(xp->e_rotor);
482 if (xp->d_rotor)
483 PyMem_DEL(xp->d_rotor);
484 if (xp->positions)
485 PyMem_DEL(xp->positions);
486 if (xp->advances)
487 PyMem_DEL(xp->advances);
488 PyObject_Del(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000489}
490
Guido van Rossumf6971e21994-08-30 12:25:20 +0000491static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000492rotorobj_encrypt(self, args)
493 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000494 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000495{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000496 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000497 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000498 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000499 char *tmp;
500
Barry Warsawaeb207c1996-12-23 23:36:24 +0000501 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000502 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000503 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000504 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000505 return NULL;
506 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000507 memset(tmp, '\0', len+1);
508 memcpy(tmp, string, len);
509 RTR_e_region(self, (unsigned char *)tmp, len, TRUE);
510 rtn = PyString_FromStringAndSize(tmp, len);
511 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000512 return(rtn);
513}
514
Guido van Rossumf6971e21994-08-30 12:25:20 +0000515static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000516rotorobj_encrypt_more(self, args)
517 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000518 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000519{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000520 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000521 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000522 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000523 char *tmp;
524
Barry Warsawaeb207c1996-12-23 23:36:24 +0000525 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000526 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000527 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000528 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000529 return NULL;
530 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000531 memset(tmp, '\0', len+1);
532 memcpy(tmp, string, len);
533 RTR_e_region(self, (unsigned char *)tmp, len, FALSE);
534 rtn = PyString_FromStringAndSize(tmp, len);
535 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000536 return(rtn);
537}
538
Guido van Rossumf6971e21994-08-30 12:25:20 +0000539static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000540rotorobj_decrypt(self, args)
541 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000542 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000543{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000544 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000545 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000546 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000547 char *tmp;
548
Barry Warsawaeb207c1996-12-23 23:36:24 +0000549 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000550 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000551 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000552 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000553 return NULL;
554 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000555 memset(tmp, '\0', len+1);
556 memcpy(tmp, string, len);
557 RTR_d_region(self, (unsigned char *)tmp, len, TRUE);
558 rtn = PyString_FromStringAndSize(tmp, len);
559 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000560 return(rtn);
561}
562
Guido van Rossumf6971e21994-08-30 12:25:20 +0000563static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000564rotorobj_decrypt_more(self, args)
565 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000566 PyObject * args;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000567{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000568 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000569 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000570 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000571 char *tmp;
572
Barry Warsawaeb207c1996-12-23 23:36:24 +0000573 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000574 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000575 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000576 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000577 return NULL;
578 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000579 memset(tmp, '\0', len+1);
580 memcpy(tmp, string, len);
581 RTR_d_region(self, (unsigned char *)tmp, len, FALSE);
582 rtn = PyString_FromStringAndSize(tmp, len);
583 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000584 return(rtn);
585}
586
Guido van Rossumf6971e21994-08-30 12:25:20 +0000587static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000588rotorobj_setkey(self, args)
589 Rotorobj *self;
Guido van Rossumf6971e21994-08-30 12:25:20 +0000590 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000591{
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000592 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000593
Guido van Rossum43713e52000-02-29 13:59:29 +0000594 if (!PyArg_ParseTuple(args, "s:setkey", &key))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000595 return NULL;
596
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000597 set_key(self, key);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000598 Py_INCREF(Py_None);
599 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000600}
601
Barry Warsawaeb207c1996-12-23 23:36:24 +0000602static struct PyMethodDef
603rotorobj_methods[] = {
604 {"encrypt", (PyCFunction)rotorobj_encrypt},
605 {"encryptmore", (PyCFunction)rotorobj_encrypt_more},
606 {"decrypt", (PyCFunction)rotorobj_decrypt},
607 {"decryptmore", (PyCFunction)rotorobj_decrypt_more},
608 {"setkey", (PyCFunction)rotorobj_setkey, 1},
Guido van Rossum50098201992-07-31 15:10:13 +0000609 {NULL, NULL} /* sentinel */
610};
611
612
613/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000614static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000615rotorobj_getattr(s, name)
616 Rotorobj *s;
Guido van Rossum50098201992-07-31 15:10:13 +0000617 char *name;
618{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000619 return Py_FindMethod(rotorobj_methods, (PyObject*)s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000620}
621
Barry Warsawaeb207c1996-12-23 23:36:24 +0000622
623statichere PyTypeObject Rotor_Type = {
Guido van Rossuma597dde1995-01-10 20:56:29 +0000624 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000625 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000626 "rotor", /*tp_name*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000627 sizeof(Rotorobj), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000628 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000629 /* methods */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000630 (destructor)rotor_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000631 0, /*tp_print*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000632 (getattrfunc)rotorobj_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000633 0, /*tp_setattr*/
634 0, /*tp_compare*/
635 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000636 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000637};
638
639
Guido van Rossumf6971e21994-08-30 12:25:20 +0000640static PyObject *
Barry Warsawaeb207c1996-12-23 23:36:24 +0000641rotor_rotor(self, args)
Guido van Rossumf6971e21994-08-30 12:25:20 +0000642 PyObject * self;
643 PyObject * args;
Guido van Rossum50098201992-07-31 15:10:13 +0000644{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000645 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000646 char *string;
Guido van Rossum50098201992-07-31 15:10:13 +0000647 int len;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000648 int num_rotors = 6;
Guido van Rossum50098201992-07-31 15:10:13 +0000649
Guido van Rossum43713e52000-02-29 13:59:29 +0000650 if (!PyArg_ParseTuple(args, "s#|i:newrotor", &string, &len, &num_rotors))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000651 return NULL;
652
653 r = rotorobj_new(num_rotors, string);
654 return (PyObject *)r;
Guido van Rossum50098201992-07-31 15:10:13 +0000655}
656
Barry Warsawaeb207c1996-12-23 23:36:24 +0000657
Barry Warsaw47d35001997-01-16 16:49:44 +0000658
Barry Warsawaeb207c1996-12-23 23:36:24 +0000659static struct PyMethodDef
660rotor_methods[] = {
661 {"newrotor", rotor_rotor, 1},
662 {NULL, NULL} /* sentinel */
Guido van Rossum50098201992-07-31 15:10:13 +0000663};
664
665
Guido van Rossum3886bb61998-12-04 18:50:17 +0000666DL_EXPORT(void)
Guido van Rossum50098201992-07-31 15:10:13 +0000667initrotor()
668{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000669 (void)Py_InitModule("rotor", rotor_methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000670}