remove PyCrypto, now we only use pycrypto++

This commit is contained in:
Brian Warner 2007-12-03 18:10:01 -07:00
parent 0bf5a762a9
commit 955bd5383d
14 changed files with 2 additions and 3575 deletions

View File

@ -118,10 +118,5 @@ setup(name='allmydata-tahoe',
setup_requires=["setuptools_darcs >= 1.0.5",],
dependency_links=dependency_links,
entry_points = { 'console_scripts': [ 'tahoe = allmydata.scripts.runner:run' ] },
ext_modules=[
Extension("allmydata.Crypto.Cipher.AES",
include_dirs=["src/allmydata/Crypto"],
sources=["src/allmydata/Crypto/AES.c"]),
],
zip_safe=False, # We prefer unzipped for easier access.
)

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
This directory contains pieces of the PyCrypto package. We've copied just the
parts we need (AES with zooko's fast-CTR-mode patch, Util.number) into the tahoe tree.
PyCrypto is published with the following license:
===================================================================
Distribute and use freely; there are no restrictions on further
dissemination and usage except those imposed by the laws of your
country of residence. This software is provided "as is" without
warranty of fitness for use or suitability for any purpose, express
or implied. Use at your own risk or not at all.
===================================================================
Incorporating the code into commercial products is permitted; you do
not have to make source available or contribute your changes back
(though that would be nice).
--amk (www.amk.ca)

View File

@ -1,76 +0,0 @@
Python Cryptography Toolkit (pycrypto)
======================================
This is a collection of both secure hash functions (such as MD5 and SHA),
and various encryption algorithms (AES, DES, IDEA, RSA, ElGamal, etc.). The
package is structured to make adding new modules easy. I consider this
section to be essentially complete, and the software interface will almost
certainly not change in an incompatible way in the future; all that remains
to be done is to fix any bugs that show up. If you encounter a bug, please
report it in the SourceForge bug tracker at
https://sourceforge.net/tracker/?group_id=20937&atid=120937
An example usage of the MD5 module is:
>>> from Crypto.Hash import MD5
>>> hash=MD5.new()
>>> hash.update('message')
>>> hash.digest()
'x\xe71\x02}\x8f\xd5\x0e\xd6B4\x0b|\x9ac\xb3'
An example usage of an encryption algorithm (AES, in this case) is:
>>> from Crypto.Cipher import AES
>>> obj=AES.new('This is a key456', AES.MODE_ECB)
>>> message="The answer is no"
>>> ciphertext=obj.encrypt(message)
>>> ciphertext
'o\x1aq_{P+\xd0\x07\xce\x89\xd1=M\x989'
>>> obj2 = AES.new('This is a key456', AES.MODE_ECB)
>>> obj2.decrypt(ciphertext)
'The answer is no'
One possible application of the modules is writing secure
administration tools. Another application is in writing daemons and
servers. Clients and servers can encrypt the data being exchanged and
mutually authenticate themselves; daemons can encrypt private data for
added security. Python also provides a pleasant framework for
prototyping and experimentation with cryptographic algorithms; thanks
to its arbitrary-length integers, public key algorithms are easily
implemented.
Development of the toolkit can be discussed on the pct mailing list;
archives and instructions for subscribing at at
<URL:http://www.amk.ca/mailman/listinfo/pct>.
Installation
============
The toolkit is written and tested using Python 2.2, though it should
also work with Python 2.1. Python 1.5.2 is not supported, and the
setup.py script will abort if you run it with 1.5.2.
The modules are packaged using the Distutils, so you can simply run
"python setup.py build" to build the package, and "python setup.py
install" to install it.
If the setup.py script crashes with a DistutilsPlatformError
complaining that the file /usr/lib/python2.2/config/Makefile doesn't
exist, this means that the files needed for compiling new Python
modules aren't installed on your system. Red Hat users often run into
this because they don't have the python2-devel RPM installed. The fix
is to simply install the requisite RPM.
To verify that everything is in order, run "python test.py". It will test
all the cryptographic modules, skipping ones that aren't available. If the
test script reports an error on your machine, please report the bug using
the bug tracker (URL given above). If possible, track down the bug and
include a patch that fixes it.
To install the package under the site-packages directory of
your Python installation, run "python setup.py install".
If you have any comments, corrections, or improvements for this package,
please send it to the 'pct' mailing list. Good luck!
--amk (www.amk.ca)

View File

@ -1,202 +0,0 @@
#
# number.py : Number-theoretic functions
#
# Part of the Python Cryptography Toolkit
#
# Distribute and use freely; there are no restrictions on further
# dissemination and usage except those imposed by the laws of your
# country of residence. This software is provided "as is" without
# warranty of fitness for use or suitability for any purpose, express
# or implied. Use at your own risk or not at all.
#
__revision__ = "$Id: number.py,v 1.13 2003/04/04 18:21:07 akuchling Exp $"
bignum = long
_fastmath = None
try:
from allmydata.Crypto.PublicKey import _fastmath
except ImportError:
pass
# Commented out and replaced with faster versions below
## def long2str(n):
## s=''
## while n>0:
## s=chr(n & 255)+s
## n=n>>8
## return s
## import types
## def str2long(s):
## if type(s)!=types.StringType: return s # Integers will be left alone
## return reduce(lambda x,y : x*256+ord(y), s, 0L)
def size (N):
"""size(N:long) : int
Returns the size of the number N in bits.
"""
bits, power = 0,1L
while N >= power:
bits += 1
power = power << 1
return bits
def getRandomNumber(N, randfunc):
"""getRandomNumber(N:int, randfunc:callable):long
Return an N-bit random number."""
S = randfunc(N/8)
odd_bits = N % 8
if odd_bits != 0:
char = ord(randfunc(1)) >> (8-odd_bits)
S = chr(char) + S
value = bytes_to_long(S)
value |= 2L ** (N-1) # Ensure high bit is set
assert size(value) >= N
return value
def GCD(x,y):
"""GCD(x:long, y:long): long
Return the GCD of x and y.
"""
x = abs(x) ; y = abs(y)
while x > 0:
x, y = y % x, x
return y
def inverse(u, v):
"""inverse(u:long, u:long):long
Return the inverse of u mod v.
"""
u3, v3 = long(u), long(v)
u1, v1 = 1L, 0L
while v3 > 0:
q=u3 / v3
u1, v1 = v1, u1 - v1*q
u3, v3 = v3, u3 - v3*q
while u1<0:
u1 = u1 + v
return u1
# Given a number of bits to generate and a random generation function,
# find a prime number of the appropriate size.
def getPrime(N, randfunc):
"""getPrime(N:int, randfunc:callable):long
Return a random N-bit prime number.
"""
number=getRandomNumber(N, randfunc) | 1
while (not isPrime(number)):
number=number+2
return number
def isPrime(N):
"""isPrime(N:long):bool
Return true if N is prime.
"""
if N == 1:
return 0
if N in sieve:
return 1
for i in sieve:
if (N % i)==0:
return 0
# Use the accelerator if available
if _fastmath is not None:
return _fastmath.isPrime(N)
# Compute the highest bit that's set in N
N1 = N - 1L
n = 1L
while (n<N):
n=n<<1L
n = n >> 1L
# Rabin-Miller test
for c in sieve[:7]:
a=long(c) ; d=1L ; t=n
while (t): # Iterate over the bits in N1
x=(d*d) % N
if x==1L and d!=1L and d!=N1:
return 0 # Square root of 1 found
if N1 & t:
d=(x*a) % N
else:
d=x
t = t >> 1L
if d!=1L:
return 0
return 1
# Small primes used for checking primality; these are all the primes
# less than 256. This should be enough to eliminate most of the odd
# numbers before needing to do a Rabin-Miller test at all.
sieve=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
197, 199, 211, 223, 227, 229, 233, 239, 241, 251]
# Improved conversion functions contributed by Barry Warsaw, after
# careful benchmarking
import struct
def long_to_bytes(n, blocksize=0):
"""long_to_bytes(n:long, blocksize:int) : string
Convert a long integer to a byte string.
If optional blocksize is given and greater than zero, pad the front of the
byte string with binary zeros so that the length is a multiple of
blocksize.
"""
# after much testing, this algorithm was deemed to be the fastest
s = ''
n = long(n)
pack = struct.pack
while n > 0:
s = pack('>I', n & 0xffffffffL) + s
n = n >> 32
# strip off leading zeros
for i in range(len(s)):
if s[i] != '\000':
break
else:
# only happens when n == 0
s = '\000'
i = 0
s = s[i:]
# add back some pad bytes. this could be done more efficiently w.r.t. the
# de-padding being done above, but sigh...
if blocksize > 0 and len(s) % blocksize:
s = (blocksize - len(s) % blocksize) * '\000' + s
return s
def bytes_to_long(s):
"""bytes_to_long(string) : long
Convert a byte string to a long integer.
This is (essentially) the inverse of long_to_bytes().
"""
acc = 0L
unpack = struct.unpack
length = len(s)
if length % 4:
extra = (4 - length % 4)
s = '\000' * extra + s
length = length + extra
for i in range(0, length, 4):
acc = (acc << 32) + unpack('>I', s[i:i+4])[0]
return acc
# For backwards compatibility...
import warnings
def long2str(n, blocksize=0):
warnings.warn("long2str() has been replaced by long_to_bytes()")
return long_to_bytes(n, blocksize)
def str2long(s):
warnings.warn("str2long() has been replaced by bytes_to_long()")
return bytes_to_long(s)

