No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

114 líneas
2.8 KiB

  1. """
  2. RFC 6979:
  3. Deterministic Usage of the Digital Signature Algorithm (DSA) and
  4. Elliptic Curve Digital Signature Algorithm (ECDSA)
  5. http://tools.ietf.org/html/rfc6979
  6. Many thanks to Coda Hale for his implementation in Go language:
  7. https://github.com/codahale/rfc6979
  8. """
  9. import hmac
  10. from binascii import hexlify
  11. from .util import number_to_string, number_to_string_crop, bit_length
  12. from ._compat import hmac_compat
  13. # bit_length was defined in this module previously so keep it for backwards
  14. # compatibility, will need to deprecate and remove it later
  15. __all__ = ["bit_length", "bits2int", "bits2octets", "generate_k"]
  16. def bits2int(data, qlen):
  17. x = int(hexlify(data), 16)
  18. l = len(data) * 8
  19. if l > qlen:
  20. return x >> (l - qlen)
  21. return x
  22. def bits2octets(data, order):
  23. z1 = bits2int(data, bit_length(order))
  24. z2 = z1 - order
  25. if z2 < 0:
  26. z2 = z1
  27. return number_to_string_crop(z2, order)
  28. # https://tools.ietf.org/html/rfc6979#section-3.2
  29. def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b""):
  30. """
  31. Generate the ``k`` value - the nonce for DSA.
  32. :param int order: order of the DSA generator used in the signature
  33. :param int secexp: secure exponent (private key) in numeric form
  34. :param hash_func: reference to the same hash function used for generating
  35. hash, like :py:class:`hashlib.sha1`
  36. :param bytes data: hash in binary form of the signing data
  37. :param int retry_gen: how many good 'k' values to skip before returning
  38. :param bytes extra_entropy: additional added data in binary form as per
  39. section-3.6 of rfc6979
  40. :rtype: int
  41. """
  42. qlen = bit_length(order)
  43. holen = hash_func().digest_size
  44. rolen = (qlen + 7) // 8
  45. bx = (
  46. hmac_compat(number_to_string(secexp, order)),
  47. hmac_compat(bits2octets(data, order)),
  48. hmac_compat(extra_entropy),
  49. )
  50. # Step B
  51. v = b"\x01" * holen
  52. # Step C
  53. k = b"\x00" * holen
  54. # Step D
  55. k = hmac.new(k, digestmod=hash_func)
  56. k.update(v + b"\x00")
  57. for i in bx:
  58. k.update(i)
  59. k = k.digest()
  60. # Step E
  61. v = hmac.new(k, v, hash_func).digest()
  62. # Step F
  63. k = hmac.new(k, digestmod=hash_func)
  64. k.update(v + b"\x01")
  65. for i in bx:
  66. k.update(i)
  67. k = k.digest()
  68. # Step G
  69. v = hmac.new(k, v, hash_func).digest()
  70. # Step H
  71. while True:
  72. # Step H1
  73. t = b""
  74. # Step H2
  75. while len(t) < rolen:
  76. v = hmac.new(k, v, hash_func).digest()
  77. t += v
  78. # Step H3
  79. secret = bits2int(t, qlen)
  80. if 1 <= secret < order:
  81. if retry_gen <= 0:
  82. return secret
  83. retry_gen -= 1
  84. k = hmac.new(k, v + b"\x00", hash_func).digest()
  85. v = hmac.new(k, v, hash_func).digest()