mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-08 11:24:25 +00:00
remove PyCrypto, now we only use pycrypto++
This commit is contained in:
parent
0bf5a762a9
commit
955bd5383d
5
setup.py
5
setup.py
@ -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
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
@ -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)
|
@ -1,4 +0,0 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
# we also need to provide bytes_to_long, normally from
|
||||
# allmydata.Crypto.Util.number.bytes_to_long
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user