_DSA.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #
  2. # DSA.py : Digital Signature Algorithm
  3. #
  4. # Part of the Python Cryptography Toolkit
  5. #
  6. # Written by Andrew Kuchling, Paul Swartz, and others
  7. #
  8. # ===================================================================
  9. # The contents of this file are dedicated to the public domain. To
  10. # the extent that dedication to the public domain is not available,
  11. # everyone is granted a worldwide, perpetual, royalty-free,
  12. # non-exclusive license to exercise all rights associated with the
  13. # contents of this file for any purpose whatsoever.
  14. # No rights are reserved.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  20. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. # SOFTWARE.
  24. # ===================================================================
  25. #
  26. __revision__ = "$Id$"
  27. from Crypto.PublicKey.pubkey import *
  28. from Crypto.Util import number
  29. from Crypto.Util.number import bytes_to_long, long_to_bytes
  30. from Crypto.Hash import SHA
  31. from Crypto.Util.py3compat import *
  32. class error (Exception):
  33. pass
  34. def generateQ(randfunc):
  35. S=randfunc(20)
  36. hash1=SHA.new(S).digest()
  37. hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest()
  38. q = bignum(0)
  39. for i in range(0,20):
  40. c=bord(hash1[i])^bord(hash2[i])
  41. if i==0:
  42. c=c | 128
  43. if i==19:
  44. c= c | 1
  45. q=q*256+c
  46. while (not isPrime(q)):
  47. q=q+2
  48. if pow(2,159L) < q < pow(2,160L):
  49. return S, q
  50. raise RuntimeError('Bad q value generated')
  51. def generate_py(bits, randfunc, progress_func=None):
  52. """generate(bits:int, randfunc:callable, progress_func:callable)
  53. Generate a DSA key of length 'bits', using 'randfunc' to get
  54. random data and 'progress_func', if present, to display
  55. the progress of the key generation.
  56. """
  57. if bits<160:
  58. raise ValueError('Key length < 160 bits')
  59. obj=DSAobj()
  60. # Generate string S and prime q
  61. if progress_func:
  62. progress_func('p,q\n')
  63. while (1):
  64. S, obj.q = generateQ(randfunc)
  65. n=divmod(bits-1, 160)[0]
  66. C, N, V = 0, 2, {}
  67. b=(obj.q >> 5) & 15
  68. powb=pow(bignum(2), b)
  69. powL1=pow(bignum(2), bits-1)
  70. while C<4096:
  71. for k in range(0, n+1):
  72. V[k]=bytes_to_long(SHA.new(S+bstr(N)+bstr(k)).digest())
  73. W=V[n] % powb
  74. for k in range(n-1, -1, -1):
  75. W=(W<<160L)+V[k]
  76. X=W+powL1
  77. p=X-(X%(2*obj.q)-1)
  78. if powL1<=p and isPrime(p):
  79. break
  80. C, N = C+1, N+n+1
  81. if C<4096:
  82. break
  83. if progress_func:
  84. progress_func('4096 multiples failed\n')
  85. obj.p = p
  86. power=divmod(p-1, obj.q)[0]
  87. if progress_func:
  88. progress_func('h,g\n')
  89. while (1):
  90. h=bytes_to_long(randfunc(bits)) % (p-1)
  91. g=pow(h, power, p)
  92. if 1<h<p-1 and g>1:
  93. break
  94. obj.g=g
  95. if progress_func:
  96. progress_func('x,y\n')
  97. while (1):
  98. x=bytes_to_long(randfunc(20))
  99. if 0 < x < obj.q:
  100. break
  101. obj.x, obj.y = x, pow(g, x, p)
  102. return obj
  103. class DSAobj:
  104. pass