View File

@ -1,4 +0,0 @@
#! /usr/bin/python
# we also need to provide bytes_to_long, normally from
# allmydata.Crypto.Util.number.bytes_to_long

View File

@ -1,804 +0,0 @@
/*
* _fastmath.c: Accelerator module that uses GMP for faster numerics.
*
* Part of the Python Cryptography Toolkit
*
* Distribute and use freely; there are no restrictions on further
* dissemination and usage except those imposed by the laws of your
* country of residence.
*
* $Id: _fastmath.c,v 1.13 2003/04/04 19:20:29 jbontje Exp $
*/
#include <stdio.h>
#include <string.h>
#include <Python.h>
#include <longintrepr.h> /* for conversions */
#include <gmp.h>
void
longObjToMPZ (mpz_t m, PyLongObject * p)
{
int size, i;
mpz_t temp, temp2;
mpz_init (temp);
mpz_init (temp2);
if (p->ob_size > 0)
size = p->ob_size;
else
size = -p->ob_size;
for (i = 0; i < size; i++)
{
mpz_set_ui (temp, p->ob_digit[i]);
mpz_mul_2exp (temp2, temp, SHIFT * i);
mpz_add (m, m, temp2);
}
mpz_clear (temp);
mpz_clear (temp2);
}
PyObject *
mpzToLongObj (mpz_t m)
{
/* borrowed from gmpy */
int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT;
int i;
mpz_t temp;
PyLongObject *l = _PyLong_New (size);
if (!l)
return NULL;
mpz_init_set (temp, m);
for (i = 0; i < size; i++)
{
l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK);
mpz_fdiv_q_2exp (temp, temp, SHIFT);
}
i = size;
while ((i > 0) && (l->ob_digit[i - 1] == 0))
i--;
l->ob_size = i;
mpz_clear (temp);
return (PyObject *) l;
}
typedef struct
{
PyObject_HEAD mpz_t y;
mpz_t g;
mpz_t p;
mpz_t q;
mpz_t x;
}
dsaKey;
typedef struct
{
PyObject_HEAD mpz_t n;
mpz_t e;
mpz_t d;
mpz_t p;
mpz_t q;
mpz_t u;
}
rsaKey;
PyObject *rsaKey_new (PyObject *, PyObject *);
PyObject *dsaKey_new (PyObject *, PyObject *);
static void dsaKey_dealloc (dsaKey *);
static PyObject *dsaKey_getattr (dsaKey *, char *);
static PyObject *dsaKey__sign (dsaKey *, PyObject *);
static PyObject *dsaKey__verify (dsaKey *, PyObject *);
static PyObject *dsaKey_size (dsaKey *, PyObject *);
static PyObject *dsaKey_has_private (dsaKey *, PyObject *);
static void rsaKey_dealloc (rsaKey *);
static PyObject *rsaKey_getattr (rsaKey *, char *);
static PyObject *rsaKey__encrypt (rsaKey *, PyObject *);
static PyObject *rsaKey__decrypt (rsaKey *, PyObject *);
static PyObject *rsaKey__verify (rsaKey *, PyObject *);
static PyObject *rsaKey__blind (rsaKey *, PyObject *);
static PyObject *rsaKey__unblind (rsaKey *, PyObject *);
static PyObject *rsaKey_size (rsaKey *, PyObject *);
static PyObject *rsaKey_has_private (rsaKey *, PyObject *);
static int
dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t r, mpz_t s)
{
mpz_t temp;
if (mpz_cmp_ui (k, 2) < 0 || mpz_cmp (k, key->q) >= 0)
{
return 1;
}
mpz_init (temp);
mpz_powm (r, key->g, k, key->p);
mpz_mod (r, r, key->q);
mpz_invert (s, k, key->q);
mpz_mul (temp, key->x, r);
mpz_add (temp, m, temp);
mpz_mul (s, s, temp);
mpz_mod (s, s, key->q);
mpz_clear (temp);
return 0;
}
static int
dsaVerify (dsaKey * key, mpz_t m, mpz_t r, mpz_t s)
{
int result;
mpz_t u1, u2, v1, v2, w;
if (mpz_cmp_ui (r, 0) <= 0 || mpz_cmp (r, key->q) >= 0 ||
mpz_cmp_ui (s, 0) <= 0 || mpz_cmp (s, key->q) >= 0)
return 0;
mpz_init (u1);
mpz_init (u2);
mpz_init (v1);
mpz_init (v2);
mpz_init (w);
mpz_invert (w, s, key->q);
mpz_mul (u1, m, w);
mpz_mod (u1, u1, key->q);
mpz_mul (u2, r, w);
mpz_mod (u2, u2, key->q);
mpz_powm (v1, key->g, u1, key->p);
mpz_powm (v2, key->y, u2, key->p);
mpz_mul (w, v1, v2);
mpz_mod (w, w, key->p);
mpz_mod (w, w, key->q);
if (mpz_cmp (r, w) == 0)
result = 1;
else
result = 0;
mpz_clear (u1);
mpz_clear (u2);
mpz_clear (v1);
mpz_clear (v2);
mpz_clear (w);
return result;
}
static int
rsaEncrypt (rsaKey * key, mpz_t v)
{
if (mpz_cmp (v, key->n) >= 0)
{
return 1;
}
mpz_powm (v, v, key->e, key->n);
return 0;
}
static int
rsaDecrypt (rsaKey * key, mpz_t v)
{
mpz_t m1, m2, h;
if (mpz_cmp (v, key->n) >= 0)
{
return 1;
}
if (mpz_size (key->d) == 0)
{
return 2;
}
if ((mpz_size (key->p) != 0) && (mpz_size (key->q) != 0) &&
(mpz_size (key->u) != 0))
{
/* fast path */
mpz_init(m1);
mpz_init(m2);
mpz_init(h);
/* m1 = c ^ (d mod (p-1)) mod p */
mpz_sub_ui(h, key->p, 1);
mpz_fdiv_r(h, key->d, h);
mpz_powm(m1, v, h, key->p);
/* m2 = c ^ (d mod (q-1)) mod q */
mpz_sub_ui(h, key->q, 1);
mpz_fdiv_r(h, key->d, h);
mpz_powm(m2, v, h, key->q);
/* h = u * ( m2 - m1 ) mod q */
mpz_sub(h, m2, m1);
if (mpz_sgn(h)==-1)
mpz_add(h, h, key->q);
mpz_mul(h, key->u, h);
mpz_mod(h, h, key->q);
/* m = m2 + h * p */
mpz_mul(h, h, key->p);
mpz_add(v, m1, h);
/* ready */
mpz_clear(m1);
mpz_clear(m2);
mpz_clear(h);
return 0;
}
/* slow */
mpz_powm (v, v, key->d, key->n);
return 0;
}
static int
rsaBlind (rsaKey * key, mpz_t v, mpz_t b)
{
if (mpz_cmp (v, key->n) >= 0)
{
return 1;
}
if (mpz_cmp (b, key->n) >= 0)
{
return 2;
}
mpz_powm (b, b, key->e, key->n);
mpz_mul (v, v, b);
mpz_mod (v, v, key->n);
return 0;
}
static int
rsaUnBlind (rsaKey * key, mpz_t v, mpz_t b)
{
if (mpz_cmp (v, key->n) >= 0)
{
return 1;
}
if (mpz_cmp (b, key->n) >= 0)
{
return 2;
}
if (!mpz_invert (b, b, key->n))
{
return 3;
}
mpz_mul (v, v, b);
mpz_mod (v, v, key->n);
return 0;
}
static PyTypeObject dsaKeyType = {
PyObject_HEAD_INIT (NULL) 0,
"dsaKey",
sizeof (dsaKey),
0,
(destructor) dsaKey_dealloc, /* dealloc */
0, /* print */
(getattrfunc) dsaKey_getattr, /* getattr */
0, /* setattr */
0, /* compare */
0, /* repr */
0, /* as_number */
0, /* as_sequence */
0, /* as_mapping */
0, /* hash */
0, /* call */
};
static PyMethodDef dsaKey__methods__[] = {
{"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS,
"Sign the given long."},
{"_verify", (PyCFunction) dsaKey__verify, METH_VARARGS,
"Verify that the signature is valid."},
{"size", (PyCFunction) dsaKey_size, METH_VARARGS,
"Return the number of bits that this key can handle."},
{"has_private", (PyCFunction) dsaKey_has_private, METH_VARARGS,
"Return 1 or 0 if this key does/doesn't have a private key."},
{NULL, NULL, 0, NULL}
};
PyObject *fastmathError; /* raised on errors */
static PyTypeObject rsaKeyType = {
PyObject_HEAD_INIT (NULL) 0,
"rsaKey",
sizeof (rsaKey),
0,
(destructor) rsaKey_dealloc, /* dealloc */
0, /* print */
(getattrfunc) rsaKey_getattr, /* getattr */
0, /* setattr */
0, /* compare */
0, /* repr */
0, /* as_number */
0, /* as_sequence */
0, /* as_mapping */
0, /* hash */
0, /* call */
};
static PyMethodDef rsaKey__methods__[] = {
{"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS,
"Encrypt the given long."},
{"_decrypt", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
"Decrypt the given long."},
{"_sign", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
"Sign the given long."},
{"_verify", (PyCFunction) rsaKey__verify, METH_VARARGS,
"Verify that the signature is valid."},
{"_blind", (PyCFunction) rsaKey__blind, METH_VARARGS,
"Blind the given long."},
{"_unblind", (PyCFunction) rsaKey__unblind, METH_VARARGS,
"Unblind the given long."},
{"size", (PyCFunction) rsaKey_size, METH_VARARGS,
"Return the number of bits that this key can handle."},
{"has_private", (PyCFunction) rsaKey_has_private, METH_VARARGS,
"Return 1 or 0 if this key does/doesn't have a private key."},
{NULL, NULL, 0, NULL}
};
PyObject *
dsaKey_new (PyObject * self, PyObject * args)
{
PyLongObject *y = NULL, *g = NULL, *p = NULL, *q = NULL, *x = NULL;
dsaKey *key;
if (!PyArg_ParseTuple(args, "O!O!O!O!|O!", &PyLong_Type, &y,
&PyLong_Type, &g, &PyLong_Type, &p,
&PyLong_Type, &q, &PyLong_Type, &x))
return NULL;
key = PyObject_New (dsaKey, &dsaKeyType);
mpz_init (key->y);
mpz_init (key->g);
mpz_init (key->p);
mpz_init (key->q);
mpz_init (key->x);
longObjToMPZ (key->y, y);
longObjToMPZ (key->g, g);
longObjToMPZ (key->p, p);
longObjToMPZ (key->q, q);
if (x)
{
longObjToMPZ (key->x, x);
}
return (PyObject *) key;
}
static void
dsaKey_dealloc (dsaKey * key)
{
mpz_clear (key->y);
mpz_clear (key->g);
mpz_clear (key->p);
mpz_clear (key->q);
mpz_clear (key->x);
PyObject_Del (key);
}
static PyObject *
dsaKey_getattr (dsaKey * key, char *attr)
{
if (strcmp (attr, "y") == 0)
return mpzToLongObj (key->y);
else if (strcmp (attr, "g") == 0)
return mpzToLongObj (key->g);
else if (strcmp (attr, "p") == 0)
return mpzToLongObj (key->p);
else if (strcmp (attr, "q") == 0)
return mpzToLongObj (key->q);
else if (strcmp (attr, "x") == 0)
{
if (mpz_size (key->x) == 0)
{
PyErr_SetString (PyExc_AttributeError,
"dsaKey instance has no attribute 'x'");
return NULL;
}
return mpzToLongObj (key->x);
}
else
{
return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr);
}
}
PyObject *
dsaKey__sign (dsaKey * key, PyObject * args)
{
PyObject *lm, *lk, *lr, *ls;
mpz_t m, k, r, s;
int result;
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm,
&PyLong_Type, &lk))
{
return NULL;
}
mpz_init (m);
mpz_init (k);
mpz_init (r);
mpz_init (s);
longObjToMPZ (m, (PyLongObject *) lm);
longObjToMPZ (k, (PyLongObject *) lk);
result = dsaSign (key, m, k, r, s);
if (result == 1)
{
PyErr_SetString (fastmathError, "K not between 2 and q");
return NULL;
}
lr = mpzToLongObj (r);
ls = mpzToLongObj (s);
mpz_clear (m);
mpz_clear (k);
mpz_clear (r);
mpz_clear (s);
return Py_BuildValue ("(NN)", lr, ls);
}
PyObject *
dsaKey__verify (dsaKey * key, PyObject * args)
{
PyObject *lm, *lr, *ls;
mpz_t m, r, s;
int result;
if (!PyArg_ParseTuple (args, "O!O!O!", &PyLong_Type, &lm,
&PyLong_Type, &lr, &PyLong_Type, &ls))
{
return NULL;
}
mpz_init (m);
mpz_init (r);
mpz_init (s);
longObjToMPZ (m, (PyLongObject *) lm);
longObjToMPZ (r, (PyLongObject *) lr);
longObjToMPZ (s, (PyLongObject *) ls);
result = dsaVerify (key, m, r, s);
mpz_clear (m);
mpz_clear (r);
mpz_clear (s);
if (result) {
Py_INCREF(Py_True);
return Py_True;
} else {
Py_INCREF(Py_False);
return Py_False;
}
}
PyObject *
dsaKey_size (dsaKey * key, PyObject * args)
{
if (!PyArg_ParseTuple (args, ""))
return NULL;
return Py_BuildValue ("i", mpz_sizeinbase (key->p, 2) - 1);
}
PyObject *
dsaKey_has_private (dsaKey * key, PyObject * args)
{
if (!PyArg_ParseTuple (args, ""))
return NULL;
if (mpz_size (key->x) == 0) {
Py_INCREF(Py_False);
return Py_False;
} else {
Py_INCREF(Py_True);
return Py_True;
}
}
PyObject *
rsaKey_new (PyObject * self, PyObject * args)
{
PyLongObject *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL,
*u = NULL;
rsaKey *key;
if (!PyArg_ParseTuple(args, "O!O!|O!O!O!O!", &PyLong_Type, &n,
&PyLong_Type, &e, &PyLong_Type, &d,
&PyLong_Type, &p, &PyLong_Type, &q,
&PyLong_Type, &u))
return NULL;
key = PyObject_New (rsaKey, &rsaKeyType);
mpz_init (key->n);
mpz_init (key->e);
mpz_init (key->d);
mpz_init (key->p);
mpz_init (key->q);
mpz_init (key->u);
longObjToMPZ (key->n, n);
longObjToMPZ (key->e, e);
if (!d)
{
return (PyObject *) key;
}
longObjToMPZ (key->d, d);
if (p && q)
{
longObjToMPZ (key->p, p);
longObjToMPZ (key->q, q);
if (u) {
longObjToMPZ (key->u, u);
} else {
mpz_invert (key->u, key->p, key->q);
}
}
return (PyObject *) key;
}
static void
rsaKey_dealloc (rsaKey * key)
{
mpz_clear (key->n);
mpz_clear (key->e);
mpz_clear (key->d);
mpz_clear (key->p);
mpz_clear (key->q);
mpz_clear (key->u);
PyObject_Del (key);
}
static PyObject *
rsaKey_getattr (rsaKey * key, char *attr)
{
if (strcmp (attr, "n") == 0)
return mpzToLongObj (key->n);
else if (strcmp (attr, "e") == 0)
return mpzToLongObj (key->e);
else if (strcmp (attr, "d") == 0)
{
if (mpz_size (key->d) == 0)
{
PyErr_SetString(PyExc_AttributeError,
"rsaKey instance has no attribute 'd'");
return NULL;
}
return mpzToLongObj (key->d);
}
else if (strcmp (attr, "p") == 0)
{
if (mpz_size (key->p) == 0)
{
PyErr_SetString(PyExc_AttributeError,
"rsaKey instance has no attribute 'p'");
return NULL;
}
return mpzToLongObj (key->p);
}
else if (strcmp (attr, "q") == 0)
{
if (mpz_size (key->q) == 0)
{
PyErr_SetString(PyExc_AttributeError,
"rsaKey instance has no attribute 'q'");
return NULL;
}
return mpzToLongObj (key->q);
}
else if (strcmp (attr, "u") == 0)
{
if (mpz_size (key->u) == 0)
{
PyErr_SetString(PyExc_AttributeError,
"rsaKey instance has no attribute 'u'");
return NULL;
}
return mpzToLongObj (key->u);
}
else
{
return Py_FindMethod (rsaKey__methods__,
(PyObject *) key, attr);
}
}
PyObject *
rsaKey__encrypt (rsaKey * key, PyObject * args)
{
PyObject *l, *r;
mpz_t v;
int result;
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
{
return NULL;
}
mpz_init (v);
longObjToMPZ (v, (PyLongObject *) l);
result = rsaEncrypt (key, v);
if (result == 1)
{
PyErr_SetString (fastmathError, "Plaintext too large");
return NULL;
}
r = (PyObject *) mpzToLongObj (v);
mpz_clear (v);
return Py_BuildValue ("N", r);
}
PyObject *
rsaKey__decrypt (rsaKey * key, PyObject * args)
{
PyObject *l, *r;
mpz_t v;
int result;
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
{
return NULL;
}
mpz_init (v);
longObjToMPZ (v, (PyLongObject *) l);
result = rsaDecrypt (key, v);
if (result == 1)
{
PyErr_SetString (fastmathError,
"Ciphertext too large");
return NULL;
}
else if (result == 2)
{
PyErr_SetString (fastmathError,
"Private key not available in this object");
return NULL;
}
r = mpzToLongObj (v);
mpz_clear (v);
return Py_BuildValue ("N", r);
}
PyObject *
rsaKey__verify (rsaKey * key, PyObject * args)
{
PyObject *l, *lsig;
mpz_t v, vsig;
if (!PyArg_ParseTuple(args, "O!O!",
&PyLong_Type, &l, &PyLong_Type, &lsig))
{
return NULL;
}
mpz_init (v);
mpz_init (vsig);
longObjToMPZ (v, (PyLongObject *) l);
longObjToMPZ (vsig, (PyLongObject *) lsig);
rsaEncrypt (key, vsig);
if (mpz_cmp (v, vsig) == 0) {
Py_INCREF(Py_True);
return Py_True;
}
else {
Py_INCREF(Py_False);
return Py_False;
}
}
PyObject *
rsaKey__blind (rsaKey * key, PyObject * args)
{
PyObject *l, *lblind, *r;
mpz_t v, vblind;
int result;
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l,
&PyLong_Type, &lblind))
{
return NULL;
}
mpz_init (v);
mpz_init (vblind);
longObjToMPZ (v, (PyLongObject *) l);
longObjToMPZ (vblind, (PyLongObject *) lblind);
result = rsaBlind (key, v, vblind);
if (result == 1)
{
PyErr_SetString (fastmathError, "Message too large");
return NULL;
}
else if (result == 2)
{
PyErr_SetString (fastmathError, "Blinding factor too large");
return NULL;
}
r = (PyObject *) mpzToLongObj (v);
mpz_clear (v);
mpz_clear (vblind);
return Py_BuildValue ("N", r);
}
PyObject *
rsaKey__unblind (rsaKey * key, PyObject * args)
{
PyObject *l, *lblind, *r;
mpz_t v, vblind;
int result;
if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l,
&PyLong_Type, &lblind))
{
return NULL;
}
mpz_init (v);
mpz_init (vblind);
longObjToMPZ (v, (PyLongObject *) l);
longObjToMPZ (vblind, (PyLongObject *) lblind);
result = rsaUnBlind (key, v, vblind);
if (result == 1)
{
PyErr_SetString (fastmathError, "Message too large");
return NULL;
}
else if (result == 2)
{
PyErr_SetString (fastmathError, "Blinding factor too large");
return NULL;
}
else if (result == 3)
{
PyErr_SetString (fastmathError, "Inverse doesn't exist");
return NULL;
}
r = (PyObject *) mpzToLongObj (v);
mpz_clear (v);
mpz_clear (vblind);
return Py_BuildValue ("N", r);
}
PyObject *
rsaKey_size (rsaKey * key, PyObject * args)
{
if (!PyArg_ParseTuple (args, ""))
return NULL;
return Py_BuildValue ("i", mpz_sizeinbase (key->n, 2) - 1);
}
PyObject *
rsaKey_has_private (rsaKey * key, PyObject * args)
{
if (!PyArg_ParseTuple (args, ""))
return NULL;
if (mpz_size (key->d) == 0) {
Py_INCREF(Py_False);
return Py_False;
} else {
Py_INCREF(Py_True);
return Py_True;
}
}
PyObject *
isPrime (PyObject * self, PyObject * args)
{
PyObject *l;
mpz_t n;
int result;
if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
{
return NULL;
}
mpz_init (n);
longObjToMPZ (n, (PyLongObject *) l);
result = mpz_probab_prime_p(n, 5);
mpz_clear (n);
if (result == 0) {
Py_INCREF(Py_False);
return Py_False;
} else {
Py_INCREF(Py_True);
return Py_True;
}
}
static PyMethodDef _fastmath__methods__[] = {
{"dsa_construct", dsaKey_new, METH_VARARGS},
{"rsa_construct", rsaKey_new, METH_VARARGS},
{"isPrime", isPrime, METH_VARARGS},
{NULL, NULL}
};
void
init_fastmath (void)
{
PyObject *_fastmath_module;
PyObject *_fastmath_dict;
rsaKeyType.ob_type = &PyType_Type;
dsaKeyType.ob_type = &PyType_Type;
_fastmath_module = Py_InitModule ("_fastmath", _fastmath__methods__);
_fastmath_dict = PyModule_GetDict (_fastmath_module);
fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL);
PyDict_SetItemString (_fastmath_dict, "error", fastmathError);
}

