_nist_ecc.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. # This file is licensed under the BSD 2-Clause License.
  2. # See https://opensource.org/licenses/BSD-2-Clause for details.
  3. from ._curve import _Curve
  4. from Crypto.Math.Numbers import Integer
  5. from Crypto.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
  6. SmartPointer, c_size_t, c_uint8_ptr,
  7. c_ulonglong)
  8. from Crypto.Util.number import long_to_bytes
  9. from Crypto.Random.random import getrandbits
  10. _ec_lib = load_pycryptodome_raw_lib("Crypto.PublicKey._ec_ws", """
  11. typedef void EcContext;
  12. typedef void EcPoint;
  13. int ec_ws_new_context(EcContext **pec_ctx,
  14. const uint8_t *modulus,
  15. const uint8_t *b,
  16. const uint8_t *order,
  17. size_t len,
  18. uint64_t seed);
  19. void ec_ws_free_context(EcContext *ec_ctx);
  20. int ec_ws_new_point(EcPoint **pecp,
  21. const uint8_t *x,
  22. const uint8_t *y,
  23. size_t len,
  24. const EcContext *ec_ctx);
  25. void ec_ws_free_point(EcPoint *ecp);
  26. int ec_ws_get_xy(uint8_t *x,
  27. uint8_t *y,
  28. size_t len,
  29. const EcPoint *ecp);
  30. int ec_ws_double(EcPoint *p);
  31. int ec_ws_add(EcPoint *ecpa, EcPoint *ecpb);
  32. int ec_ws_scalar(EcPoint *ecp,
  33. const uint8_t *k,
  34. size_t len,
  35. uint64_t seed);
  36. int ec_ws_clone(EcPoint **pecp2, const EcPoint *ecp);
  37. int ec_ws_cmp(const EcPoint *ecp1, const EcPoint *ecp2);
  38. int ec_ws_neg(EcPoint *p);
  39. """)
  40. class EcLib(object):
  41. new_context = _ec_lib.ec_ws_new_context
  42. free_context = _ec_lib.ec_ws_free_context
  43. new_point = _ec_lib.ec_ws_new_point
  44. free_point = _ec_lib.ec_ws_free_point
  45. get_xy = _ec_lib.ec_ws_get_xy
  46. double = _ec_lib.ec_ws_double
  47. add = _ec_lib.ec_ws_add
  48. scalar = _ec_lib.ec_ws_scalar
  49. clone = _ec_lib.ec_ws_clone
  50. cmp = _ec_lib.ec_ws_cmp
  51. neg = _ec_lib.ec_ws_neg
  52. def p192_curve():
  53. p = 0xfffffffffffffffffffffffffffffffeffffffffffffffff
  54. b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
  55. order = 0xffffffffffffffffffffffff99def836146bc9b1b4d22831
  56. Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
  57. Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
  58. p192_modulus = long_to_bytes(p, 24)
  59. p192_b = long_to_bytes(b, 24)
  60. p192_order = long_to_bytes(order, 24)
  61. ec_p192_context = VoidPointer()
  62. result = _ec_lib.ec_ws_new_context(ec_p192_context.address_of(),
  63. c_uint8_ptr(p192_modulus),
  64. c_uint8_ptr(p192_b),
  65. c_uint8_ptr(p192_order),
  66. c_size_t(len(p192_modulus)),
  67. c_ulonglong(getrandbits(64))
  68. )
  69. if result:
  70. raise ImportError("Error %d initializing P-192 context" % result)
  71. context = SmartPointer(ec_p192_context.get(), _ec_lib.ec_ws_free_context)
  72. p192 = _Curve(Integer(p),
  73. Integer(b),
  74. Integer(order),
  75. Integer(Gx),
  76. Integer(Gy),
  77. None,
  78. 192,
  79. "1.2.840.10045.3.1.1", # ANSI X9.62 / SEC2
  80. context,
  81. "NIST P-192",
  82. "ecdsa-sha2-nistp192",
  83. EcLib)
  84. return p192
  85. def p224_curve():
  86. p = 0xffffffffffffffffffffffffffffffff000000000000000000000001
  87. b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
  88. order = 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d
  89. Gx = 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
  90. Gy = 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34
  91. p224_modulus = long_to_bytes(p, 28)
  92. p224_b = long_to_bytes(b, 28)
  93. p224_order = long_to_bytes(order, 28)
  94. ec_p224_context = VoidPointer()
  95. result = _ec_lib.ec_ws_new_context(ec_p224_context.address_of(),
  96. c_uint8_ptr(p224_modulus),
  97. c_uint8_ptr(p224_b),
  98. c_uint8_ptr(p224_order),
  99. c_size_t(len(p224_modulus)),
  100. c_ulonglong(getrandbits(64))
  101. )
  102. if result:
  103. raise ImportError("Error %d initializing P-224 context" % result)
  104. context = SmartPointer(ec_p224_context.get(), _ec_lib.ec_ws_free_context)
  105. p224 = _Curve(Integer(p),
  106. Integer(b),
  107. Integer(order),
  108. Integer(Gx),
  109. Integer(Gy),
  110. None,
  111. 224,
  112. "1.3.132.0.33", # SEC 2
  113. context,
  114. "NIST P-224",
  115. "ecdsa-sha2-nistp224",
  116. EcLib)
  117. return p224
  118. def p256_curve():
  119. p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
  120. b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
  121. order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
  122. Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
  123. Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
  124. p256_modulus = long_to_bytes(p, 32)
  125. p256_b = long_to_bytes(b, 32)
  126. p256_order = long_to_bytes(order, 32)
  127. ec_p256_context = VoidPointer()
  128. result = _ec_lib.ec_ws_new_context(ec_p256_context.address_of(),
  129. c_uint8_ptr(p256_modulus),
  130. c_uint8_ptr(p256_b),
  131. c_uint8_ptr(p256_order),
  132. c_size_t(len(p256_modulus)),
  133. c_ulonglong(getrandbits(64))
  134. )
  135. if result:
  136. raise ImportError("Error %d initializing P-256 context" % result)
  137. context = SmartPointer(ec_p256_context.get(), _ec_lib.ec_ws_free_context)
  138. p256 = _Curve(Integer(p),
  139. Integer(b),
  140. Integer(order),
  141. Integer(Gx),
  142. Integer(Gy),
  143. None,
  144. 256,
  145. "1.2.840.10045.3.1.7", # ANSI X9.62 / SEC2
  146. context,
  147. "NIST P-256",
  148. "ecdsa-sha2-nistp256",
  149. EcLib)
  150. return p256
  151. def p384_curve():
  152. p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff
  153. b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
  154. order = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973
  155. Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7
  156. Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5F
  157. p384_modulus = long_to_bytes(p, 48)
  158. p384_b = long_to_bytes(b, 48)
  159. p384_order = long_to_bytes(order, 48)
  160. ec_p384_context = VoidPointer()
  161. result = _ec_lib.ec_ws_new_context(ec_p384_context.address_of(),
  162. c_uint8_ptr(p384_modulus),
  163. c_uint8_ptr(p384_b),
  164. c_uint8_ptr(p384_order),
  165. c_size_t(len(p384_modulus)),
  166. c_ulonglong(getrandbits(64))
  167. )
  168. if result:
  169. raise ImportError("Error %d initializing P-384 context" % result)
  170. context = SmartPointer(ec_p384_context.get(), _ec_lib.ec_ws_free_context)
  171. p384 = _Curve(Integer(p),
  172. Integer(b),
  173. Integer(order),
  174. Integer(Gx),
  175. Integer(Gy),
  176. None,
  177. 384,
  178. "1.3.132.0.34", # SEC 2
  179. context,
  180. "NIST P-384",
  181. "ecdsa-sha2-nistp384",
  182. EcLib)
  183. return p384
  184. def p521_curve():
  185. p = 0x000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  186. b = 0x00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
  187. order = 0x000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409
  188. Gx = 0x000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
  189. Gy = 0x0000011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
  190. p521_modulus = long_to_bytes(p, 66)
  191. p521_b = long_to_bytes(b, 66)
  192. p521_order = long_to_bytes(order, 66)
  193. ec_p521_context = VoidPointer()
  194. result = _ec_lib.ec_ws_new_context(ec_p521_context.address_of(),
  195. c_uint8_ptr(p521_modulus),
  196. c_uint8_ptr(p521_b),
  197. c_uint8_ptr(p521_order),
  198. c_size_t(len(p521_modulus)),
  199. c_ulonglong(getrandbits(64))
  200. )
  201. if result:
  202. raise ImportError("Error %d initializing P-521 context" % result)
  203. context = SmartPointer(ec_p521_context.get(), _ec_lib.ec_ws_free_context)
  204. p521 = _Curve(Integer(p),
  205. Integer(b),
  206. Integer(order),
  207. Integer(Gx),
  208. Integer(Gy),
  209. None,
  210. 521,
  211. "1.3.132.0.35", # SEC 2
  212. context,
  213. "NIST P-521",
  214. "ecdsa-sha2-nistp521",
  215. EcLib)
  216. return p521