summaryrefslogtreecommitdiffstats
path: root/Modules/rotormodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/rotormodule.c')
-rw-r--r--Modules/rotormodule.c627
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;
-}