View File

@ -1,750 +0,0 @@
/* -*- C -*- */
/*
* block_template.c : Generic framework for block encryption algorithms
*
* Distribute and use freely; there are no restrictions on further
* dissemination and usage except those imposed by the laws of your
* country of residence. This software is provided "as is" without
* warranty of fitness for use or suitability for any purpose, express
* or implied. Use at your own risk or not at all.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _HAVE_STDC_HEADERS
#include <string.h>
#endif
#include "Python.h"
#include "modsupport.h"
/* Cipher operation modes */
#define MODE_ECB 1
#define MODE_CBC 2
#define MODE_CFB 3
#define MODE_PGP 4
#define MODE_OFB 5
#define MODE_CTR 6
#define _STR(x) #x
#define _XSTR(x) _STR(x)
#define _PASTE(x,y) x##y
#define _PASTE2(x,y) _PASTE(x,y)
#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
#define _MODULE_STRING _XSTR(MODULE_NAME)
typedef struct
{
PyObject_HEAD
int mode, count, segment_size;
unsigned char IV[BLOCK_SIZE], oldCipher[BLOCK_SIZE];
unsigned char ctrval[BLOCK_SIZE]; /* carries counter value between block crypt calls */
unsigned char ctroffset; /* carries offset into current block between block crypt calls */
block_state st;
} ALGobject;
staticforward PyTypeObject ALGtype;
#define is_ALGobject(v) ((v)->ob_type == &ALGtype)
static ALGobject *
newALGobject(void)
{
ALGobject * new;
new = PyObject_New(ALGobject, &ALGtype);
new->mode = MODE_ECB;
memset(new->ctrval, 0, BLOCK_SIZE);
new->ctroffset = 0;
return new;
}
static void
ALGdealloc(PyObject *ptr)
{
ALGobject *self = (ALGobject *)ptr;
/* Overwrite the contents of the object */
memset(self->IV, 0, BLOCK_SIZE);
memset(self->oldCipher, 0, BLOCK_SIZE);
memset((char*)&(self->st), 0, sizeof(block_state));
memset(self->ctrval, 0, BLOCK_SIZE);
self->ctroffset = 0;
self->mode = self->count = self->segment_size = 0;
PyObject_Del(ptr);
}
static char ALGnew__doc__[] =
"new(key, [mode], [IV]): Return a new " _MODULE_STRING " encryption object.";
static char *kwlist[] = {"key", "mode", "IV", "counterstart", "segment_size",
#ifdef PCT_RC5_MODULE
"version", "word_size", "rounds",
#endif
NULL};
static ALGobject *
ALGnew(PyObject *self, PyObject *args, PyObject *kwdict)
{
unsigned char *key, *IV;
ALGobject * new=NULL;
int keylen, IVlen=0, mode=MODE_ECB, segment_size=0;
PyObject *counterstart = NULL;
#ifdef PCT_RC5_MODULE
int version = 0x10, word_size = 32, rounds = 16; /*XXX default rounds? */
#endif
/* Set default values */
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s#|is#Oi"
#ifdef PCT_RC5_MODULE
"iii"
#endif
, kwlist,
&key, &keylen, &mode, &IV, &IVlen,
&counterstart, &segment_size
#ifdef PCT_RC5_MODULE
, &version, &word_size, &rounds
#endif
))
{
return NULL;
}
if (KEY_SIZE!=0 && keylen!=KEY_SIZE)
{
PyErr_Format(PyExc_ValueError,
"Key must be %i bytes long, not %i",
KEY_SIZE, keylen);
return NULL;
}
if (KEY_SIZE==0 && keylen==0)
{
PyErr_SetString(PyExc_ValueError,
"Key cannot be the null string");
return NULL;
}
if (IVlen != BLOCK_SIZE && IVlen != 0)
{
PyErr_Format(PyExc_ValueError,
"IV must be %i bytes long", BLOCK_SIZE);
return NULL;
}
if (mode<MODE_ECB || mode>MODE_CTR)
{
PyErr_Format(PyExc_ValueError,
"Unknown cipher feedback mode %i",
mode);
return NULL;
}
/* Mode-specific checks */
if (mode == MODE_CFB) {
if (segment_size == 0) segment_size = 8;
if (segment_size < 1 || segment_size > BLOCK_SIZE*8) {
PyErr_Format(PyExc_ValueError,
"segment_size must be multiple of 8 "
"between 1 and %i", BLOCK_SIZE);
}
}
if (mode == MODE_CTR) {
if ((counterstart == NULL) || (!PyString_Check(counterstart))) {
PyErr_SetString(PyExc_ValueError,
"'counterstart' parameter is required to be a string");
return NULL;
}
if (PyString_Size(counterstart) != BLOCK_SIZE) {
PyErr_SetString(PyExc_ValueError,
"'counterstart' parameter is required to be of length block size");
return NULL;
}
} else {
if (counterstart != NULL) {
PyErr_SetString(PyExc_ValueError,
"'counterstart' parameter only useful with CTR mode");
return NULL;
}
}
/* Cipher-specific checks */
#ifdef PCT_RC5_MODULE
if (version!=0x10) {
PyErr_Format(PyExc_ValueError,
"RC5: Bad RC5 algorithm version: %i",
version);
return NULL;
}
if (word_size!=16 && word_size!=32) {
PyErr_Format(PyExc_ValueError,
"RC5: Unsupported word size: %i",
word_size);
return NULL;
}
if (rounds<0 || 255<rounds) {
PyErr_Format(PyExc_ValueError,
"RC5: rounds must be between 0 and 255, not %i",
rounds);
return NULL;
}
#endif
/* Copy parameters into object */
new = newALGobject();
new->segment_size = segment_size;
if ((counterstart != NULL) && PyString_Check(counterstart))
{
assert (PyString_Size(counterstart) == BLOCK_SIZE);
memcpy(new->ctrval, PyString_AsString(counterstart), PyString_Size(counterstart));
}
#ifdef PCT_RC5_MODULE
new->st.version = version;
new->st.word_size = word_size;
new->st.rounds = rounds;
#endif
block_init(&(new->st), key, keylen);
if (PyErr_Occurred())
{
Py_DECREF(new);
return NULL;
}
memset(new->IV, 0, BLOCK_SIZE);
memset(new->oldCipher, 0, BLOCK_SIZE);
memcpy(new->IV, IV, IVlen);
new->mode = mode;
new->count=8;
return new;
}
static char ALG_Encrypt__doc__[] =
"Encrypt the provided string of binary data.";
/*
* Treat the data in buf as an big-endian unsigned integer and increment it
* mod 2^(bytes*8).
*/
void
increment_unsigned(unsigned char*buf, size_t bytes)
{
unsigned char* p = buf + bytes - 1;
while (*p == 255)
{
*p += 1;
/* carry */
if (p == buf)
return;
p--;
}
*p += 1;
}
static void
ctr_crypt(ALGobject *const self, const unsigned char*const str, unsigned char*const buffer, const int len)
{
int i = 0; /* always points to the next byte of str which is to be crypted */
unsigned char temp[BLOCK_SIZE];
while (i < len)
{
/* This loop is per block. */
block_encrypt(&(self->st), self->ctrval, temp);
while (self->ctroffset < BLOCK_SIZE)
{
if (i == len)
return; /* finished */
/* This loop is per byte. */
buffer[i] = str[i]^temp[self->ctroffset];
i++; self->ctroffset++;
}
increment_unsigned(self->ctrval, BLOCK_SIZE);
self->ctroffset = 0;
}
}
static PyObject *
ALG_Encrypt(ALGobject *self, PyObject *args)
{
unsigned char *buffer, *str;
unsigned char temp[BLOCK_SIZE];
int i, j, len;
PyObject *result;
if (!PyArg_Parse(args, "s#", &str, &len))
return NULL;
if (len==0) /* Handle empty string */
{
return PyString_FromStringAndSize(NULL, 0);
}
if ( (len % BLOCK_SIZE) !=0 &&
(self->mode!=MODE_CFB) && (self->mode!=MODE_PGP) && self->mode!=MODE_CTR)
{
PyErr_Format(PyExc_ValueError,
"Input strings must be "
"a multiple of %i in length",
BLOCK_SIZE);
return NULL;
}
if (self->mode == MODE_CFB &&
(len % (self->segment_size/8) !=0)) {
PyErr_Format(PyExc_ValueError,
"Input strings must be a multiple of "
"the segment size %i in length",
self->segment_size/8);
return NULL;
}
buffer=malloc(len);
if (buffer==NULL)
{
PyErr_SetString(PyExc_MemoryError,
"No memory available in "
_MODULE_STRING " encrypt");
return NULL;
}
switch(self->mode)
{
case(MODE_ECB):
for(i=0; i<len; i+=BLOCK_SIZE)
{
block_encrypt(&(self->st), str+i, buffer+i);
}
break;
case(MODE_CBC):
for(i=0; i<len; i+=BLOCK_SIZE)
{
for(j=0; j<BLOCK_SIZE; j++)
{
temp[j]=str[i+j]^self->IV[j];
}
block_encrypt(&(self->st), temp, buffer+i);
memcpy(self->IV, buffer+i, BLOCK_SIZE);
}
break;
case(MODE_CFB):
for(i=0; i<len; i+=self->segment_size/8)
{
block_encrypt(&(self->st), self->IV, temp);
for (j=0; j<self->segment_size/8; j++) {
buffer[i+j] = str[i+j] ^ temp[j];
}
if (self->segment_size == BLOCK_SIZE * 8) {
/* s == b: segment size is identical to
the algorithm block size */
memcpy(self->IV, buffer + i, BLOCK_SIZE);
}
else if ((self->segment_size % 8) == 0) {
int sz = self->segment_size/8;
memmove(self->IV, self->IV + sz,
BLOCK_SIZE-sz);
memcpy(self->IV + BLOCK_SIZE - sz, buffer + i,
sz);
}
else {
/* segment_size is not a multiple of 8;
currently this can't happen */
}
}
break;
case(MODE_PGP):
if (len<=BLOCK_SIZE-self->count)
{
/* If less than one block, XOR it in */
for(i=0; i<len; i++)
buffer[i] = self->IV[self->count+i] ^= str[i];
self->count += len;
}
else
{
int j;
for(i=0; i<BLOCK_SIZE-self->count; i++)
buffer[i] = self->IV[self->count+i] ^= str[i];
self->count=0;
for(; i<len-BLOCK_SIZE; i+=BLOCK_SIZE)
{
block_encrypt(&(self->st), self->oldCipher,
self->IV);
for(j=0; j<BLOCK_SIZE; j++)
buffer[i+j] = self->IV[j] ^= str[i+j];
}
/* Do the remaining 1 to BLOCK_SIZE bytes */
block_encrypt(&(self->st), self->oldCipher, self->IV);
self->count=len-i;
for(j=0; j<len-i; j++)
{
buffer[i+j] = self->IV[j] ^= str[i+j];
}
}
break;
case(MODE_OFB):
for(i=0; i<len; i+=BLOCK_SIZE)
{
block_encrypt(&(self->st), self->IV, temp);
memcpy(self->IV, temp, BLOCK_SIZE);
for(j=0; j<BLOCK_SIZE; j++)
{
buffer[i+j] = str[i+j] ^ temp[j];
}
}
break;
case(MODE_CTR):
ctr_crypt(self, str, buffer, len);
break;
default:
PyErr_Format(PyExc_SystemError,
"Unknown ciphertext feedback mode %i; "
"this shouldn't happen",
self->mode);
free(buffer);
return NULL;
}
result=PyString_FromStringAndSize((char *)buffer, len);
free(buffer);
return(result);
}
static char ALG_Decrypt__doc__[] =
"decrypt(string): Decrypt the provided string of binary data.";
static PyObject *
ALG_Decrypt(ALGobject *self, PyObject *args)
{
unsigned char *buffer, *str;
unsigned char temp[BLOCK_SIZE];
int i, j, len;
PyObject *result;
if (!PyArg_Parse(args, "s#", &str, &len))
return NULL;
if (len==0) /* Handle empty string */
{
return PyString_FromStringAndSize(NULL, 0);
}
if ( (len % BLOCK_SIZE) !=0 &&
(self->mode!=MODE_CFB && self->mode!=MODE_PGP && self->mode!=MODE_CTR))
{
PyErr_Format(PyExc_ValueError,
"Input strings must be "
"a multiple of %i in length",
BLOCK_SIZE);
return NULL;
}
if (self->mode == MODE_CFB &&
(len % (self->segment_size/8) !=0)) {
PyErr_Format(PyExc_ValueError,
"Input strings must be a multiple of "
"the segment size %i in length",
self->segment_size/8);
return NULL;
}
buffer=malloc(len);
if (buffer==NULL)
{
PyErr_SetString(PyExc_MemoryError,
"No memory available in " _MODULE_STRING
" decrypt");
return NULL;
}
switch(self->mode)
{
case(MODE_ECB):
for(i=0; i<len; i+=BLOCK_SIZE)
{
block_decrypt(&(self->st), str+i, buffer+i);
}
break;
case(MODE_CBC):
for(i=0; i<len; i+=BLOCK_SIZE)
{
memcpy(self->oldCipher, self->IV, BLOCK_SIZE);
block_decrypt(&(self->st), str+i, temp);
for(j=0; j<BLOCK_SIZE; j++)
{
buffer[i+j]=temp[j]^self->IV[j];
self->IV[j]=str[i+j];
}
}
break;
case(MODE_CFB):
for(i=0; i<len; i+=self->segment_size/8)
{
block_encrypt(&(self->st), self->IV, temp);
for (j=0; j<self->segment_size/8; j++) {
buffer[i+j] = str[i+j]^temp[j];
}
if (self->segment_size == BLOCK_SIZE * 8) {
/* s == b: segment size is identical to
the algorithm block size */
memcpy(self->IV, str + i, BLOCK_SIZE);
}
else if ((self->segment_size % 8) == 0) {
int sz = self->segment_size/8;
memmove(self->IV, self->IV + sz,
BLOCK_SIZE-sz);
memcpy(self->IV + BLOCK_SIZE - sz, str + i,
sz);
}
else {
/* segment_size is not a multiple of 8;
currently this can't happen */
}
}
break;
case(MODE_PGP):
if (len<=BLOCK_SIZE-self->count)
{
/* If less than one block, XOR it in */
unsigned char t;
for(i=0; i<len; i++)
{
t=self->IV[self->count+i];
buffer[i] = t ^ (self->IV[self->count+i] = str[i]);
}
self->count += len;
}
else
{
int j;
unsigned char t;
for(i=0; i<BLOCK_SIZE-self->count; i++)
{
t=self->IV[self->count+i];
buffer[i] = t ^ (self->IV[self->count+i] = str[i]);
}
self->count=0;
for(; i<len-BLOCK_SIZE; i+=BLOCK_SIZE)
{
block_encrypt(&(self->st), self->oldCipher, self->IV);
for(j=0; j<BLOCK_SIZE; j++)
{
t=self->IV[j];
buffer[i+j] = t ^ (self->IV[j] = str[i+j]);
}
}
/* Do the remaining 1 to BLOCK_SIZE bytes */
block_encrypt(&(self->st), self->oldCipher, self->IV);
self->count=len-i;
for(j=0; j<len-i; j++)
{
t=self->IV[j];
buffer[i+j] = t ^ (self->IV[j] = str[i+j]);
}
}
break;
case (MODE_OFB):
for(i=0; i<len; i+=BLOCK_SIZE)
{
block_encrypt(&(self->st), self->IV, temp);
memcpy(self->IV, temp, BLOCK_SIZE);
for(j=0; j<BLOCK_SIZE; j++)
{
buffer[i+j] = str[i+j] ^ self->IV[j];
}
}
break;
case (MODE_CTR):
ctr_crypt(self, str, buffer, len);
break;
default:
PyErr_Format(PyExc_SystemError,
"Unknown ciphertext feedback mode %i; "
"this shouldn't happen",
self->mode);
free(buffer);
return NULL;
}
result=PyString_FromStringAndSize((char *)buffer, len);
free(buffer);
return(result);
}
static char ALG_Sync__doc__[] =
"sync(): For objects using the PGP feedback mode, this method modifies "
"the IV, synchronizing it with the preceding ciphertext.";
static PyObject *
ALG_Sync(ALGobject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) {
return NULL;
}
if (self->mode!=MODE_PGP)
{
PyErr_SetString(PyExc_SystemError, "sync() operation not defined for "
"this feedback mode");
return NULL;
}
if (self->count!=8)
{
memmove(self->IV+BLOCK_SIZE-self->count, self->IV,
self->count);
memcpy(self->IV, self->oldCipher+self->count,
BLOCK_SIZE-self->count);
self->count=8;
}
Py_INCREF(Py_None);
return Py_None;
}
#if 0
void PrintState(self, msg)
ALGobject *self;
char * msg;
{
int count;
printf("%sing: %i IV ", msg, (int)self->count);
for(count=0; count<8; count++) printf("%i ", self->IV[count]);
printf("\noldCipher:");
for(count=0; count<8; count++) printf("%i ", self->oldCipher[count]);
printf("\n");
}
#endif
/* ALG object methods */
static PyMethodDef ALGmethods[] =
{
{"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__},
{"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__},
{"sync", (PyCFunction) ALG_Sync, METH_VARARGS, ALG_Sync__doc__},
{NULL, NULL} /* sentinel */
};
static int
ALGsetattr(PyObject *ptr, char *name, PyObject *v)
{
ALGobject *self=(ALGobject *)ptr;
if (strcmp(name, "IV") != 0)
{
PyErr_Format(PyExc_AttributeError,
"non-existent block cipher object attribute '%s'",
name);
return -1;
}
if (v==NULL)
{
PyErr_SetString(PyExc_AttributeError,
"Can't delete IV attribute of block cipher object");
return -1;
}
if (!PyString_Check(v))
{
PyErr_SetString(PyExc_TypeError,
"IV attribute of block cipher object must be string");
return -1;
}
if (PyString_Size(v)!=BLOCK_SIZE)
{
PyErr_Format(PyExc_ValueError,
_MODULE_STRING " IV must be %i bytes long",
BLOCK_SIZE);
return -1;
}
memcpy(self->IV, PyString_AsString(v), BLOCK_SIZE);
return 0;
}
static PyObject *
ALGgetattr(PyObject *s, char *name)
{
ALGobject *self = (ALGobject*)s;
if (strcmp(name, "IV") == 0)
{
return(PyString_FromStringAndSize((char *)(self->IV), BLOCK_SIZE));
}
if (strcmp(name, "mode") == 0)
{
return(PyInt_FromLong((long)(self->mode)));
}
if (strcmp(name, "block_size") == 0)
{
return PyInt_FromLong(BLOCK_SIZE);
}
if (strcmp(name, "key_size") == 0)
{
return PyInt_FromLong(KEY_SIZE);
}
return Py_FindMethod(ALGmethods, (PyObject *) self, name);
}
/* List of functions defined in the module */
static struct PyMethodDef modulemethods[] =
{
{"new", (PyCFunction) ALGnew, METH_VARARGS|METH_KEYWORDS, ALGnew__doc__},
{NULL, NULL} /* sentinel */
};
static PyTypeObject ALGtype =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
_MODULE_STRING, /*tp_name*/
sizeof(ALGobject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
ALGdealloc, /*tp_dealloc*/
0, /*tp_print*/
ALGgetattr, /*tp_getattr*/
ALGsetattr, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc) 0, /*tp_repr*/
0, /*tp_as_number*/
};
/* Initialization function for the module */
#if PYTHON_API_VERSION < 1011
#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \
if (o!=NULL) \
{PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}}
#endif
void
_MODULE_NAME (void)
{
PyObject *m;
ALGtype.ob_type = &PyType_Type;
/* Create the module and add the functions */
m = Py_InitModule("allmydata.Crypto.Cipher." _MODULE_STRING, modulemethods);
PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB);
PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC);
PyModule_AddIntConstant(m, "MODE_CFB", MODE_CFB);
PyModule_AddIntConstant(m, "MODE_PGP", MODE_PGP);
PyModule_AddIntConstant(m, "MODE_OFB", MODE_OFB);
PyModule_AddIntConstant(m, "MODE_CTR", MODE_CTR);
PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE);
PyModule_AddIntConstant(m, "key_size", KEY_SIZE);
/* Check for errors */
if (PyErr_Occurred())
Py_FatalError("can't initialize module " _MODULE_STRING);
}

