faset over fra Z3950 til google books
This commit is contained in:
238
python/gdata/Crypto/PublicKey/DSA.py
Normal file
238
python/gdata/Crypto/PublicKey/DSA.py
Normal file
@@ -0,0 +1,238 @@
|
||||
|
||||
#
|
||||
# DSA.py : Digital Signature Algorithm
|
||||
#
|
||||
# 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: DSA.py,v 1.16 2004/05/06 12:52:54 akuchling Exp $"
|
||||
|
||||
from Crypto.PublicKey.pubkey import *
|
||||
from Crypto.Util import number
|
||||
from Crypto.Util.number import bytes_to_long, long_to_bytes
|
||||
from Crypto.Hash import SHA
|
||||
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
except ImportError:
|
||||
_fastmath = None
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
def generateQ(randfunc):
|
||||
S=randfunc(20)
|
||||
hash1=SHA.new(S).digest()
|
||||
hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest()
|
||||
q = bignum(0)
|
||||
for i in range(0,20):
|
||||
c=ord(hash1[i])^ord(hash2[i])
|
||||
if i==0:
|
||||
c=c | 128
|
||||
if i==19:
|
||||
c= c | 1
|
||||
q=q*256+c
|
||||
while (not isPrime(q)):
|
||||
q=q+2
|
||||
if pow(2,159L) < q < pow(2,160L):
|
||||
return S, q
|
||||
raise error, 'Bad q value generated'
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate a DSA key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
|
||||
if bits<160:
|
||||
raise error, 'Key length <160 bits'
|
||||
obj=DSAobj()
|
||||
# Generate string S and prime q
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
while (1):
|
||||
S, obj.q = generateQ(randfunc)
|
||||
n=(bits-1)/160
|
||||
C, N, V = 0, 2, {}
|
||||
b=(obj.q >> 5) & 15
|
||||
powb=pow(bignum(2), b)
|
||||
powL1=pow(bignum(2), bits-1)
|
||||
while C<4096:
|
||||
for k in range(0, n+1):
|
||||
V[k]=bytes_to_long(SHA.new(S+str(N)+str(k)).digest())
|
||||
W=V[n] % powb
|
||||
for k in range(n-1, -1, -1):
|
||||
W=(W<<160L)+V[k]
|
||||
X=W+powL1
|
||||
p=X-(X%(2*obj.q)-1)
|
||||
if powL1<=p and isPrime(p):
|
||||
break
|
||||
C, N = C+1, N+n+1
|
||||
if C<4096:
|
||||
break
|
||||
if progress_func:
|
||||
progress_func('4096 multiples failed\n')
|
||||
|
||||
obj.p = p
|
||||
power=(p-1)/obj.q
|
||||
if progress_func:
|
||||
progress_func('h,g\n')
|
||||
while (1):
|
||||
h=bytes_to_long(randfunc(bits)) % (p-1)
|
||||
g=pow(h, power, p)
|
||||
if 1<h<p-1 and g>1:
|
||||
break
|
||||
obj.g=g
|
||||
if progress_func:
|
||||
progress_func('x,y\n')
|
||||
while (1):
|
||||
x=bytes_to_long(randfunc(20))
|
||||
if 0 < x < obj.q:
|
||||
break
|
||||
obj.x, obj.y = x, pow(g, x, p)
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)):DSAobj
|
||||
Construct a DSA object from a 4- or 5-tuple of numbers.
|
||||
"""
|
||||
obj=DSAobj()
|
||||
if len(tuple) not in [4,5]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class DSAobj(pubkey):
|
||||
keydata=['y', 'g', 'p', 'q', 'x']
|
||||
|
||||
def _encrypt(self, s, Kstr):
|
||||
raise error, 'DSA algorithm cannot encrypt data'
|
||||
|
||||
def _decrypt(self, s):
|
||||
raise error, 'DSA algorithm cannot decrypt data'
|
||||
|
||||
def _sign(self, M, K):
|
||||
if (K<2 or self.q<=K):
|
||||
raise error, 'K is not between 2 and q'
|
||||
r=pow(self.g, K, self.p) % self.q
|
||||
s=(inverse(K, self.q)*(M+self.x*r)) % self.q
|
||||
return (r,s)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
r, s = sig
|
||||
if r<=0 or r>=self.q or s<=0 or s>=self.q:
|
||||
return 0
|
||||
w=inverse(s, self.q)
|
||||
u1, u2 = (M*w) % self.q, (r*w) % self.q
|
||||
v1 = pow(self.g, u1, self.p)
|
||||
v2 = pow(self.y, u2, self.p)
|
||||
v = ((v1*v2) % self.p)
|
||||
v = v % self.q
|
||||
if v==r:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return number.size(self.p) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
if hasattr(self, 'x'):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def can_sign(self):
|
||||
"""Return a Boolean value recording whether this algorithm can generate signatures."""
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
"""Return a Boolean value recording whether this algorithm can encrypt data."""
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.y, self.g, self.p, self.q))
|
||||
|
||||
object=DSAobj
|
||||
|
||||
generate_py = generate
|
||||
construct_py = construct
|
||||
|
||||
class DSAobj_c(pubkey):
|
||||
keydata = ['y', 'g', 'p', 'q', 'x']
|
||||
|
||||
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):
|
||||
y,g,p,q = state['y'], state['g'], state['p'], state['q']
|
||||
if not state.has_key('x'):
|
||||
self.key = _fastmath.dsa_construct(y,g,p,q)
|
||||
else:
|
||||
x = state['x']
|
||||
self.key = _fastmath.dsa_construct(y,g,p,q,x)
|
||||
|
||||
def _sign(self, M, K):
|
||||
return self.key._sign(M, K)
|
||||
|
||||
def _verify(self, M, (r, s)):
|
||||
return self.key._verify(M, r, s)
|
||||
|
||||
def size(self):
|
||||
return self.key.size()
|
||||
|
||||
def has_private(self):
|
||||
return self.key.has_private()
|
||||
|
||||
def publickey(self):
|
||||
return construct_c((self.key.y, self.key.g, self.key.p, self.key.q))
|
||||
|
||||
def can_sign(self):
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
return 0
|
||||
|
||||
def generate_c(bits, randfunc, progress_func=None):
|
||||
obj = generate_py(bits, randfunc, progress_func)
|
||||
y,g,p,q,x = obj.y, obj.g, obj.p, obj.q, obj.x
|
||||
return construct_c((y,g,p,q,x))
|
||||
|
||||
def construct_c(tuple):
|
||||
key = apply(_fastmath.dsa_construct, tuple)
|
||||
return DSAobj_c(key)
|
||||
|
||||
if _fastmath:
|
||||
#print "using C version of DSA"
|
||||
generate = generate_c
|
||||
construct = construct_c
|
||||
error = _fastmath.error
|
132
python/gdata/Crypto/PublicKey/ElGamal.py
Normal file
132
python/gdata/Crypto/PublicKey/ElGamal.py
Normal file
@@ -0,0 +1,132 @@
|
||||
#
|
||||
# ElGamal.py : ElGamal encryption/decryption and signatures
|
||||
#
|
||||
# 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: ElGamal.py,v 1.9 2003/04/04 19:44:26 akuchling Exp $"
|
||||
|
||||
from Crypto.PublicKey.pubkey import *
|
||||
from Crypto.Util import number
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
# Generate an ElGamal key with N bits
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate an ElGamal key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=ElGamalobj()
|
||||
# Generate prime p
|
||||
if progress_func:
|
||||
progress_func('p\n')
|
||||
obj.p=bignum(getPrime(bits, randfunc))
|
||||
# Generate random number g
|
||||
if progress_func:
|
||||
progress_func('g\n')
|
||||
size=bits-1-(ord(randfunc(1)) & 63) # g will be from 1--64 bits smaller than p
|
||||
if size<1:
|
||||
size=bits-1
|
||||
while (1):
|
||||
obj.g=bignum(getPrime(size, randfunc))
|
||||
if obj.g < obj.p:
|
||||
break
|
||||
size=(size+1) % bits
|
||||
if size==0:
|
||||
size=4
|
||||
# Generate random number x
|
||||
if progress_func:
|
||||
progress_func('x\n')
|
||||
while (1):
|
||||
size=bits-1-ord(randfunc(1)) # x will be from 1 to 256 bits smaller than p
|
||||
if size>2:
|
||||
break
|
||||
while (1):
|
||||
obj.x=bignum(getPrime(size, randfunc))
|
||||
if obj.x < obj.p:
|
||||
break
|
||||
size = (size+1) % bits
|
||||
if size==0:
|
||||
size=4
|
||||
if progress_func:
|
||||
progress_func('y\n')
|
||||
obj.y = pow(obj.g, obj.x, obj.p)
|
||||
return obj
|
||||
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)))
|
||||
: ElGamalobj
|
||||
Construct an ElGamal key from a 3- or 4-tuple of numbers.
|
||||
"""
|
||||
|
||||
obj=ElGamalobj()
|
||||
if len(tuple) not in [3,4]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class ElGamalobj(pubkey):
|
||||
keydata=['p', 'g', 'y', 'x']
|
||||
|
||||
def _encrypt(self, M, K):
|
||||
a=pow(self.g, K, self.p)
|
||||
b=( M*pow(self.y, K, self.p) ) % self.p
|
||||
return ( a,b )
|
||||
|
||||
def _decrypt(self, M):
|
||||
if (not hasattr(self, 'x')):
|
||||
raise error, 'Private key not available in this object'
|
||||
ax=pow(M[0], self.x, self.p)
|
||||
plaintext=(M[1] * inverse(ax, self.p ) ) % self.p
|
||||
return plaintext
|
||||
|
||||
def _sign(self, M, K):
|
||||
if (not hasattr(self, 'x')):
|
||||
raise error, 'Private key not available in this object'
|
||||
p1=self.p-1
|
||||
if (GCD(K, p1)!=1):
|
||||
raise error, 'Bad K value: GCD(K,p-1)!=1'
|
||||
a=pow(self.g, K, self.p)
|
||||
t=(M-self.x*a) % p1
|
||||
while t<0: t=t+p1
|
||||
b=(t*inverse(K, p1)) % p1
|
||||
return (a, b)
|
||||
|
||||
def _verify(self, M, sig):
|
||||
v1=pow(self.y, sig[0], self.p)
|
||||
v1=(v1*pow(sig[0], sig[1], self.p)) % self.p
|
||||
v2=pow(self.g, M, self.p)
|
||||
if v1==v2:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return number.size(self.p) - 1
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
if hasattr(self, 'x'):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.p, self.g, self.y))
|
||||
|
||||
|
||||
object=ElGamalobj
|
256
python/gdata/Crypto/PublicKey/RSA.py
Normal file
256
python/gdata/Crypto/PublicKey/RSA.py
Normal file
@@ -0,0 +1,256 @@
|
||||
#
|
||||
# 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 Crypto.PublicKey import pubkey
|
||||
from Crypto.Util import number
|
||||
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
except ImportError:
|
||||
_fastmath = None
|
||||
|
||||
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
python/gdata/Crypto/PublicKey/__init__.py
Normal file
17
python/gdata/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', 'DSA', 'ElGamal', 'qNEW']
|
||||
__revision__ = "$Id: __init__.py,v 1.4 2003/04/03 20:27:13 akuchling Exp $"
|
||||
|
172
python/gdata/Crypto/PublicKey/pubkey.py
Normal file
172
python/gdata/Crypto/PublicKey/pubkey.py
Normal file
@@ -0,0 +1,172 @@
|
||||
#
|
||||
# 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 Crypto.Util.number import *
|
||||
|
||||
# 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__()
|
170
python/gdata/Crypto/PublicKey/qNEW.py
Normal file
170
python/gdata/Crypto/PublicKey/qNEW.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#
|
||||
# qNEW.py : The q-NEW signature algorithm.
|
||||
#
|
||||
# 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: qNEW.py,v 1.8 2003/04/04 15:13:35 akuchling Exp $"
|
||||
|
||||
from Crypto.PublicKey import pubkey
|
||||
from Crypto.Util.number import *
|
||||
from Crypto.Hash import SHA
|
||||
|
||||
class error (Exception):
|
||||
pass
|
||||
|
||||
HASHBITS = 160 # Size of SHA digests
|
||||
|
||||
def generate(bits, randfunc, progress_func=None):
|
||||
"""generate(bits:int, randfunc:callable, progress_func:callable)
|
||||
|
||||
Generate a qNEW key of length 'bits', using 'randfunc' to get
|
||||
random data and 'progress_func', if present, to display
|
||||
the progress of the key generation.
|
||||
"""
|
||||
obj=qNEWobj()
|
||||
|
||||
# Generate prime numbers p and q. q is a 160-bit prime
|
||||
# number. p is another prime number (the modulus) whose bit
|
||||
# size is chosen by the caller, and is generated so that p-1
|
||||
# is a multiple of q.
|
||||
#
|
||||
# Note that only a single seed is used to
|
||||
# generate p and q; if someone generates a key for you, you can
|
||||
# use the seed to duplicate the key generation. This can
|
||||
# protect you from someone generating values of p,q that have
|
||||
# some special form that's easy to break.
|
||||
if progress_func:
|
||||
progress_func('p,q\n')
|
||||
while (1):
|
||||
obj.q = getPrime(160, randfunc)
|
||||
# assert pow(2, 159L)<obj.q<pow(2, 160L)
|
||||
obj.seed = S = long_to_bytes(obj.q)
|
||||
C, N, V = 0, 2, {}
|
||||
# Compute b and n such that bits-1 = b + n*HASHBITS
|
||||
n= (bits-1) / HASHBITS
|
||||
b= (bits-1) % HASHBITS ; powb=2L << b
|
||||
powL1=pow(long(2), bits-1)
|
||||
while C<4096:
|
||||
# The V array will contain (bits-1) bits of random
|
||||
# data, that are assembled to produce a candidate
|
||||
# value for p.
|
||||
for k in range(0, n+1):
|
||||
V[k]=bytes_to_long(SHA.new(S+str(N)+str(k)).digest())
|
||||
p = V[n] % powb
|
||||
for k in range(n-1, -1, -1):
|
||||
p= (p << long(HASHBITS) )+V[k]
|
||||
p = p+powL1 # Ensure the high bit is set
|
||||
|
||||
# Ensure that p-1 is a multiple of q
|
||||
p = p - (p % (2*obj.q)-1)
|
||||
|
||||
# If p is still the right size, and it's prime, we're done!
|
||||
if powL1<=p and isPrime(p):
|
||||
break
|
||||
|
||||
# Otherwise, increment the counter and try again
|
||||
C, N = C+1, N+n+1
|
||||
if C<4096:
|
||||
break # Ended early, so exit the while loop
|
||||
if progress_func:
|
||||
progress_func('4096 values of p tried\n')
|
||||
|
||||
obj.p = p
|
||||
power=(p-1)/obj.q
|
||||
|
||||
# Next parameter: g = h**((p-1)/q) mod p, such that h is any
|
||||
# number <p-1, and g>1. g is kept; h can be discarded.
|
||||
if progress_func:
|
||||
progress_func('h,g\n')
|
||||
while (1):
|
||||
h=bytes_to_long(randfunc(bits)) % (p-1)
|
||||
g=pow(h, power, p)
|
||||
if 1<h<p-1 and g>1:
|
||||
break
|
||||
obj.g=g
|
||||
|
||||
# x is the private key information, and is
|
||||
# just a random number between 0 and q.
|
||||
# y=g**x mod p, and is part of the public information.
|
||||
if progress_func:
|
||||
progress_func('x,y\n')
|
||||
while (1):
|
||||
x=bytes_to_long(randfunc(20))
|
||||
if 0 < x < obj.q:
|
||||
break
|
||||
obj.x, obj.y=x, pow(g, x, p)
|
||||
|
||||
return obj
|
||||
|
||||
# Construct a qNEW object
|
||||
def construct(tuple):
|
||||
"""construct(tuple:(long,long,long,long)|(long,long,long,long,long)
|
||||
Construct a qNEW object from a 4- or 5-tuple of numbers.
|
||||
"""
|
||||
obj=qNEWobj()
|
||||
if len(tuple) not in [4,5]:
|
||||
raise error, 'argument for construct() wrong length'
|
||||
for i in range(len(tuple)):
|
||||
field = obj.keydata[i]
|
||||
setattr(obj, field, tuple[i])
|
||||
return obj
|
||||
|
||||
class qNEWobj(pubkey.pubkey):
|
||||
keydata=['p', 'q', 'g', 'y', 'x']
|
||||
|
||||
def _sign(self, M, K=''):
|
||||
if (self.q<=K):
|
||||
raise error, 'K is greater than q'
|
||||
if M<0:
|
||||
raise error, 'Illegal value of M (<0)'
|
||||
if M>=pow(2,161L):
|
||||
raise error, 'Illegal value of M (too large)'
|
||||
r=pow(self.g, K, self.p) % self.q
|
||||
s=(K- (r*M*self.x % self.q)) % self.q
|
||||
return (r,s)
|
||||
def _verify(self, M, sig):
|
||||
r, s = sig
|
||||
if r<=0 or r>=self.q or s<=0 or s>=self.q:
|
||||
return 0
|
||||
if M<0:
|
||||
raise error, 'Illegal value of M (<0)'
|
||||
if M<=0 or M>=pow(2,161L):
|
||||
return 0
|
||||
v1 = pow(self.g, s, self.p)
|
||||
v2 = pow(self.y, M*r, self.p)
|
||||
v = ((v1*v2) % self.p)
|
||||
v = v % self.q
|
||||
if v==r:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def size(self):
|
||||
"Return the maximum number of bits that can be handled by this key."
|
||||
return 160
|
||||
|
||||
def has_private(self):
|
||||
"""Return a Boolean denoting whether the object contains
|
||||
private components."""
|
||||
return hasattr(self, 'x')
|
||||
|
||||
def can_sign(self):
|
||||
"""Return a Boolean value recording whether this algorithm can generate signatures."""
|
||||
return 1
|
||||
|
||||
def can_encrypt(self):
|
||||
"""Return a Boolean value recording whether this algorithm can encrypt data."""
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
"""Return a new key object containing only the public information."""
|
||||
return construct((self.p, self.q, self.g, self.y))
|
||||
|
||||
object = qNEWobj
|
||||
|
Reference in New Issue
Block a user