diff options
Diffstat (limited to 'Modules/rotormodule.c')
-rw-r--r-- | Modules/rotormodule.c | 627 |
1 files changed, 0 insertions, 627 deletions
diff --git a/Modules/rotormodule.c b/Modules/rotormodule.c deleted file mode 100644 index 6759244..0000000 --- a/Modules/rotormodule.c +++ /dev/null @@ -1,627 +0,0 @@ -/*********************************************************** -Copyright 1994 by Lance Ellinghouse, -Cathedral City, California Republic, United States of America. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Lance Ellinghouse -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. - -LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, -INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING -FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -******************************************************************/ - -/* This creates an encryption and decryption engine I am calling - a rotor due to the original design was a hardware rotor with - contacts used in Germany during WWII. - -Rotor Module: - -- rotor.newrotor('key') -> rotorobject (default of 6 rotors) -- rotor.newrotor('key', num_rotors) -> rotorobject - -Rotor Objects: - -- ro.setkey('string') -> None (resets the key as defined in newrotor(). -- ro.encrypt('string') -> encrypted string -- ro.decrypt('encrypted string') -> unencrypted string - -- ro.encryptmore('string') -> encrypted string -- ro.decryptmore('encrypted string') -> unencrypted string - -NOTE: the {en,de}cryptmore() methods use the setup that was - established via the {en,de}crypt calls. They will NOT - re-initalize the rotors unless: 1) They have not been - initialized with {en,de}crypt since the last setkey() call; - 2) {en,de}crypt has not been called for this rotor yet. - -NOTE: you MUST use the SAME key in rotor.newrotor() - if you wish to decrypt an encrypted string. - Also, the encrypted string is NOT 0-127 ASCII. - It is considered BINARY data. - -*/ - -/* Rotor objects */ - -#include "Python.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -typedef struct { - PyObject_HEAD - int seed[3]; - short key[5]; - int isinited; - int size; - int size_mask; - int rotors; - unsigned char *e_rotor; /* [num_rotors][size] */ - unsigned char *d_rotor; /* [num_rotors][size] */ - unsigned char *positions; /* [num_rotors] */ - unsigned char *advances; /* [num_rotors] */ -} Rotorobj; - -static PyTypeObject Rotor_Type; - -#define is_rotor(v) ((v)->ob_type == &Rotor_Type) - - -/* This defines the necessary routines to manage rotor objects */ - -static void -set_seed(Rotorobj *r) -{ - r->seed[0] = r->key[0]; - r->seed[1] = r->key[1]; - r->seed[2] = r->key[2]; - r->isinited = FALSE; -} - -/* Return the next random number in the range [0.0 .. 1.0) */ -static double -r_random(Rotorobj *r) -{ - int x, y, z; - double val, term; - - x = r->seed[0]; - y = r->seed[1]; - z = r->seed[2]; - - x = 171 * (x % 177) - 2 * (x/177); - y = 172 * (y % 176) - 35 * (y/176); - z = 170 * (z % 178) - 63 * (z/178); - - if (x < 0) x = x + 30269; - if (y < 0) y = y + 30307; - if (z < 0) z = z + 30323; - - r->seed[0] = x; - r->seed[1] = y; - r->seed[2] = z; - - term = (double)( - (((double)x)/(double)30269.0) + - (((double)y)/(double)30307.0) + - (((double)z)/(double)30323.0) - ); - val = term - (double)floor((double)term); - - if (val >= 1.0) - val = 0.0; - - return val; -} - -static short -r_rand(Rotorobj *r, short s) -{ - return (short)((short)(r_random(r) * (double)s) % s); -} - -static void -set_key(Rotorobj *r, char *key) -{ - unsigned long k1=995, k2=576, k3=767, k4=671, k5=463; - size_t i; - size_t len = strlen(key); - - for (i = 0; i < len; i++) { - unsigned short ki = Py_CHARMASK(key[i]); - - k1 = (((k1<<3 | k1>>13) + ki) & 65535); - k2 = (((k2<<3 | k2>>13) ^ ki) & 65535); - k3 = (((k3<<3 | k3>>13) - ki) & 65535); - k4 = ((ki - (k4<<3 | k4>>13)) & 65535); - k5 = (((k5<<3 | k5>>13) ^ ~ki) & 65535); - } - r->key[0] = (short)k1; - r->key[1] = (short)(k2|1); - r->key[2] = (short)k3; - r->key[3] = (short)k4; - r->key[4] = (short)k5; - - set_seed(r); -} - - - -/* These define the interface to a rotor object */ -static Rotorobj * -rotorobj_new(int num_rotors, char *key) -{ - Rotorobj *xp; - - xp = PyObject_New(Rotorobj, &Rotor_Type); - if (xp == NULL) - return NULL; - set_key(xp, key); - - xp->size = 256; - xp->size_mask = xp->size - 1; - xp->size_mask = 0; - xp->rotors = num_rotors; - xp->e_rotor = NULL; - xp->d_rotor = NULL; - xp->positions = NULL; - xp->advances = NULL; - - if (!(xp->e_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size))) - goto finally; - if (!(xp->d_rotor = PyMem_NEW(unsigned char, num_rotors * xp->size))) - goto finally; - if (!(xp->positions = PyMem_NEW(unsigned char, num_rotors))) - goto finally; - if (!(xp->advances = PyMem_NEW(unsigned char, num_rotors))) - goto finally; - - return xp; - - finally: - if (xp->e_rotor) - PyMem_DEL(xp->e_rotor); - if (xp->d_rotor) - PyMem_DEL(xp->d_rotor); - if (xp->positions) - PyMem_DEL(xp->positions); - if (xp->advances) - PyMem_DEL(xp->advances); - Py_DECREF(xp); - return (Rotorobj*)PyErr_NoMemory(); -} - - -/* These routines implement the rotor itself */ - -/* Here is a fairly sophisticated {en,de}cryption system. It is based on - the idea of a "rotor" machine. A bunch of rotors, each with a - different permutation of the alphabet, rotate around a different amount - after encrypting one character. The current state of the rotors is - used to encrypt one character. - - The code is smart enough to tell if your alphabet has a number of - characters equal to a power of two. If it does, it uses logical - operations, if not it uses div and mod (both require a division). - - You will need to make two changes to the code 1) convert to c, and - customize for an alphabet of 255 chars 2) add a filter at the begining, - and end, which subtracts one on the way in, and adds one on the way - out. - - You might wish to do some timing studies. Another viable alternative - is to "byte stuff" the encrypted data of a normal (perhaps this one) - encryption routine. - - j' - - */ - -/* Note: the C code here is a fairly straightforward transliteration of a - * rotor implemented in lisp. The original lisp code has been removed from - * this file to for simplification, but I've kept the docstrings as - * comments in front of the functions. - */ - - -/* Set ROTOR to the identity permutation */ -static void -RTR_make_id_rotor(Rotorobj *r, unsigned char *rtr) -{ - register int j; - register int size = r->size; - for (j = 0; j < size; j++) { - rtr[j] = (unsigned char)j; - } -} - - -/* The current set of encryption rotors */ -static void -RTR_e_rotors(Rotorobj *r) -{ - int i; - for (i = 0; i < r->rotors; i++) { - RTR_make_id_rotor(r, &(r->e_rotor[(i*r->size)])); - } -} - -/* The current set of decryption rotors */ -static void -RTR_d_rotors(Rotorobj *r) -{ - register int i, j; - for (i = 0; i < r->rotors; i++) { - for (j = 0; j < r->size; j++) { - r->d_rotor[((i*r->size)+j)] = (unsigned char)j; - } - } -} - -/* The positions of the rotors at this time */ -static void -RTR_positions(Rotorobj *r) -{ - int i; - for (i = 0; i < r->rotors; i++) { - r->positions[i] = 1; - } -} - -/* The number of positions to advance the rotors at a time */ -static void -RTR_advances(Rotorobj *r) -{ - int i; - for (i = 0; i < r->rotors; i++) { - r->advances[i] = 1; - } -} - -/* Permute the E rotor, and make the D rotor its inverse - * see Knuth for explanation of algorithm. - */ -static void -RTR_permute_rotor(Rotorobj *r, unsigned char *e, unsigned char *d) -{ - short i = r->size; - short q; - unsigned char j; - RTR_make_id_rotor(r,e); - while (2 <= i) { - q = r_rand(r,i); - i--; - j = e[q]; - e[q] = (unsigned char)e[i]; - e[i] = (unsigned char)j; - d[j] = (unsigned char)i; - } - e[0] = (unsigned char)e[0]; - d[(e[0])] = (unsigned char)0; -} - -/* Given KEY (a list of 5 16 bit numbers), initialize the rotor machine. - * Set the advancement, position, and permutation of the rotors - */ -static void -RTR_init(Rotorobj *r) -{ - int i; - set_seed(r); - RTR_positions(r); - RTR_advances(r); - RTR_e_rotors(r); - RTR_d_rotors(r); - for (i = 0; i < r->rotors; i++) { - r->positions[i] = (unsigned char) r_rand(r, (short)r->size); - r->advances[i] = (1+(2*(r_rand(r, (short)(r->size/2))))); - RTR_permute_rotor(r, - &(r->e_rotor[(i*r->size)]), - &(r->d_rotor[(i*r->size)])); - } - r->isinited = TRUE; -} - -/* Change the RTR-positions vector, using the RTR-advances vector */ -static void -RTR_advance(Rotorobj *r) -{ - register int i=0, temp=0; - if (r->size_mask) { - while (i < r->rotors) { - temp = r->positions[i] + r->advances[i]; - r->positions[i] = temp & r->size_mask; - if ((temp >= r->size) && (i < (r->rotors - 1))) { - r->positions[(i+1)] = 1 + r->positions[(i+1)]; - } - i++; - } - } else { - while (i < r->rotors) { - temp = r->positions[i] + r->advances[i]; - r->positions[i] = temp%r->size; - if ((temp >= r->size) && (i < (r->rotors - 1))) { - r->positions[(i+1)] = 1 + r->positions[(i+1)]; - } - i++; - } - } -} - -/* Encrypt the character P with the current rotor machine */ -static unsigned char -RTR_e_char(Rotorobj *r, unsigned char p) -{ - register int i=0; - register unsigned char tp=p; - if (r->size_mask) { - while (i < r->rotors) { - tp = r->e_rotor[(i*r->size) + - (((r->positions[i] ^ tp) & - r->size_mask))]; - i++; - } - } else { - while (i < r->rotors) { - tp = r->e_rotor[(i*r->size) + - (((r->positions[i] ^ tp) % - (unsigned int) r->size))]; - i++; - } - } - RTR_advance(r); - return ((unsigned char)tp); -} - -/* Decrypt the character C with the current rotor machine */ -static unsigned char -RTR_d_char(Rotorobj *r, unsigned char c) -{ - register int i = r->rotors - 1; - register unsigned char tc = c; - - if (r->size_mask) { - while (0 <= i) { - tc = (r->positions[i] ^ - r->d_rotor[(i*r->size)+tc]) & r->size_mask; - i--; - } - } else { - while (0 <= i) { - tc = (r->positions[i] ^ - r->d_rotor[(i*r->size)+tc]) % - (unsigned int) r->size; - i--; - } - } - RTR_advance(r); - return(tc); -} - -/* Perform a rotor encryption of the region from BEG to END by KEY */ -static void -RTR_e_region(Rotorobj *r, unsigned char *beg, int len, int doinit) -{ - register int i; - if (doinit || r->isinited == FALSE) - RTR_init(r); - for (i = 0; i < len; i++) { - beg[i] = RTR_e_char(r, beg[i]); - } -} - -/* Perform a rotor decryption of the region from BEG to END by KEY */ -static void -RTR_d_region(Rotorobj *r, unsigned char *beg, int len, int doinit) -{ - register int i; - if (doinit || r->isinited == FALSE) - RTR_init(r); - for (i = 0; i < len; i++) { - beg[i] = RTR_d_char(r, beg[i]); - } -} - - - -/* Rotor methods */ -static void -rotor_dealloc(Rotorobj *xp) -{ - if (xp->e_rotor) - PyMem_DEL(xp->e_rotor); - if (xp->d_rotor) - PyMem_DEL(xp->d_rotor); - if (xp->positions) - PyMem_DEL(xp->positions); - if (xp->advances) - PyMem_DEL(xp->advances); - PyObject_Del(xp); -} - -static PyObject * -rotorobj_encrypt(Rotorobj *self, PyObject *args) -{ - char *string = NULL; - int len = 0; - PyObject *rtn = NULL; - char *tmp; - - if (!PyArg_ParseTuple(args, "s#:encrypt", &string, &len)) - return NULL; - if (!(tmp = PyMem_NEW(char, len+5))) { - PyErr_NoMemory(); - return NULL; - } - memset(tmp, '\0', len+1); - memcpy(tmp, string, len); - RTR_e_region(self, (unsigned char *)tmp, len, TRUE); - rtn = PyString_FromStringAndSize(tmp, len); - PyMem_DEL(tmp); - return(rtn); -} - -static PyObject * -rotorobj_encrypt_more(Rotorobj *self, PyObject *args) -{ - char *string = NULL; - int len = 0; - PyObject *rtn = NULL; - char *tmp; - - if (!PyArg_ParseTuple(args, "s#:encrypt_more", &string, &len)) - return NULL; - if (!(tmp = PyMem_NEW(char, len+5))) { - PyErr_NoMemory(); - return NULL; - } - memset(tmp, '\0', len+1); - memcpy(tmp, string, len); - RTR_e_region(self, (unsigned char *)tmp, len, FALSE); - rtn = PyString_FromStringAndSize(tmp, len); - PyMem_DEL(tmp); - return(rtn); -} - -static PyObject * -rotorobj_decrypt(Rotorobj *self, PyObject *args) -{ - char *string = NULL; - int len = 0; - PyObject *rtn = NULL; - char *tmp; - - if (!PyArg_ParseTuple(args, "s#:decrypt", &string, &len)) - return NULL; - if (!(tmp = PyMem_NEW(char, len+5))) { - PyErr_NoMemory(); - return NULL; - } - memset(tmp, '\0', len+1); - memcpy(tmp, string, len); - RTR_d_region(self, (unsigned char *)tmp, len, TRUE); - rtn = PyString_FromStringAndSize(tmp, len); - PyMem_DEL(tmp); - return(rtn); -} - -static PyObject * -rotorobj_decrypt_more(Rotorobj *self, PyObject *args) -{ - char *string = NULL; - int len = 0; - PyObject *rtn = NULL; - char *tmp; - - if (!PyArg_ParseTuple(args, "s#:decrypt_more", &string, &len)) - return NULL; - if (!(tmp = PyMem_NEW(char, len+5))) { - PyErr_NoMemory(); - return NULL; - } - memset(tmp, '\0', len+1); - memcpy(tmp, string, len); - RTR_d_region(self, (unsigned char *)tmp, len, FALSE); - rtn = PyString_FromStringAndSize(tmp, len); - PyMem_DEL(tmp); - return(rtn); -} - -static PyObject * -rotorobj_setkey(Rotorobj *self, PyObject *args) -{ - char *key; - - if (!PyArg_ParseTuple(args, "s:setkey", &key)) - return NULL; - - set_key(self, key); - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef -rotorobj_methods[] = { - {"encrypt", (PyCFunction)rotorobj_encrypt, METH_VARARGS}, - {"encryptmore", (PyCFunction)rotorobj_encrypt_more, METH_VARARGS}, - {"decrypt", (PyCFunction)rotorobj_decrypt, METH_VARARGS}, - {"decryptmore", (PyCFunction)rotorobj_decrypt_more, METH_VARARGS}, - {"setkey", (PyCFunction)rotorobj_setkey, METH_VARARGS}, - {NULL, NULL} /* sentinel */ -}; - - -/* Return a rotor object's named attribute. */ -static PyObject * -rotorobj_getattr(Rotorobj *s, char *name) -{ - return Py_FindMethod(rotorobj_methods, (PyObject*)s, name); -} - - -static PyTypeObject Rotor_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "rotor.rotor", /*tp_name*/ - sizeof(Rotorobj), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)rotor_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)rotorobj_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_hash*/ -}; - - -static PyObject * -rotor_rotor(PyObject *self, PyObject *args) -{ - Rotorobj *r; - char *string; - int num_rotors = 6; - - if (!PyArg_ParseTuple(args, "s|i:newrotor", &string, &num_rotors)) - return NULL; - - r = rotorobj_new(num_rotors, string); - return (PyObject *)r; -} - - - -static struct PyMethodDef -rotor_methods[] = { - {"newrotor", rotor_rotor, METH_VARARGS}, - {NULL, NULL} /* sentinel */ -}; - - -PyMODINIT_FUNC -initrotor(void) -{ - Rotor_Type.ob_type = &PyType_Type; - (void)Py_InitModule("rotor", rotor_methods); - if (PyErr_Warn(PyExc_DeprecationWarning, - "the rotor module uses an insecure algorithm " - "and is deprecated") < 0) - return; -} |