home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- __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
-
- 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()
- if progress_func:
- progress_func('p,q\n')
-
- while None:
- obj.q = getPrime(160, randfunc)
- obj.seed = S = long_to_bytes(obj.q)
- C = 0
- N = 2
- V = { }
- n = (bits - 1) / HASHBITS
- b = (bits - 1) % HASHBITS
- powb = 0x2L << b
- powL1 = pow(long(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())
-
- p = V[n] % powb
- for k in range(n - 1, -1, -1):
- p = (p << long(HASHBITS)) + V[k]
-
- p = p + powL1
- p = p - p % 2 * obj.q - 1
- if powL1 <= p and isPrime(p):
- break
-
- C = C + 1
- N = N + n + 1
- if C < 4096:
- break
-
- if progress_func:
- progress_func('4096 values of p tried\n')
- continue
- continue
- obj.p = p
- power = (p - 1) / obj.q
- if progress_func:
- progress_func('h,g\n')
-
- while None:
- h = bytes_to_long(randfunc(bits)) % (p - 1)
- g = pow(h, power, p)
- if h < h:
- pass
- elif h < p - 1 and g > 1:
- break
- continue
- continue
- obj.g = g
- if progress_func:
- progress_func('x,y\n')
-
- while None:
- x = bytes_to_long(randfunc(20))
- if x < x:
- pass
- elif x < obj.q:
- break
- continue
- continue
- obj.x = x
- obj.y = pow(g, x, p)
- return obj
-
-
- 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'
- len(tuple) not in (4, 5)
- 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'
- self.q <= K
- if M < 0:
- raise error, 'Illegal value of M (<0)'
- M < 0
- if M >= pow(2, 0xA1L):
- raise error, 'Illegal value of M (too large)'
- M >= pow(2, 0xA1L)
- 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 and r >= self.q and s <= 0 or s >= self.q:
- return 0
- if M < 0:
- raise error, 'Illegal value of M (<0)'
- M < 0
- if M <= 0 or M >= pow(2, 0xA1L):
- 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
-