blob: 393e73a11daad98eee5db943768e29965570f61d [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 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
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +000090set_seed(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +000091{
92 r->seed[0] = r->key[0];
93 r->seed[1] = r->key[1];
94 r->seed[2] = r->key[2];
Guido van Rossum7b2c03f1992-08-02 09:00:06 +000095 r->isinited = FALSE;
Guido van Rossum50098201992-07-31 15:10:13 +000096}
97
98/* Return the next random number in the range [0.0 .. 1.0) */
Guido van Rossum7844e381997-04-11 20:44:04 +000099static double
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000100r_random(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000101{
102 int x, y, z;
Guido van Rossum7844e381997-04-11 20:44:04 +0000103 double val, term;
Guido van Rossum50098201992-07-31 15:10:13 +0000104
105 x = r->seed[0];
106 y = r->seed[1];
107 z = r->seed[2];
108
109 x = 171 * (x % 177) - 2 * (x/177);
110 y = 172 * (y % 176) - 35 * (y/176);
111 z = 170 * (z % 178) - 63 * (z/178);
112
113 if (x < 0) x = x + 30269;
114 if (y < 0) y = y + 30307;
115 if (z < 0) z = z + 30323;
116
117 r->seed[0] = x;
118 r->seed[1] = y;
119 r->seed[2] = z;
120
Guido van Rossum7844e381997-04-11 20:44:04 +0000121 term = (double)(
122 (((double)x)/(double)30269.0) +
123 (((double)y)/(double)30307.0) +
124 (((double)z)/(double)30323.0)
Barry Warsawaeb207c1996-12-23 23:36:24 +0000125 );
Guido van Rossum7844e381997-04-11 20:44:04 +0000126 val = term - (double)floor((double)term);
Guido van Rossum50098201992-07-31 15:10:13 +0000127
Barry Warsawaeb207c1996-12-23 23:36:24 +0000128 if (val >= 1.0)
129 val = 0.0;
Guido van Rossum50098201992-07-31 15:10:13 +0000130
131 return val;
132}
133
Barry Warsawaeb207c1996-12-23 23:36:24 +0000134static short
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000135r_rand(Rotorobj *r, 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
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000141set_key(Rotorobj *r, char *key)
Guido van Rossum50098201992-07-31 15:10:13 +0000142{
Guido van Rossume77a7571993-11-03 15:01:26 +0000143 unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
Guido van Rossume8268952000-06-28 21:31:10 +0000144 size_t i;
145 size_t len = strlen(key);
Barry Warsaw47d35001997-01-16 16:49:44 +0000146
Barry Warsawaeb207c1996-12-23 23:36:24 +0000147 for (i = 0; i < len; i++) {
Barry Warsaw47d35001997-01-16 16:49:44 +0000148 unsigned short ki = Py_CHARMASK(key[i]);
149
150 k1 = (((k1<<3 | k1>>13) + ki) & 65535);
151 k2 = (((k2<<3 | k2>>13) ^ ki) & 65535);
152 k3 = (((k3<<3 | k3>>13) - ki) & 65535);
153 k4 = ((ki - (k4<<3 | k4>>13)) & 65535);
154 k5 = (((k5<<3 | k5>>13) ^ ~ki) & 65535);
Guido van Rossum50098201992-07-31 15:10:13 +0000155 }
156 r->key[0] = (short)k1;
157 r->key[1] = (short)(k2|1);
158 r->key[2] = (short)k3;
159 r->key[3] = (short)k4;
160 r->key[4] = (short)k5;
161
162 set_seed(r);
163}
164
Barry Warsaw47d35001997-01-16 16:49:44 +0000165
166
Guido van Rossum50098201992-07-31 15:10:13 +0000167/* These define the interface to a rotor object */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000168static Rotorobj *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000169rotorobj_new(int num_rotors, char *key)
Guido van Rossum50098201992-07-31 15:10:13 +0000170{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000171 Rotorobj *xp;
172
Guido van Rossumb18618d2000-05-03 23:44:39 +0000173 xp = PyObject_New(Rotorobj, &Rotor_Type);
Guido van Rossum50098201992-07-31 15:10:13 +0000174 if (xp == NULL)
175 return NULL;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000176 set_key(xp, key);
Guido van Rossum50098201992-07-31 15:10:13 +0000177
178 xp->size = 256;
179 xp->size_mask = xp->size - 1;
180 xp->size_mask = 0;
181 xp->rotors = num_rotors;
Guido van Rossume6e9fe181992-07-31 15:11:01 +0000182 xp->e_rotor = NULL;
183 xp->d_rotor = NULL;
184 xp->positions = NULL;
185 xp->advances = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000186
Barry Warsawaeb207c1996-12-23 23:36:24 +0000187 if (!(xp->e_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
188 goto finally;
189 if (!(xp->d_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size)))
190 goto finally;
191 if (!(xp->positions = PyMem_NEW(unsigned char, num_rotors)))
192 goto finally;
193 if (!(xp->advances = PyMem_NEW(unsigned char, num_rotors)))
194 goto finally;
195
Guido van Rossum50098201992-07-31 15:10:13 +0000196 return xp;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000197
198 finally:
Guido van Rossumb18618d2000-05-03 23:44:39 +0000199 if (xp->e_rotor)
200 PyMem_DEL(xp->e_rotor);
201 if (xp->d_rotor)
202 PyMem_DEL(xp->d_rotor);
203 if (xp->positions)
204 PyMem_DEL(xp->positions);
205 if (xp->advances)
206 PyMem_DEL(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
Thomas Wouters7e474022000-07-16 12:04:32 +0000212/* These routines implement the rotor itself */
Guido van Rossum50098201992-07-31 15:10:13 +0000213
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
Thomas Wouters7e474022000-07-16 12:04:32 +0000220 The code is smart enough to tell if your alphabet has a number of
Barry Warsawaeb207c1996-12-23 23:36:24 +0000221 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
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000246RTR_make_id_rotor(Rotorobj *r, unsigned char *rtr)
Guido van Rossum50098201992-07-31 15:10:13 +0000247{
248 register int j;
249 register int size = r->size;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000250 for (j = 0; j < size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000251 rtr[j] = (unsigned char)j;
252 }
253}
254
255
Barry Warsaw47d35001997-01-16 16:49:44 +0000256/* The current set of encryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000257static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000258RTR_e_rotors(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000259{
260 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000261 for (i = 0; i < r->rotors; i++) {
262 RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000263 }
264}
265
Barry Warsaw47d35001997-01-16 16:49:44 +0000266/* The current set of decryption rotors */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000267static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000268RTR_d_rotors(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000269{
270 register int i, j;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000271 for (i = 0; i < r->rotors; i++) {
272 for (j = 0; j < r->size; j++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000273 r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
274 }
275 }
276}
277
Barry Warsaw47d35001997-01-16 16:49:44 +0000278/* The positions of the rotors at this time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000279static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000280RTR_positions(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000281{
282 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000283 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000284 r->positions[i] = 1;
285 }
286}
287
Barry Warsaw47d35001997-01-16 16:49:44 +0000288/* The number of positions to advance the rotors at a time */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000289static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000290RTR_advances(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000291{
292 int i;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000293 for (i = 0; i < r->rotors; i++) {
Guido van Rossum50098201992-07-31 15:10:13 +0000294 r->advances[i] = 1;
295 }
296}
297
Barry Warsaw47d35001997-01-16 16:49:44 +0000298/* Permute the E rotor, and make the D rotor its inverse
299 * see Knuth for explanation of algorithm.
300 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000301static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000302RTR_permute_rotor(Rotorobj *r, unsigned char *e, unsigned char *d)
Guido van Rossum50098201992-07-31 15:10:13 +0000303{
304 short i = r->size;
305 short q;
306 unsigned char j;
307 RTR_make_id_rotor(r,e);
308 while (2 <= i) {
309 q = r_rand(r,i);
310 i--;
311 j = e[q];
312 e[q] = (unsigned char)e[i];
313 e[i] = (unsigned char)j;
314 d[j] = (unsigned char)i;
315 }
316 e[0] = (unsigned char)e[0];
317 d[(e[0])] = (unsigned char)0;
318}
319
Barry Warsaw47d35001997-01-16 16:49:44 +0000320/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
321 * Set the advancement, position, and permutation of the rotors
322 */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000323static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000324RTR_init(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000325{
326 int i;
327 set_seed(r);
328 RTR_positions(r);
329 RTR_advances(r);
330 RTR_e_rotors(r);
331 RTR_d_rotors(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000332 for (i = 0; i < r->rotors; i++) {
Tim Petersdc0c0312000-07-10 22:41:30 +0000333 r->positions[i] = (unsigned char) r_rand(r, (short)r->size);
334 r->advances[i] = (1+(2*(r_rand(r, (short)(r->size/2)))));
Barry Warsawaeb207c1996-12-23 23:36:24 +0000335 RTR_permute_rotor(r,
336 &(r->e_rotor[(i*r->size)]),
337 &(r->d_rotor[(i*r->size)]));
Guido van Rossum50098201992-07-31 15:10:13 +0000338 }
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000339 r->isinited = TRUE;
Guido van Rossum50098201992-07-31 15:10:13 +0000340}
341
Barry Warsaw47d35001997-01-16 16:49:44 +0000342/* Change the RTR-positions vector, using the RTR-advances vector */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000343static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000344RTR_advance(Rotorobj *r)
Guido van Rossum50098201992-07-31 15:10:13 +0000345{
346 register int i=0, temp=0;
347 if (r->size_mask) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000348 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000349 temp = r->positions[i] + r->advances[i];
350 r->positions[i] = temp & r->size_mask;
351 if ((temp >= r->size) && (i < (r->rotors - 1))) {
352 r->positions[(i+1)] = 1 + r->positions[(i+1)];
353 }
354 i++;
355 }
356 } else {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000357 while (i < r->rotors) {
Guido van Rossum50098201992-07-31 15:10:13 +0000358 temp = r->positions[i] + r->advances[i];
359 r->positions[i] = temp%r->size;
360 if ((temp >= r->size) && (i < (r->rotors - 1))) {
361 r->positions[(i+1)] = 1 + r->positions[(i+1)];
362 }
363 i++;
364 }
365 }
366}
367
Barry Warsaw47d35001997-01-16 16:49:44 +0000368/* Encrypt the character P with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000369static unsigned char
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000370RTR_e_char(Rotorobj *r, unsigned char p)
Guido van Rossum50098201992-07-31 15:10:13 +0000371{
372 register int i=0;
373 register unsigned char tp=p;
374 if (r->size_mask) {
375 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000376 tp = r->e_rotor[(i*r->size) +
377 (((r->positions[i] ^ tp) &
378 r->size_mask))];
Guido van Rossum50098201992-07-31 15:10:13 +0000379 i++;
380 }
381 } else {
382 while (i < r->rotors) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000383 tp = r->e_rotor[(i*r->size) +
384 (((r->positions[i] ^ tp) %
385 (unsigned int) r->size))];
Guido van Rossum50098201992-07-31 15:10:13 +0000386 i++;
387 }
388 }
389 RTR_advance(r);
390 return ((unsigned char)tp);
391}
392
Barry Warsaw47d35001997-01-16 16:49:44 +0000393/* Decrypt the character C with the current rotor machine */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000394static unsigned char
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000395RTR_d_char(Rotorobj *r, unsigned char c)
Guido van Rossum50098201992-07-31 15:10:13 +0000396{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000397 register int i = r->rotors - 1;
398 register unsigned char tc = c;
399
Guido van Rossum50098201992-07-31 15:10:13 +0000400 if (r->size_mask) {
401 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000402 tc = (r->positions[i] ^
403 r->d_rotor[(i*r->size)+tc]) & r->size_mask;
Guido van Rossum50098201992-07-31 15:10:13 +0000404 i--;
405 }
406 } else {
407 while (0 <= i) {
Barry Warsawaeb207c1996-12-23 23:36:24 +0000408 tc = (r->positions[i] ^
409 r->d_rotor[(i*r->size)+tc]) %
410 (unsigned int) r->size;
Guido van Rossum50098201992-07-31 15:10:13 +0000411 i--;
412 }
413 }
414 RTR_advance(r);
415 return(tc);
416}
417
Barry Warsaw47d35001997-01-16 16:49:44 +0000418/* Perform a rotor encryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000419static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000420RTR_e_region(Rotorobj *r, unsigned char *beg, int len, int doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000421{
422 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000423 if (doinit || r->isinited == FALSE)
424 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000425 for (i = 0; i < len; i++) {
426 beg[i] = RTR_e_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000427 }
428}
429
Barry Warsaw47d35001997-01-16 16:49:44 +0000430/* Perform a rotor decryption of the region from BEG to END by KEY */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000431static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000432RTR_d_region(Rotorobj *r, unsigned char *beg, int len, int doinit)
Guido van Rossum50098201992-07-31 15:10:13 +0000433{
434 register int i;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000435 if (doinit || r->isinited == FALSE)
436 RTR_init(r);
Barry Warsawaeb207c1996-12-23 23:36:24 +0000437 for (i = 0; i < len; i++) {
438 beg[i] = RTR_d_char(r, beg[i]);
Guido van Rossum50098201992-07-31 15:10:13 +0000439 }
440}
441
442
Barry Warsaw47d35001997-01-16 16:49:44 +0000443
Guido van Rossum50098201992-07-31 15:10:13 +0000444/* Rotor methods */
Guido van Rossum50098201992-07-31 15:10:13 +0000445static void
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000446rotor_dealloc(Rotorobj *xp)
Guido van Rossum50098201992-07-31 15:10:13 +0000447{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000448 if (xp->e_rotor)
449 PyMem_DEL(xp->e_rotor);
450 if (xp->d_rotor)
451 PyMem_DEL(xp->d_rotor);
452 if (xp->positions)
453 PyMem_DEL(xp->positions);
454 if (xp->advances)
455 PyMem_DEL(xp->advances);
456 PyObject_Del(xp);
Guido van Rossum50098201992-07-31 15:10:13 +0000457}
458
Guido van Rossumf6971e21994-08-30 12:25:20 +0000459static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000460rotorobj_encrypt(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000461{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000462 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000463 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000464 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000465 char *tmp;
466
Barry Warsawaeb207c1996-12-23 23:36:24 +0000467 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000468 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000469 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000470 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000471 return NULL;
472 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000473 memset(tmp, '\0', len+1);
474 memcpy(tmp, string, len);
475 RTR_e_region(self, (unsigned char *)tmp, len, TRUE);
476 rtn = PyString_FromStringAndSize(tmp, len);
477 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000478 return(rtn);
479}
480
Guido van Rossumf6971e21994-08-30 12:25:20 +0000481static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000482rotorobj_encrypt_more(Rotorobj *self, PyObject *args)
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000483{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000484 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000485 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000486 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000487 char *tmp;
488
Barry Warsawaeb207c1996-12-23 23:36:24 +0000489 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +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 Rossum7b2c03f1992-08-02 09:00:06 +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, FALSE);
498 rtn = PyString_FromStringAndSize(tmp, len);
499 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000500 return(rtn);
501}
502
Guido van Rossumf6971e21994-08-30 12:25:20 +0000503static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000504rotorobj_decrypt(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000505{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000506 char *string = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000507 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000508 PyObject *rtn = NULL;
Guido van Rossum50098201992-07-31 15:10:13 +0000509 char *tmp;
510
Barry Warsawaeb207c1996-12-23 23:36:24 +0000511 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum50098201992-07-31 15:10:13 +0000512 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000513 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000514 PyErr_NoMemory();
Guido van Rossum50098201992-07-31 15:10:13 +0000515 return NULL;
516 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000517 memset(tmp, '\0', len+1);
518 memcpy(tmp, string, len);
519 RTR_d_region(self, (unsigned char *)tmp, len, TRUE);
520 rtn = PyString_FromStringAndSize(tmp, len);
521 PyMem_DEL(tmp);
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000522 return(rtn);
523}
524
Guido van Rossumf6971e21994-08-30 12:25:20 +0000525static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000526rotorobj_decrypt_more(Rotorobj *self, PyObject *args)
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000527{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000528 char *string = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000529 int len = 0;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000530 PyObject *rtn = NULL;
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000531 char *tmp;
532
Barry Warsawaeb207c1996-12-23 23:36:24 +0000533 if (!PyArg_Parse(args, "s#", &string, &len))
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000534 return NULL;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000535 if (!(tmp = PyMem_NEW(char, len+5))) {
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000536 PyErr_NoMemory();
Guido van Rossum7b2c03f1992-08-02 09:00:06 +0000537 return NULL;
538 }
Barry Warsawaeb207c1996-12-23 23:36:24 +0000539 memset(tmp, '\0', len+1);
540 memcpy(tmp, string, len);
541 RTR_d_region(self, (unsigned char *)tmp, len, FALSE);
542 rtn = PyString_FromStringAndSize(tmp, len);
543 PyMem_DEL(tmp);
Guido van Rossum50098201992-07-31 15:10:13 +0000544 return(rtn);
545}
546
Guido van Rossumf6971e21994-08-30 12:25:20 +0000547static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000548rotorobj_setkey(Rotorobj *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000549{
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000550 char *key;
Guido van Rossum50098201992-07-31 15:10:13 +0000551
Guido van Rossum43713e52000-02-29 13:59:29 +0000552 if (!PyArg_ParseTuple(args, "s:setkey", &key))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000553 return NULL;
554
Barry Warsaw9e3fceb1997-01-02 20:36:36 +0000555 set_key(self, key);
Guido van Rossumf6971e21994-08-30 12:25:20 +0000556 Py_INCREF(Py_None);
557 return Py_None;
Guido van Rossum50098201992-07-31 15:10:13 +0000558}
559
Barry Warsawaeb207c1996-12-23 23:36:24 +0000560static struct PyMethodDef
561rotorobj_methods[] = {
562 {"encrypt", (PyCFunction)rotorobj_encrypt},
563 {"encryptmore", (PyCFunction)rotorobj_encrypt_more},
564 {"decrypt", (PyCFunction)rotorobj_decrypt},
565 {"decryptmore", (PyCFunction)rotorobj_decrypt_more},
566 {"setkey", (PyCFunction)rotorobj_setkey, 1},
Guido van Rossum50098201992-07-31 15:10:13 +0000567 {NULL, NULL} /* sentinel */
568};
569
570
571/* Return a rotor object's named attribute. */
Guido van Rossumf6971e21994-08-30 12:25:20 +0000572static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000573rotorobj_getattr(Rotorobj *s, char *name)
Guido van Rossum50098201992-07-31 15:10:13 +0000574{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000575 return Py_FindMethod(rotorobj_methods, (PyObject*)s, name);
Guido van Rossum50098201992-07-31 15:10:13 +0000576}
577
Barry Warsawaeb207c1996-12-23 23:36:24 +0000578
579statichere PyTypeObject Rotor_Type = {
Guido van Rossuma597dde1995-01-10 20:56:29 +0000580 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000581 0, /*ob_size*/
Guido van Rossum50098201992-07-31 15:10:13 +0000582 "rotor", /*tp_name*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000583 sizeof(Rotorobj), /*tp_size*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000584 0, /*tp_itemsize*/
Guido van Rossum50098201992-07-31 15:10:13 +0000585 /* methods */
Barry Warsawaeb207c1996-12-23 23:36:24 +0000586 (destructor)rotor_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000587 0, /*tp_print*/
Barry Warsawaeb207c1996-12-23 23:36:24 +0000588 (getattrfunc)rotorobj_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000589 0, /*tp_setattr*/
590 0, /*tp_compare*/
591 0, /*tp_repr*/
Guido van Rossum7b1e9741994-08-29 10:46:42 +0000592 0, /*tp_hash*/
Guido van Rossum50098201992-07-31 15:10:13 +0000593};
594
595
Guido van Rossumf6971e21994-08-30 12:25:20 +0000596static PyObject *
Peter Schneider-Kamp7d0c71a2000-07-10 13:05:29 +0000597rotor_rotor(PyObject *self, PyObject *args)
Guido van Rossum50098201992-07-31 15:10:13 +0000598{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000599 Rotorobj *r;
Guido van Rossum50098201992-07-31 15:10:13 +0000600 char *string;
Guido van Rossum50098201992-07-31 15:10:13 +0000601 int len;
Barry Warsawaeb207c1996-12-23 23:36:24 +0000602 int num_rotors = 6;
Guido van Rossum50098201992-07-31 15:10:13 +0000603
Guido van Rossum43713e52000-02-29 13:59:29 +0000604 if (!PyArg_ParseTuple(args, "s#|i:newrotor", &string, &len, &num_rotors))
Barry Warsawaeb207c1996-12-23 23:36:24 +0000605 return NULL;
606
607 r = rotorobj_new(num_rotors, string);
608 return (PyObject *)r;
Guido van Rossum50098201992-07-31 15:10:13 +0000609}
610
Barry Warsawaeb207c1996-12-23 23:36:24 +0000611
Barry Warsaw47d35001997-01-16 16:49:44 +0000612
Barry Warsawaeb207c1996-12-23 23:36:24 +0000613static struct PyMethodDef
614rotor_methods[] = {
615 {"newrotor", rotor_rotor, 1},
616 {NULL, NULL} /* sentinel */
Guido van Rossum50098201992-07-31 15:10:13 +0000617};
618
619
Guido van Rossum3886bb61998-12-04 18:50:17 +0000620DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000621initrotor(void)
Guido van Rossum50098201992-07-31 15:10:13 +0000622{
Barry Warsawaeb207c1996-12-23 23:36:24 +0000623 (void)Py_InitModule("rotor", rotor_methods);
Guido van Rossum50098201992-07-31 15:10:13 +0000624}