/gdata/Crypto/PublicKey/DSA.py

http://radioappz.googlecode.com/ · Python · 238 lines · 218 code · 7 blank · 13 comment · 9 complexity · da684ba5019f44e61a05f79af8089e9e MD5 · raw file

  1. #
  2. # DSA.py : Digital Signature Algorithm
  3. #
  4. # Part of the Python Cryptography Toolkit
  5. #
  6. # Distribute and use freely; there are no restrictions on further
  7. # dissemination and usage except those imposed by the laws of your
  8. # country of residence. This software is provided "as is" without
  9. # warranty of fitness for use or suitability for any purpose, express
  10. # or implied. Use at your own risk or not at all.
  11. #
  12. __revision__ = "$Id: DSA.py,v 1.16 2004/05/06 12:52:54 akuchling Exp $"
  13. from Crypto.PublicKey.pubkey import *
  14. from Crypto.Util import number
  15. from Crypto.Util.number import bytes_to_long, long_to_bytes
  16. from Crypto.Hash import SHA
  17. try:
  18. from Crypto.PublicKey import _fastmath
  19. except ImportError:
  20. _fastmath = None
  21. class error (Exception):
  22. pass
  23. def generateQ(randfunc):
  24. S=randfunc(20)
  25. hash1=SHA.new(S).digest()
  26. hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest()
  27. q = bignum(0)
  28. for i in range(0,20):
  29. c=ord(hash1[i])^ord(hash2[i])
  30. if i==0:
  31. c=c | 128
  32. if i==19:
  33. c= c | 1
  34. q=q*256+c
  35. while (not isPrime(q)):
  36. q=q+2
  37. if pow(2,159L) < q < pow(2,160L):
  38. return S, q
  39. raise error, 'Bad q value generated'
  40. def generate(bits, randfunc, progress_func=None):
  41. """generate(bits:int, randfunc:callable, progress_func:callable)
  42. Generate a DSA key of length 'bits', using 'randfunc' to get
  43. random data and 'progress_func', if present, to display
  44. the progress of the key generation.
  45. """
  46. if bits<160:
  47. raise error, 'Key length <160 bits'
  48. obj=DSAobj()
  49. # Generate string S and prime q
  50. if progress_func:
  51. progress_func('p,q\n')
  52. while (1):
  53. S, obj.q = generateQ(randfunc)
  54. n=(bits-1)/160
  55. C, N, V = 0, 2, {}
  56. b=(obj.q >> 5) & 15
  57. powb=pow(bignum(2), b)
  58. powL1=pow(bignum(2), bits-1)
  59. while C<4096:
  60. for k in range(0, n+1):
  61. V[k]=bytes_to_long(SHA.new(S+str(N)+str(k)).digest())
  62. W=V[n] % powb
  63. for k in range(n-1, -1, -1):
  64. W=(W<<160L)+V[k]
  65. X=W+powL1
  66. p=X-(X%(2*obj.q)-1)
  67. if powL1<=p and isPrime(p):
  68. break
  69. C, N = C+1, N+n+1
  70. if C<4096:
  71. break
  72. if progress_func:
  73. progress_func('4096 multiples failed\n')
  74. obj.p = p
  75. power=(p-1)/obj.q
  76. if progress_func:
  77. progress_func('h,g\n')
  78. while (1):
  79. h=bytes_to_long(randfunc(bits)) % (p-1)
  80. g=pow(h, power, p)
  81. if 1<h<p-1 and g>1:
  82. break
  83. obj.g=g
  84. if progress_func:
  85. progress_func('x,y\n')
  86. while (1):
  87. x=bytes_to_long(randfunc(20))
  88. if 0 < x < obj.q:
  89. break
  90. obj.x, obj.y = x, pow(g, x, p)
  91. return obj
  92. def construct(tuple):
  93. """construct(tuple:(long,long,long,long)|(long,long,long,long,long)):DSAobj
  94. Construct a DSA object from a 4- or 5-tuple of numbers.
  95. """
  96. obj=DSAobj()
  97. if len(tuple) not in [4,5]:
  98. raise error, 'argument for construct() wrong length'
  99. for i in range(len(tuple)):
  100. field = obj.keydata[i]
  101. setattr(obj, field, tuple[i])
  102. return obj
  103. class DSAobj(pubkey):
  104. keydata=['y', 'g', 'p', 'q', 'x']
  105. def _encrypt(self, s, Kstr):
  106. raise error, 'DSA algorithm cannot encrypt data'
  107. def _decrypt(self, s):
  108. raise error, 'DSA algorithm cannot decrypt data'
  109. def _sign(self, M, K):
  110. if (K<2 or self.q<=K):
  111. raise error, 'K is not between 2 and q'
  112. r=pow(self.g, K, self.p) % self.q
  113. s=(inverse(K, self.q)*(M+self.x*r)) % self.q
  114. return (r,s)
  115. def _verify(self, M, sig):
  116. r, s = sig
  117. if r<=0 or r>=self.q or s<=0 or s>=self.q:
  118. return 0
  119. w=inverse(s, self.q)
  120. u1, u2 = (M*w) % self.q, (r*w) % self.q
  121. v1 = pow(self.g, u1, self.p)
  122. v2 = pow(self.y, u2, self.p)
  123. v = ((v1*v2) % self.p)
  124. v = v % self.q
  125. if v==r:
  126. return 1
  127. return 0
  128. def size(self):
  129. "Return the maximum number of bits that can be handled by this key."
  130. return number.size(self.p) - 1
  131. def has_private(self):
  132. """Return a Boolean denoting whether the object contains
  133. private components."""
  134. if hasattr(self, 'x'):
  135. return 1
  136. else:
  137. return 0
  138. def can_sign(self):
  139. """Return a Boolean value recording whether this algorithm can generate signatures."""
  140. return 1
  141. def can_encrypt(self):
  142. """Return a Boolean value recording whether this algorithm can encrypt data."""
  143. return 0
  144. def publickey(self):
  145. """Return a new key object containing only the public information."""
  146. return construct((self.y, self.g, self.p, self.q))
  147. object=DSAobj
  148. generate_py = generate
  149. construct_py = construct
  150. class DSAobj_c(pubkey):
  151. keydata = ['y', 'g', 'p', 'q', 'x']
  152. def __init__(self, key):
  153. self.key = key
  154. def __getattr__(self, attr):
  155. if attr in self.keydata:
  156. return getattr(self.key, attr)
  157. else:
  158. if self.__dict__.has_key(attr):
  159. self.__dict__[attr]
  160. else:
  161. raise AttributeError, '%s instance has no attribute %s' % (self.__class__, attr)
  162. def __getstate__(self):
  163. d = {}
  164. for k in self.keydata:
  165. if hasattr(self.key, k):
  166. d[k]=getattr(self.key, k)
  167. return d
  168. def __setstate__(self, state):
  169. y,g,p,q = state['y'], state['g'], state['p'], state['q']
  170. if not state.has_key('x'):
  171. self.key = _fastmath.dsa_construct(y,g,p,q)
  172. else:
  173. x = state['x']
  174. self.key = _fastmath.dsa_construct(y,g,p,q,x)
  175. def _sign(self, M, K):
  176. return self.key._sign(M, K)
  177. def _verify(self, M, (r, s)):
  178. return self.key._verify(M, r, s)
  179. def size(self):
  180. return self.key.size()
  181. def has_private(self):
  182. return self.key.has_private()
  183. def publickey(self):
  184. return construct_c((self.key.y, self.key.g, self.key.p, self.key.q))
  185. def can_sign(self):
  186. return 1
  187. def can_encrypt(self):
  188. return 0
  189. def generate_c(bits, randfunc, progress_func=None):
  190. obj = generate_py(bits, randfunc, progress_func)
  191. y,g,p,q,x = obj.y, obj.g, obj.p, obj.q, obj.x
  192. return construct_c((y,g,p,q,x))
  193. def construct_c(tuple):
  194. key = apply(_fastmath.dsa_construct, tuple)
  195. return DSAobj_c(key)
  196. if _fastmath:
  197. #print "using C version of DSA"
  198. generate = generate_c
  199. construct = construct_c
  200. error = _fastmath.error