blob: cc2592422ac908ec2098cf4c747e53f2ad5a2de5 [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
Thomas Wouters7e474022000-07-16 12:04:32 +000026 a rotor due to the original design was a hardware rotor with
Guido van Rossum50098201992-07-31 15:10:13 +000027 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
Thomas Wouters7e474022000-07-16 12:04:32 +000046 initialized with {en,de}crypt since the last setkey() call;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000047 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 Rossuma597dde1995-01-10 20:56:29 +000059
Guido van Rossum19a6c8a1997-05-20 15:58:36 +000060#ifndef TRUE
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000061#define TRUE 1
Guido van Rossum19a6c8a1997-05-20 15:58:36 +000062#endif
63#ifndef FALSE
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000064#define FALSE 0
Guido van Rossum19a6c8a1997-05-20 15:58:36 +000065#endif
Guido van Rossum50098201992-07-31 15:10:13 +000066
67typedef struct {
Guido van Rossum7b1e9741994-08-29 10:46:42 +000068 PyObject_HEAD
Guido van Rossum50098201992-07-31 15:10:13 +000069 int seed[3];
70 short key[5];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000071 int isinited;
Guido van Rossum50098201992-07-31 15:10:13 +000072 int size;
73 int size_mask;
74 int rotors;
Barry Warsawaeb207c1996-12-23 23:36:24 +000075 unsigned char *e_rotor; /* [num_rotors][size] */
76 unsigned char *d_rotor; /* [num_rotors][size] */
77 unsigned char *positions; /* [num_rotors] */
78 unsigned char *advances; /* [num_rotors] */
79} Rotorobj;
Guido van Rossum50098201992-07-31 15:10:13 +000080
Barry Warsawaeb207c1996-12-23 23:36:24 +000081staticforward PyTypeObject Rotor_Type;
Guido van Rossum50098201992-07-31 15:10:13 +000082
Barry Warsawaeb207c1996-12-23 23:36:24 +000083#define is_rotor(v) ((v)->ob_type == &Rotor_Type)
Guido van Rossum50098201992-07-31 15:10:13 +000084
Barry Warsaw47d35001997-01-16 16:49:44 +000085
86/* This defines the necessary routines to manage rotor objects */
Guido van Rossum50098201992-07-31 15:10:13 +000087
Barry Warsawaeb207c1996-12-23 23:36:24 +000088static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +000089set_seed(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +000090{
91 r->seed[0] = r->key[0];
92 r->seed[1] = r->key[1];
93 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000094 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +000095}
96
97/* Return the next random number in the range [0.0 .. 1.0) */
Guido van Rossum7844e381997-04-11 20:44:04 +000098static double
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +000099r_random(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000100{
101 int x, y, z;
Guido van Rossum7844e381997-04-11 20:44:04 +0000102 double val, term;
Guido van Rossum50098201992-07-31 15:10:13 +0000103
104 x = r->seed[0];
105 y = r->seed[1];
106 z = r->seed[2];
107
108 x = 171 * (x % 177) - 2 * (x/177);
109 y = 172 * (y % 176) - 35 * (y/176);
110 z = 170 * (z % 178) - 63 * (z/178);
111
112 if (x < 0) x = x + 30269;
113 if (y < 0) y = y + 30307;
114 if (z < 0) z = z + 30323;
115
116 r->seed[0] = x;
117 r->seed[1] = y;
118 r->seed[2] = z;
119
Guido van Rossum7844e381997-04-11 20:44:04 +0000120 term = (double)(
121 (((double)x)/(double)30269.0) +
122 (((double)y)/(double)30307.0) +
123 (((double)z)/(double)30323.0)
Barry Warsawaeb207c1996-12-23 23:36:24 +0000124 );
Guido van Rossum7844e381997-04-11 20:44:04 +0000125 val = term - (double)floor((double)term);
Guido van Rossum50098201992-07-31 15:10:13 +0000126
Barry Warsawaeb207c1996-12-23 23:36:24 +0000127 if (val >= 1.0)
128 val = 0.0;
Guido van Rossum50098201992-07-31 15:10:13 +0000129
130 return val;
131}
132
Barry Warsawaeb207c1996-12-23 23:36:24 +0000133static short
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000134r_rand(Rotorobj *r, short s)
Guido van Rossum50098201992-07-31 15:10:13 +0000135{
Guido van Rossum7844e381997-04-11 20:44:04 +0000136 return (short)((short)(r_random(r) * (double)s) % s);
Guido van Rossum50098201992-07-31 15:10:13 +0000137}
138
Barry Warsawaeb207c1996-12-23 23:36:24 +0000139static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000140set_key(Rotorobj *r, char *key)
Guido van Rossum50098201992-07-31 15:10:13 +0000141{
Guido van Rossume77a7571993-11-03 15:01:26 +0000142 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossume8268952000-06-28 21:31:10 +0000143 size_t i;
144 size_t len = strlen(key);
Barry Warsaw47d35001997-01-16 16:49:44 +0000145
Barry Warsawaeb207c1996-12-23 23:36:24 +0000146 for (i = 0; i < len; i++) {
Barry Warsaw47d35001997-01-16 16:49:44 +0000147 unsigned short ki = Py_CHARMASK(key[i]);
148
149 k1 = (((k1<<3 | k1>>13) + ki) & 65535);
150 k2 = (((k2<<3 | k2>>13) ^ ki) & 65535);
151 k3 = (((k3<<3 | k3>>13) - ki) & 65535);
152 k4 = ((ki - (k4<<3 | k4>>13)) & 65535);
153 k5 = (((k5<<3 | k5>>13) ^ ~ki) & 65535);
Guido van Rossum50098201992-07-31 15:10:13 +0000154 }
155 r->key[0] = (short)k1;
156 r->key[1] = (short)(k2|1);
157 r->key[2] = (short)k3;
158 r->key[3] = (short)k4;
159 r->key[4] = (short)k5;
160
161 set_seed(r);
162}
163
Barry Warsaw47d35001997-01-16 16:49:44 +0000164
165
Guido van Rossum50098201992-07-31 15:10:13 +0000166/* These define the interface to a rotor object */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000167static Rotorobj *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000168rotorobj_new(int num_rotors, char *key)
Guido van Rossum50098201992-07-31 15:10:13 +0000169{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000170 Rotorobj *xp;
171
Guido van Rossumb18618d2000-05-03 23:44:39 +0000172 xp = PyObject_New(Rotorobj, &Rotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000173 if (xp == NULL)
174 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000175 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000176
177 xp->size = 256;
178 xp->size_mask = xp->size - 1;
179 xp->size_mask = 0;
180 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000181 xp->e_rotor = NULL;
182 xp->d_rotor = NULL;
183 xp->positions = NULL;
184 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000185
Barry Warsawaeb207c1996-12-23 23:36:24 +0000186 if (!(xp->e_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
187 goto finally;
188 if (!(xp->d_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
189 goto finally;
190 if (!(xp->positions = PyMem_NEW(unsigned char, num_rotors)))
191 goto finally;
192 if (!(xp->advances = PyMem_NEW(unsigned char, num_rotors)))
193 goto finally;
194
Guido van Rossum50098201992-07-31 15:10:13 +0000195 return xp;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000196
197 finally:
Guido van Rossumb18618d2000-05-03 23:44:39 +0000198 if (xp->e_rotor)
199 PyMem_DEL(xp->e_rotor);
200 if (xp->d_rotor)
201 PyMem_DEL(xp->d_rotor);
202 if (xp->positions)
203 PyMem_DEL(xp->positions);
204 if (xp->advances)
205 PyMem_DEL(xp->advances);
Guido van Rossuma597dde1995-01-10 20:56:29 +0000206 Py_DECREF(xp);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000207 return (Rotorobj*)PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000208}
209
Barry Warsaw47d35001997-01-16 16:49:44 +0000210
Thomas Wouters7e474022000-07-16 12:04:32 +0000211/* These routines implement the rotor itself */
Guido van Rossum50098201992-07-31 15:10:13 +0000212
Barry Warsaw47d35001997-01-16 16:49:44 +0000213/* Here is a fairly sophisticated {en,de}cryption system. It is based on
214 the idea of a "rotor" machine. A bunch of rotors, each with a
Barry Warsawaeb207c1996-12-23 23:36:24 +0000215 different permutation of the alphabet, rotate around a different amount
216 after encrypting one character. The current state of the rotors is
217 used to encrypt one character.
Guido van Rossum50098201992-07-31 15:10:13 +0000218
Thomas Wouters7e474022000-07-16 12:04:32 +0000219 The code is smart enough to tell if your alphabet has a number of
Barry Warsawaeb207c1996-12-23 23:36:24 +0000220 characters equal to a power of two. If it does, it uses logical
221 operations, if not it uses div and mod (both require a division).
Guido van Rossum50098201992-07-31 15:10:13 +0000222
Barry Warsawaeb207c1996-12-23 23:36:24 +0000223 You will need to make two changes to the code 1) convert to c, and
224 customize for an alphabet of 255 chars 2) add a filter at the begining,
225 and end, which subtracts one on the way in, and adds one on the way
226 out.
Guido van Rossum50098201992-07-31 15:10:13 +0000227
Barry Warsawaeb207c1996-12-23 23:36:24 +0000228 You might wish to do some timing studies. Another viable alternative
229 is to "byte stuff" the encrypted data of a normal (perhaps this one)
230 encryption routine.
Guido van Rossum50098201992-07-31 15:10:13 +0000231
Barry Warsawaeb207c1996-12-23 23:36:24 +0000232 j'
Guido van Rossum50098201992-07-31 15:10:13 +0000233
Barry Warsaw47d35001997-01-16 16:49:44 +0000234 */
235
236/* Note: the C code here is a fairly straightforward transliteration of a
237 * rotor implemented in lisp. The original lisp code has been removed from
238 * this file to for simplification, but I've kept the docstrings as
239 * comments in front of the functions.
240 */
241
242
243/* Set ROTOR to the identity permutation */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000244static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000245RTR_make_id_rotor(Rotorobj *r, unsigned char *rtr)
Guido van Rossum50098201992-07-31 15:10:13 +0000246{
247 register int j;
248 register int size = r->size;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000249 for (j = 0; j < size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000250 rtr[j] = (unsigned char)j;
251 }
252}
253
254
Barry Warsaw47d35001997-01-16 16:49:44 +0000255/* The current set of encryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000256static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000257RTR_e_rotors(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000258{
259 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000260 for (i = 0; i < r->rotors; i++) {
261 RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000262 }
263}
264
Barry Warsaw47d35001997-01-16 16:49:44 +0000265/* The current set of decryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000266static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000267RTR_d_rotors(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000268{
269 register int i, j;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000270 for (i = 0; i < r->rotors; i++) {
271 for (j = 0; j < r->size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000272 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
273 }
274 }
275}
276
Barry Warsaw47d35001997-01-16 16:49:44 +0000277/* The positions of the rotors at this time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000278static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000279RTR_positions(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000280{
281 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000282 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000283 r->positions[i] = 1;
284 }
285}
286
Barry Warsaw47d35001997-01-16 16:49:44 +0000287/* The number of positions to advance the rotors at a time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000288static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000289RTR_advances(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->advances[i] = 1;
294 }
295}
296
Barry Warsaw47d35001997-01-16 16:49:44 +0000297/* Permute the E rotor, and make the D rotor its inverse
298 * see Knuth for explanation of algorithm.
299 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000300static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000301RTR_permute_rotor(Rotorobj *r, unsigned char *e, unsigned char *d)
Guido van Rossum50098201992-07-31 15:10:13 +0000302{
303 short i = r->size;
304 short q;
305 unsigned char j;
306 RTR_make_id_rotor(r,e);
307 while (2 <= i) {
308 q = r_rand(r,i);
309 i--;
310 j = e[q];
311 e[q] = (unsigned char)e[i];
312 e[i] = (unsigned char)j;
313 d[j] = (unsigned char)i;
314 }
315 e[0] = (unsigned char)e[0];
316 d[(e[0])] = (unsigned char)0;
317}
318
Barry Warsaw47d35001997-01-16 16:49:44 +0000319/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
320 * Set the advancement, position, and permutation of the rotors
321 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000322static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000323RTR_init(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000324{
325 int i;
326 set_seed(r);
327 RTR_positions(r);
328 RTR_advances(r);
329 RTR_e_rotors(r);
330 RTR_d_rotors(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000331 for (i = 0; i < r->rotors; i++) {
Tim Petersdc0c0312000-07-10 22:41:30 +0000332 r->positions[i] = (unsigned char) r_rand(r, (short)r->size);
333 r->advances[i] = (1+(2*(r_rand(r, (short)(r->size/2)))));
Barry Warsawaeb207c1996-12-23 23:36:24 +0000334 RTR_permute_rotor(r,
335 &(r->e_rotor[(i*r->size)]),
336 &(r->d_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000337 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000338 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000339}
340
Barry Warsaw47d35001997-01-16 16:49:44 +0000341/* Change the RTR-positions vector, using the RTR-advances vector */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000342static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000343RTR_advance(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000344{
345 register int i=0, temp=0;
346 if (r->size_mask) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000347 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000348 temp = r->positions[i] + r->advances[i];
349 r->positions[i] = temp & r->size_mask;
350 if ((temp >= r->size) && (i < (r->rotors - 1))) {
351 r->positions[(i+1)] = 1 + r->positions[(i+1)];
352 }
353 i++;
354 }
355 } else {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000356 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000357 temp = r->positions[i] + r->advances[i];
358 r->positions[i] = temp%r->size;
359 if ((temp >= r->size) && (i < (r->rotors - 1))) {
360 r->positions[(i+1)] = 1 + r->positions[(i+1)];
361 }
362 i++;
363 }
364 }
365}
366
Barry Warsaw47d35001997-01-16 16:49:44 +0000367/* Encrypt the character P with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000368static unsigned char
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000369RTR_e_char(Rotorobj *r, unsigned char p)
Guido van Rossum50098201992-07-31 15:10:13 +0000370{
371 register int i=0;
372 register unsigned char tp=p;
373 if (r->size_mask) {
374 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000375 tp = r->e_rotor[(i*r->size) +
376 (((r->positions[i] ^ tp) &
377 r->size_mask))];
Guido van Rossum50098201992-07-31 15:10:13 +0000378 i++;
379 }
380 } else {
381 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000382 tp = r->e_rotor[(i*r->size) +
383 (((r->positions[i] ^ tp) %
384 (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000385 i++;
386 }
387 }
388 RTR_advance(r);
389 return ((unsigned char)tp);
390}
391
Barry Warsaw47d35001997-01-16 16:49:44 +0000392/* Decrypt the character C with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000393static unsigned char
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000394RTR_d_char(Rotorobj *r, unsigned char c)
Guido van Rossum50098201992-07-31 15:10:13 +0000395{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000396 register int i = r->rotors - 1;
397 register unsigned char tc = c;
398
Guido van Rossum50098201992-07-31 15:10:13 +0000399 if (r->size_mask) {
400 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000401 tc = (r->positions[i] ^
402 r->d_rotor[(i*r->size)+tc]) & r->size_mask;
Guido van Rossum50098201992-07-31 15:10:13 +0000403 i--;
404 }
405 } else {
406 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000407 tc = (r->positions[i] ^
408 r->d_rotor[(i*r->size)+tc]) %
409 (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000410 i--;
411 }
412 }
413 RTR_advance(r);
414 return(tc);
415}
416
Barry Warsaw47d35001997-01-16 16:49:44 +0000417/* Perform a rotor encryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000418static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000419RTR_e_region(Rotorobj *r, unsigned char *beg, int len, int doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000420{
421 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000422 if (doinit || r->isinited == FALSE)
423 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000424 for (i = 0; i < len; i++) {
425 beg[i] = RTR_e_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000426 }
427}
428
Barry Warsaw47d35001997-01-16 16:49:44 +0000429/* Perform a rotor decryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000430static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000431RTR_d_region(Rotorobj *r, unsigned char *beg, int len, int doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000432{
433 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000434 if (doinit || r->isinited == FALSE)
435 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000436 for (i = 0; i < len; i++) {
437 beg[i] = RTR_d_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000438 }
439}
440
441
Barry Warsaw47d35001997-01-16 16:49:44 +0000442
Guido van Rossum50098201992-07-31 15:10:13 +0000443/* Rotor methods */
Guido van Rossum50098201992-07-31 15:10:13 +0000444static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000445rotor_dealloc(Rotorobj *xp)
Guido van Rossum50098201992-07-31 15:10:13 +0000446{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000447 if (xp->e_rotor)
448 PyMem_DEL(xp->e_rotor);
449 if (xp->d_rotor)
450 PyMem_DEL(xp->d_rotor);
451 if (xp->positions)
452 PyMem_DEL(xp->positions);
453 if (xp->advances)
454 PyMem_DEL(xp->advances);
455 PyObject_Del(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000456}
457
Guido van Rossumf6971e21994-08-30 12:25:20 +0000458static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000459rotorobj_encrypt(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000460{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000461 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000462 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000463 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000464 char *tmp;
465
Barry Warsawaeb207c1996-12-23 23:36:24 +0000466 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000467 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000468 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000469 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000470 return NULL;
471 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000472 memset(tmp, '\0', len+1);
473 memcpy(tmp, string, len);
474 RTR_e_region(self, (unsigned char *)tmp, len, TRUE);
475 rtn = PyString_FromStringAndSize(tmp, len);
476 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000477 return(rtn);
478}
479
Guido van Rossumf6971e21994-08-30 12:25:20 +0000480static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000481rotorobj_encrypt_more(Rotorobj *self, PyObject *args)
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000482{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000483 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000484 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000485 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000486 char *tmp;
487
Barry Warsawaeb207c1996-12-23 23:36:24 +0000488 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000489 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000490 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000491 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000492 return NULL;
493 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000494 memset(tmp, '\0', len+1);
495 memcpy(tmp, string, len);
496 RTR_e_region(self, (unsigned char *)tmp, len, FALSE);
497 rtn = PyString_FromStringAndSize(tmp, len);
498 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000499 return(rtn);
500}
501
Guido van Rossumf6971e21994-08-30 12:25:20 +0000502static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000503rotorobj_decrypt(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000504{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000505 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000506 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000507 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000508 char *tmp;
509
Barry Warsawaeb207c1996-12-23 23:36:24 +0000510 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000511 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000512 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000513 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000514 return NULL;
515 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000516 memset(tmp, '\0', len+1);
517 memcpy(tmp, string, len);
518 RTR_d_region(self, (unsigned char *)tmp, len, TRUE);
519 rtn = PyString_FromStringAndSize(tmp, len);
520 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000521 return(rtn);
522}
523
Guido van Rossumf6971e21994-08-30 12:25:20 +0000524static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000525rotorobj_decrypt_more(Rotorobj *self, PyObject *args)
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000526{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000527 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000528 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000529 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000530 char *tmp;
531
Barry Warsawaeb207c1996-12-23 23:36:24 +0000532 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000533 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000534 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000535 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000536 return NULL;
537 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000538 memset(tmp, '\0', len+1);
539 memcpy(tmp, string, len);
540 RTR_d_region(self, (unsigned char *)tmp, len, FALSE);
541 rtn = PyString_FromStringAndSize(tmp, len);
542 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000543 return(rtn);
544}
545
Guido van Rossumf6971e21994-08-30 12:25:20 +0000546static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000547rotorobj_setkey(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000548{
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000549 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000550
Guido van Rossum43713e52000-02-29 13:59:29 +0000551 if (!PyArg_ParseTuple(args, "s:setkey", &key))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000552 return NULL;
553
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000554 set_key(self, key);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000555 Py_INCREF(Py_None);
556 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000557}
558
Barry Warsawaeb207c1996-12-23 23:36:24 +0000559static struct PyMethodDef
560rotorobj_methods[] = {
561 {"encrypt", (PyCFunction)rotorobj_encrypt},
562 {"encryptmore", (PyCFunction)rotorobj_encrypt_more},
563 {"decrypt", (PyCFunction)rotorobj_decrypt},
564 {"decryptmore", (PyCFunction)rotorobj_decrypt_more},
565 {"setkey", (PyCFunction)rotorobj_setkey, 1},
Guido van Rossum50098201992-07-31 15:10:13 +0000566 {NULL, NULL} /* sentinel */
567};
568
569
570/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000571static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000572rotorobj_getattr(Rotorobj *s, char *name)
Guido van Rossum50098201992-07-31 15:10:13 +0000573{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000574 return Py_FindMethod(rotorobj_methods, (PyObject*)s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000575}
576
Barry Warsawaeb207c1996-12-23 23:36:24 +0000577
578statichere PyTypeObject Rotor_Type = {
Guido van Rossum5a530192001-01-10 21:03:32 +0000579 PyObject_HEAD_INIT(NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000580 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000581 "rotor", /*tp_name*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000582 sizeof(Rotorobj), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000583 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000584 /* methods */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000585 (destructor)rotor_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000586 0, /*tp_print*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000587 (getattrfunc)rotorobj_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000588 0, /*tp_setattr*/
589 0, /*tp_compare*/
590 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000591 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000592};
593
594
Guido van Rossumf6971e21994-08-30 12:25:20 +0000595static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000596rotor_rotor(PyObject *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000597{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000598 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000599 char *string;
Guido van Rossum50098201992-07-31 15:10:13 +0000600 int len;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000601 int num_rotors = 6;
Guido van Rossum50098201992-07-31 15:10:13 +0000602
Guido van Rossum43713e52000-02-29 13:59:29 +0000603 if (!PyArg_ParseTuple(args, "s#|i:newrotor", &string, &len, &num_rotors))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000604 return NULL;
605
606 r = rotorobj_new(num_rotors, string);
607 return (PyObject *)r;
Guido van Rossum50098201992-07-31 15:10:13 +0000608}
609
Barry Warsawaeb207c1996-12-23 23:36:24 +0000610
Barry Warsaw47d35001997-01-16 16:49:44 +0000611
Barry Warsawaeb207c1996-12-23 23:36:24 +0000612static struct PyMethodDef
613rotor_methods[] = {
614 {"newrotor", rotor_rotor, 1},
615 {NULL, NULL} /* sentinel */
Guido van Rossum50098201992-07-31 15:10:13 +0000616};
617
618
Guido van Rossum3886bb61998-12-04 18:50:17 +0000619DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000620initrotor(void)
Guido van Rossum50098201992-07-31 15:10:13 +0000621{
Guido van Rossum5a530192001-01-10 21:03:32 +0000622 Rotor_Type.ob_type = &PyType_Type;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000623 (void)Py_InitModule("rotor", rotor_methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000624}