mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-21 13:57:51 +00:00
copy RSA from PyCrypto into the allmydata/ tree, we'll use it eventually
This commit is contained in:
parent
8088044bf3
commit
6c24848797
5
setup.py
5
setup.py
@ -85,7 +85,8 @@ setup(name='allmydata-tahoe',
|
||||
packages=["allmydata", "allmydata.test", "allmydata.util",
|
||||
"allmydata.scripts",
|
||||
"allmydata.Crypto", "allmydata.Crypto.Cipher",
|
||||
"allmydata.Crypto.Hash", "allmydata.Crypto.Util"],
|
||||
"allmydata.Crypto.Hash", "allmydata.Crypto.Util",
|
||||
"allmydata.Crypto.PublicKey"],
|
||||
package_dir={ "allmydata": "src/allmydata",},
|
||||
scripts = ["bin/allmydata-tahoe"],
|
||||
package_data={ 'allmydata': ['web/*.xhtml', 'web/*.html', 'web/*.css'] },
|
||||
@ -98,5 +99,7 @@ setup(name='allmydata-tahoe',
|
||||
Extension("allmydata.Crypto.Hash.SHA256",
|
||||
include_dirs=["src/allmydata/Crypto"],
|
||||
sources=["src/allmydata/Crypto/SHA256.c"]),
|
||||
Extension("allmydata.Crypto.PublicKey._fastmath",
|
||||
sources=["src/allmydata/Crypto/_fastmath.c"]),
|
||||
],
|
||||
)
|
||||
|
257
src/allmydata/Crypto/PublicKey/RSA.py
Normal file
257
src/allmydata/Crypto/PublicKey/RSA.py
Normal file
@ -0,0 +1,257 @@
|
||||
#
|
||||
# RSA.py : RSA encryption/decryption
|
||||
#
|
||||
# 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: RSA.py,v 1.20 2004/05/06 12:52:54 akuchling Exp $"
|
||||
|
||||
from allmydata.Crypto.PublicKey import pubkey
|
||||
from allmydata.Crypto.Util import number
|
||||
|
||||
_fastmath = None
|
||||
try:
|
||||
from allmydata.Crypto.PublicKey import _fastmath
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate an RSA key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=RSAobj()
|
||||
|
||||
# Generate the prime factors of n
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
p = q = 1L
|
||||
while number.size(p*q) < bits:
|
||||
p = pubkey.getPrime(bits/2, randfunc)
|
||||
q = pubkey.getPrime(bits/2, randfunc)
|
||||
|
||||
# p shall be smaller than q (for calc of u)
|
||||
if p > q:
|
||||
(p, q)=(q, p)
|
||||
obj.p = p
|
||||
obj.q = q
|
||||
|
||||
if progress_func:
|
||||
progress_func('u\n')
|
||||
obj.u = pubkey.inverse(obj.p, obj.q)
|
||||
obj.n = obj.p*obj.q
|
||||
|
||||
obj.e = 65537L
|
||||
if progress_func:
|
||||
progress_func('d\n')
|
||||
obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1))
|
||||
|
||||
assert bits <= 1+obj.size(), "Generated key is too small"
|
||||
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,) : RSAobj
|
||||
Construct an RSA object from a 2-, 3-, 5-, or 6-tuple of numbers.
|
||||
"""
|
||||
|
||||
obj=RSAobj()
|
||||
if len(tuple) not in [2,3,5,6]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
if len(tuple) >= 5:
|
||||
# Ensure p is smaller than q
|
||||
if obj.p>obj.q:
|
||||
(obj.p, obj.q)=(obj.q, obj.p)
|
||||
|
||||
if len(tuple) == 5:
|
||||
# u not supplied, so we're going to have to compute it.
|
||||
obj.u=pubkey.inverse(obj.p, obj.q)
|
||||
|
||||
return obj
|
||||
|
||||
class RSAobj(pubkey.pubkey):
|
||||
keydata = ['n', 'e', 'd', 'p', 'q', 'u']
|
||||
def _encrypt(self, plaintext, K=''):
|
||||
if self.n<=plaintext:
|
||||
raise error, 'Plaintext too large'
|
||||
return (pow(plaintext, self.e, self.n),)
|
||||
|
||||
def _decrypt(self, ciphertext):
|
||||
if (not hasattr(self, 'd')):
|
||||
raise error, 'Private key not available in this object'
|
||||
if self.n<=ciphertext[0]:
|
||||
raise error, 'Ciphertext too large'
|
||||
return pow(ciphertext[0], self.d, self.n)
|
||||
|
||||
def _sign(self, M, K=''):
|
||||
return (self._decrypt((M,)),)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
m2=self._encrypt(sig[0])
|
||||
if m2[0]==M:
|
||||
return 1
|
||||
else: return 0
|
||||
|
||||
def _blind(self, M, B):
|
||||
tmp = pow(B, self.e, self.n)
|
||||
return (M * tmp) % self.n
|
||||
|
||||
def _unblind(self, M, B):
|
||||
tmp = pubkey.inverse(B, self.n)
|
||||
return (M * tmp) % self.n
|
||||
|
||||
def can_blind (self):
|
||||
"""can_blind() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
blind data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to blind a message.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def size(self):
|
||||
"""size() : int
|
||||
Return the maximum number of bits that can be handled by this key.
|
||||
"""
|
||||
return number.size(self.n) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""has_private() : bool
|
||||
Return a Boolean denoting whether the object contains
|
||||
private components.
|
||||
"""
|
||||
if hasattr(self, 'd'):
|
||||
return 1
|
||||
else: return 0
|
||||
|
||||
def publickey(self):
|
||||
"""publickey(): RSAobj
|
||||
Return a new key object containing only the public key information.
|
||||
"""
|
||||
return construct((self.n, self.e))
|
||||
|
||||
class RSAobj_c(pubkey.pubkey):
|
||||
keydata = ['n', 'e', 'd', 'p', 'q', 'u']
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self.keydata:
|
||||
return getattr(self.key, attr)
|
||||
else:
|
||||
if self.__dict__.has_key(attr):
|
||||
self.__dict__[attr]
|
||||
else:
|
||||
raise AttributeError, '%s instance has no attribute %s' % (self.__class__, attr)
|
||||
|
||||
def __getstate__(self):
|
||||
d = {}
|
||||
for k in self.keydata:
|
||||
if hasattr(self.key, k):
|
||||
d[k]=getattr(self.key, k)
|
||||
return d
|
||||
|
||||
def __setstate__(self, state):
|
||||
n,e = state['n'], state['e']
|
||||
if not state.has_key('d'):
|
||||
self.key = _fastmath.rsa_construct(n,e)
|
||||
else:
|
||||
d = state['d']
|
||||
if not state.has_key('q'):
|
||||
self.key = _fastmath.rsa_construct(n,e,d)
|
||||
else:
|
||||
p, q, u = state['p'], state['q'], state['u']
|
||||
self.key = _fastmath.rsa_construct(n,e,d,p,q,u)
|
||||
|
||||
def _encrypt(self, plain, K):
|
||||
return (self.key._encrypt(plain),)
|
||||
|
||||
def _decrypt(self, cipher):
|
||||
return self.key._decrypt(cipher[0])
|
||||
|
||||
def _sign(self, M, K):
|
||||
return (self.key._sign(M),)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
return self.key._verify(M, sig[0])
|
||||
|
||||
def _blind(self, M, B):
|
||||
return self.key._blind(M, B)
|
||||
|
||||
def _unblind(self, M, B):
|
||||
return self.key._unblind(M, B)
|
||||
|
||||
def can_blind (self):
|
||||
return 1
|
||||
|
||||
def size(self):
|
||||
return self.key.size()
|
||||
|
||||
def has_private(self):
|
||||
return self.key.has_private()
|
||||
|
||||
def publickey(self):
|
||||
return construct_c((self.key.n, self.key.e))
|
||||
|
||||
def generate_c(bits, randfunc, progress_func = None):
|
||||
# Generate the prime factors of n
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
|
||||
p = q = 1L
|
||||
while number.size(p*q) < bits:
|
||||
p = pubkey.getPrime(bits/2, randfunc)
|
||||
q = pubkey.getPrime(bits/2, randfunc)
|
||||
|
||||
# p shall be smaller than q (for calc of u)
|
||||
if p > q:
|
||||
(p, q)=(q, p)
|
||||
if progress_func:
|
||||
progress_func('u\n')
|
||||
u=pubkey.inverse(p, q)
|
||||
n=p*q
|
||||
|
||||
e = 65537L
|
||||
if progress_func:
|
||||
progress_func('d\n')
|
||||
d=pubkey.inverse(e, (p-1)*(q-1))
|
||||
key = _fastmath.rsa_construct(n,e,d,p,q,u)
|
||||
obj = RSAobj_c(key)
|
||||
|
||||
## print p
|
||||
## print q
|
||||
## print number.size(p), number.size(q), number.size(q*p),
|
||||
## print obj.size(), bits
|
||||
assert bits <= 1+obj.size(), "Generated key is too small"
|
||||
return obj
|
||||
|
||||
|
||||
def construct_c(tuple):
|
||||
key = apply(_fastmath.rsa_construct, tuple)
|
||||
return RSAobj_c(key)
|
||||
|
||||
object = RSAobj
|
||||
|
||||
generate_py = generate
|
||||
construct_py = construct
|
||||
|
||||
if _fastmath:
|
||||
#print "using C version of RSA"
|
||||
generate = generate_c
|
||||
construct = construct_c
|
||||
error = _fastmath.error
|
17
src/allmydata/Crypto/PublicKey/__init__.py
Normal file
17
src/allmydata/Crypto/PublicKey/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
"""Public-key encryption and signature algorithms.
|
||||
|
||||
Public-key encryption uses two different keys, one for encryption and
|
||||
one for decryption. The encryption key can be made public, and the
|
||||
decryption key is kept private. Many public-key algorithms can also
|
||||
be used to sign messages, and some can *only* be used for signatures.
|
||||
|
||||
Crypto.PublicKey.DSA Digital Signature Algorithm. (Signature only)
|
||||
Crypto.PublicKey.ElGamal (Signing and encryption)
|
||||
Crypto.PublicKey.RSA (Signing, encryption, and blinding)
|
||||
Crypto.PublicKey.qNEW (Signature only)
|
||||
|
||||
"""
|
||||
|
||||
__all__ = ['RSA']
|
||||
__revision__ = "$Id: __init__.py,v 1.4 2003/04/03 20:27:13 akuchling Exp $"
|
||||
|
173
src/allmydata/Crypto/PublicKey/pubkey.py
Normal file
173
src/allmydata/Crypto/PublicKey/pubkey.py
Normal file
@ -0,0 +1,173 @@
|
||||
#
|
||||
# pubkey.py : Internal functions for public key operations
|
||||
#
|
||||
# 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: pubkey.py,v 1.11 2003/04/03 20:36:14 akuchling Exp $"
|
||||
|
||||
import types, warnings
|
||||
from allmydata.Crypto.Util.number import bignum, bytes_to_long, \
|
||||
long_to_bytes, error
|
||||
|
||||
# Basic public key class
|
||||
class pubkey:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __getstate__(self):
|
||||
"""To keep key objects platform-independent, the key data is
|
||||
converted to standard Python long integers before being
|
||||
written out. It will then be reconverted as necessary on
|
||||
restoration."""
|
||||
d=self.__dict__
|
||||
for key in self.keydata:
|
||||
if d.has_key(key): d[key]=long(d[key])
|
||||
return d
|
||||
|
||||
def __setstate__(self, d):
|
||||
"""On unpickling a key object, the key data is converted to the big
|
||||
number representation being used, whether that is Python long
|
||||
integers, MPZ objects, or whatever."""
|
||||
for key in self.keydata:
|
||||
if d.has_key(key): self.__dict__[key]=bignum(d[key])
|
||||
|
||||
def encrypt(self, plaintext, K):
|
||||
"""encrypt(plaintext:string|long, K:string|long) : tuple
|
||||
Encrypt the string or integer plaintext. K is a random
|
||||
parameter required by some algorithms.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(plaintext, types.StringType):
|
||||
plaintext=bytes_to_long(plaintext) ; wasString=1
|
||||
if isinstance(K, types.StringType):
|
||||
K=bytes_to_long(K)
|
||||
ciphertext=self._encrypt(plaintext, K)
|
||||
if wasString: return tuple(map(long_to_bytes, ciphertext))
|
||||
else: return ciphertext
|
||||
|
||||
def decrypt(self, ciphertext):
|
||||
"""decrypt(ciphertext:tuple|string|long): string
|
||||
Decrypt 'ciphertext' using this key.
|
||||
"""
|
||||
wasString=0
|
||||
if not isinstance(ciphertext, types.TupleType):
|
||||
ciphertext=(ciphertext,)
|
||||
if isinstance(ciphertext[0], types.StringType):
|
||||
ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1
|
||||
plaintext=self._decrypt(ciphertext)
|
||||
if wasString: return long_to_bytes(plaintext)
|
||||
else: return plaintext
|
||||
|
||||
def sign(self, M, K):
|
||||
"""sign(M : string|long, K:string|long) : tuple
|
||||
Return a tuple containing the signature for the message M.
|
||||
K is a random parameter required by some algorithms.
|
||||
"""
|
||||
if (not self.has_private()):
|
||||
raise error, 'Private key not available in this object'
|
||||
if isinstance(M, types.StringType): M=bytes_to_long(M)
|
||||
if isinstance(K, types.StringType): K=bytes_to_long(K)
|
||||
return self._sign(M, K)
|
||||
|
||||
def verify (self, M, signature):
|
||||
"""verify(M:string|long, signature:tuple) : bool
|
||||
Verify that the signature is valid for the message M;
|
||||
returns true if the signature checks out.
|
||||
"""
|
||||
if isinstance(M, types.StringType): M=bytes_to_long(M)
|
||||
return self._verify(M, signature)
|
||||
|
||||
# alias to compensate for the old validate() name
|
||||
def validate (self, M, signature):
|
||||
warnings.warn("validate() method name is obsolete; use verify()",
|
||||
DeprecationWarning)
|
||||
|
||||
def blind(self, M, B):
|
||||
"""blind(M : string|long, B : string|long) : string|long
|
||||
Blind message M using blinding factor B.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(M, types.StringType):
|
||||
M=bytes_to_long(M) ; wasString=1
|
||||
if isinstance(B, types.StringType): B=bytes_to_long(B)
|
||||
blindedmessage=self._blind(M, B)
|
||||
if wasString: return long_to_bytes(blindedmessage)
|
||||
else: return blindedmessage
|
||||
|
||||
def unblind(self, M, B):
|
||||
"""unblind(M : string|long, B : string|long) : string|long
|
||||
Unblind message M using blinding factor B.
|
||||
"""
|
||||
wasString=0
|
||||
if isinstance(M, types.StringType):
|
||||
M=bytes_to_long(M) ; wasString=1
|
||||
if isinstance(B, types.StringType): B=bytes_to_long(B)
|
||||
unblindedmessage=self._unblind(M, B)
|
||||
if wasString: return long_to_bytes(unblindedmessage)
|
||||
else: return unblindedmessage
|
||||
|
||||
|
||||
# The following methods will usually be left alone, except for
|
||||
# signature-only algorithms. They both return Boolean values
|
||||
# recording whether this key's algorithm can sign and encrypt.
|
||||
def can_sign (self):
|
||||
"""can_sign() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
generate signatures. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to generate a signature.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def can_encrypt (self):
|
||||
"""can_encrypt() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
encrypt data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to decrypt a message.)
|
||||
"""
|
||||
return 1
|
||||
|
||||
def can_blind (self):
|
||||
"""can_blind() : bool
|
||||
Return a Boolean value recording whether this algorithm can
|
||||
blind data. (This does not imply that this
|
||||
particular key object has the private information required to
|
||||
to blind a message.)
|
||||
"""
|
||||
return 0
|
||||
|
||||
# The following methods will certainly be overridden by
|
||||
# subclasses.
|
||||
|
||||
def size (self):
|
||||
"""size() : int
|
||||
Return the maximum number of bits that can be handled by this key.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def has_private (self):
|
||||
"""has_private() : bool
|
||||
Return a Boolean denoting whether the object contains
|
||||
private components.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def publickey (self):
|
||||
"""publickey(): object
|
||||
Return a new key object containing only the public information.
|
||||
"""
|
||||
return self
|
||||
|
||||
def __eq__ (self, other):
|
||||
"""__eq__(other): 0, 1
|
||||
Compare us to other for equality.
|
||||
"""
|
||||
return self.__getstate__() == other.__getstate__()
|
804
src/allmydata/Crypto/_fastmath.c
Normal file
804
src/allmydata/Crypto/_fastmath.c
Normal file
@ -0,0 +1,804 @@
|
||||
|
||||
/*
|
||||
* _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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user