View File

@ -1,248 +0,0 @@
/*
* hash_template.c : Generic framework for hash function extension modules
*
* Distribute and use freely; there are no restrictions on further
* dissemination and usage except those imposed by the laws of your
* country of residence. This software is provided "as is" without
* warranty of fitness for use or suitability for any purpose, express
* or implied. Use at your own risk or not at all.
*
*/
/* Basic object type */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _HAVE_STDC_HEADERS
#include <string.h>
#endif
#define _STR(x) #x
#define _XSTR(x) _STR(x)
#define _PASTE(x,y) x##y
#define _PASTE2(x,y) _PASTE(x,y)
#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
#define _MODULE_STRING _XSTR(MODULE_NAME)
typedef struct {
PyObject_HEAD
hash_state st;
} ALGobject;
staticforward PyTypeObject ALGtype;
#define is_ALGobject(v) ((v)->ob_type == &ALGtype)
static ALGobject *
newALGobject(void)
{
ALGobject *new;
new = PyObject_New(ALGobject, &ALGtype);
return new;
}
/* Internal methods for a hashing object */
static void
ALG_dealloc(PyObject *ptr)
{
ALGobject *self = (ALGobject *)ptr;
/* Overwrite the contents of the object */
memset((char*)&(self->st), 0, sizeof(hash_state));
PyObject_Del(ptr);
}
/* External methods for a hashing object */
static char ALG_copy__doc__[] =
"copy(): Return a copy of the hashing object.";
static PyObject *
ALG_copy(ALGobject *self, PyObject *args)
{
ALGobject *newobj;
if (!PyArg_ParseTuple(args, "")) {
return NULL;
}
if ( (newobj = newALGobject())==NULL)
return NULL;
hash_copy(&(self->st), &(newobj->st));
return((PyObject *)newobj);
}
static char ALG_digest__doc__[] =
"digest(): Return the digest value as a string of binary data.";
static PyObject *
ALG_digest(ALGobject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
return (PyObject *)hash_digest(&(self->st));
}
static char ALG_hexdigest__doc__[] =
"hexdigest(): Return the digest value as a string of hexadecimal digits.";
static PyObject *
ALG_hexdigest(ALGobject *self, PyObject *args)
{
PyObject *value, *retval;
unsigned char *raw_digest, *hex_digest;
int i, j, size;
if (!PyArg_ParseTuple(args, ""))
return NULL;
/* Get the raw (binary) digest value */
value = (PyObject *)hash_digest(&(self->st));
size = PyString_Size(value);
raw_digest = (unsigned char *)PyString_AsString(value);
/* Create a new string */
retval = PyString_FromStringAndSize(NULL, size * 2 );
hex_digest = (unsigned char *)PyString_AsString(retval);
/* Make hex version of the digest */
for(i=j=0; i<size; i++)
{
char c;
c = raw_digest[i] / 16; c = (c>9) ? c+'a'-10 : c + '0';
hex_digest[j++] = c;
c = raw_digest[i] % 16; c = (c>9) ? c+'a'-10 : c + '0';
hex_digest[j++] = c;
}
Py_DECREF(value);
return retval;
}
static char ALG_update__doc__[] =
"update(string): Update this hashing object's state with the provided string.";
static PyObject *
ALG_update(ALGobject *self, PyObject *args)
{
unsigned char *cp;
int len;
if (!PyArg_ParseTuple(args, "s#", &cp, &len))
return NULL;
hash_update(&(self->st), cp, len);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef ALG_methods[] = {
{"copy", (PyCFunction)ALG_copy, METH_VARARGS, ALG_copy__doc__},
{"digest", (PyCFunction)ALG_digest, METH_VARARGS, ALG_digest__doc__},
{"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS,
ALG_hexdigest__doc__},
{"update", (PyCFunction)ALG_update, METH_VARARGS, ALG_update__doc__},
{NULL, NULL} /* sentinel */
};
static PyObject *
ALG_getattr(PyObject *self, char *name)
{
if (strcmp(name, "digest_size")==0)
return PyInt_FromLong(DIGEST_SIZE);
return Py_FindMethod(ALG_methods, self, name);
}
static PyTypeObject ALGtype = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
_MODULE_STRING, /*tp_name*/
sizeof(ALGobject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
ALG_dealloc, /*tp_dealloc*/
0, /*tp_print*/
ALG_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
};
/* The single module-level function: new() */
static char ALG_new__doc__[] =
"new([string]): Return a new " _MODULE_STRING
" hashing object. An optional string "
"argument may be provided; if present, this string will be "
"automatically hashed into the initial state of the object.";
static PyObject *
ALG_new(PyObject *self, PyObject *args)
{
ALGobject *new;
unsigned char *cp = NULL;
int len;
if ((new = newALGobject()) == NULL)
return NULL;
if (!PyArg_ParseTuple(args, "|s#",
&cp, &len)) {
Py_DECREF(new);
return NULL;
}
hash_init(&(new->st));
if (PyErr_Occurred()) {
Py_DECREF(new);
return NULL;
}
if (cp)
hash_update(&(new->st), cp, len);
return (PyObject *)new;
}
/* List of functions exported by this module */
static struct PyMethodDef ALG_functions[] = {
{"new", (PyCFunction)ALG_new, METH_VARARGS, ALG_new__doc__},
{NULL, NULL} /* Sentinel */
};
/* Initialize this module. */
#if PYTHON_API_VERSION < 1011
#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \
if (o!=NULL) \
{PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}}
#endif
void
_MODULE_NAME (void)
{
PyObject *m;
ALGtype.ob_type = &PyType_Type;
m = Py_InitModule("allmydata.Crypto.Hash." _MODULE_STRING, ALG_functions);
/* Add some symbolic constants to the module */
PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE);
/* Check for errors */
if (PyErr_Occurred())
Py_FatalError("can't initialize module "
_MODULE_STRING);
}

View File

@ -10,7 +10,6 @@ from twisted.application.internet import TimerService
from twisted.python import log
import allmydata
from allmydata.Crypto.Util.number import bytes_to_long
from allmydata.storage import StorageServer
from allmydata.upload import Uploader
from allmydata.download import Downloader
@ -238,7 +237,7 @@ class Client(node.Node, Referenceable, testutil.PollMixin):
if not include_myself and peerid == self.nodeid:
self.log("get_permuted_peers: removing myself from the list")
continue
permuted = bytes_to_long(sha.new(key + peerid).digest())
permuted = sha.new(key + peerid).digest()
results.append((permuted, peerid, connection))
results.sort()
return results

View File

@ -11,7 +11,6 @@ from allmydata.interfaces import IURI, INewDirectoryURI, \
IMutableFileURI
import sha
from allmydata.Crypto.Util.number import bytes_to_long
class Netstring(unittest.TestCase):
def test_split(self):
@ -151,7 +150,7 @@ class FakeClient:
results = []
for peerid, connection in peers_and_connections:
assert isinstance(peerid, str)
permuted = bytes_to_long(sha.new(key + peerid).digest())
permuted = sha.new(key + peerid).digest()
results.append((permuted, peerid, connection))
results.sort()
return results