_elliptic_curve.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. # coding: utf-8
  2. """
  3. Classes and objects to represent prime-field elliptic curves and points on them.
  4. Exports the following items:
  5. - PrimeCurve()
  6. - PrimePoint()
  7. - SECP192R1_CURVE
  8. - SECP192R1_BASE_POINT
  9. - SECP224R1_CURVE
  10. - SECP224R1_BASE_POINT
  11. - SECP256R1_CURVE
  12. - SECP256R1_BASE_POINT
  13. - SECP384R1_CURVE
  14. - SECP384R1_BASE_POINT
  15. - SECP521R1_CURVE
  16. - SECP521R1_BASE_POINT
  17. The curve constants are all PrimeCurve() objects and the base point constants
  18. are all PrimePoint() objects.
  19. Some of the following source code is derived from
  20. http://webpages.charter.net/curryfans/peter/downloads.html, but has been heavily
  21. modified to fit into this projects lint settings. The original project license
  22. is listed below:
  23. Copyright (c) 2014 Peter Pearson
  24. Permission is hereby granted, free of charge, to any person obtaining a copy
  25. of this software and associated documentation files (the "Software"), to deal
  26. in the Software without restriction, including without limitation the rights
  27. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  28. copies of the Software, and to permit persons to whom the Software is
  29. furnished to do so, subject to the following conditions:
  30. The above copyright notice and this permission notice shall be included in
  31. all copies or substantial portions of the Software.
  32. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  33. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  34. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  35. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  36. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  37. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  38. THE SOFTWARE.
  39. """
  40. from __future__ import unicode_literals, division, absolute_import, print_function
  41. from ._int import inverse_mod
  42. class PrimeCurve():
  43. """
  44. Elliptic curve over a prime field. Characteristic two field curves are not
  45. supported.
  46. """
  47. def __init__(self, p, a, b):
  48. """
  49. The curve of points satisfying y^2 = x^3 + a*x + b (mod p)
  50. :param p:
  51. The prime number as an integer
  52. :param a:
  53. The component a as an integer
  54. :param b:
  55. The component b as an integer
  56. """
  57. self.p = p
  58. self.a = a
  59. self.b = b
  60. def contains(self, point):
  61. """
  62. :param point:
  63. A Point object
  64. :return:
  65. Boolean if the point is on this curve
  66. """
  67. y2 = point.y * point.y
  68. x3 = point.x * point.x * point.x
  69. return (y2 - (x3 + self.a * point.x + self.b)) % self.p == 0
  70. class PrimePoint():
  71. """
  72. A point on a prime-field elliptic curve
  73. """
  74. def __init__(self, curve, x, y, order=None):
  75. """
  76. :param curve:
  77. A PrimeCurve object
  78. :param x:
  79. The x coordinate of the point as an integer
  80. :param y:
  81. The y coordinate of the point as an integer
  82. :param order:
  83. The order of the point, as an integer - optional
  84. """
  85. self.curve = curve
  86. self.x = x
  87. self.y = y
  88. self.order = order
  89. # self.curve is allowed to be None only for INFINITY:
  90. if self.curve:
  91. if not self.curve.contains(self):
  92. raise ValueError('Invalid EC point')
  93. if self.order:
  94. if self * self.order != INFINITY:
  95. raise ValueError('Invalid EC point')
  96. def __cmp__(self, other):
  97. """
  98. :param other:
  99. A PrimePoint object
  100. :return:
  101. 0 if identical, 1 otherwise
  102. """
  103. if self.curve == other.curve and self.x == other.x and self.y == other.y:
  104. return 0
  105. else:
  106. return 1
  107. def __add__(self, other):
  108. """
  109. :param other:
  110. A PrimePoint object
  111. :return:
  112. A PrimePoint object
  113. """
  114. # X9.62 B.3:
  115. if other == INFINITY:
  116. return self
  117. if self == INFINITY:
  118. return other
  119. assert self.curve == other.curve
  120. if self.x == other.x:
  121. if (self.y + other.y) % self.curve.p == 0:
  122. return INFINITY
  123. else:
  124. return self.double()
  125. p = self.curve.p
  126. l = ((other.y - self.y) * inverse_mod(other.x - self.x, p)) % p
  127. x3 = (l * l - self.x - other.x) % p
  128. y3 = (l * (self.x - x3) - self.y) % p
  129. return PrimePoint(self.curve, x3, y3)
  130. def __mul__(self, other):
  131. """
  132. :param other:
  133. An integer to multiple the Point by
  134. :return:
  135. A PrimePoint object
  136. """
  137. def leftmost_bit(x):
  138. assert x > 0
  139. result = 1
  140. while result <= x:
  141. result = 2 * result
  142. return result // 2
  143. e = other
  144. if self.order:
  145. e = e % self.order
  146. if e == 0:
  147. return INFINITY
  148. if self == INFINITY:
  149. return INFINITY
  150. assert e > 0
  151. # From X9.62 D.3.2:
  152. e3 = 3 * e
  153. negative_self = PrimePoint(self.curve, self.x, -self.y, self.order)
  154. i = leftmost_bit(e3) // 2
  155. result = self
  156. # print "Multiplying %s by %d (e3 = %d):" % ( self, other, e3 )
  157. while i > 1:
  158. result = result.double()
  159. if (e3 & i) != 0 and (e & i) == 0:
  160. result = result + self
  161. if (e3 & i) == 0 and (e & i) != 0:
  162. result = result + negative_self
  163. # print ". . . i = %d, result = %s" % ( i, result )
  164. i = i // 2
  165. return result
  166. def __rmul__(self, other):
  167. """
  168. :param other:
  169. An integer to multiple the Point by
  170. :return:
  171. A PrimePoint object
  172. """
  173. return self * other
  174. def double(self):
  175. """
  176. :return:
  177. A PrimePoint object that is twice this point
  178. """
  179. # X9.62 B.3:
  180. p = self.curve.p
  181. a = self.curve.a
  182. l = ((3 * self.x * self.x + a) * inverse_mod(2 * self.y, p)) % p
  183. x3 = (l * l - 2 * self.x) % p
  184. y3 = (l * (self.x - x3) - self.y) % p
  185. return PrimePoint(self.curve, x3, y3)
  186. # This one point is the Point At Infinity for all purposes:
  187. INFINITY = PrimePoint(None, None, None)
  188. # NIST Curve P-192:
  189. SECP192R1_CURVE = PrimeCurve(
  190. 6277101735386680763835789423207666416083908700390324961279,
  191. -3,
  192. 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
  193. )
  194. SECP192R1_BASE_POINT = PrimePoint(
  195. SECP192R1_CURVE,
  196. 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012,
  197. 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811,
  198. 6277101735386680763835789423176059013767194773182842284081
  199. )
  200. # NIST Curve P-224:
  201. SECP224R1_CURVE = PrimeCurve(
  202. 26959946667150639794667015087019630673557916260026308143510066298881,
  203. -3,
  204. 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
  205. )
  206. SECP224R1_BASE_POINT = PrimePoint(
  207. SECP224R1_CURVE,
  208. 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21,
  209. 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34,
  210. 26959946667150639794667015087019625940457807714424391721682722368061
  211. )
  212. # NIST Curve P-256:
  213. SECP256R1_CURVE = PrimeCurve(
  214. 115792089210356248762697446949407573530086143415290314195533631308867097853951,
  215. -3,
  216. 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
  217. )
  218. SECP256R1_BASE_POINT = PrimePoint(
  219. SECP256R1_CURVE,
  220. 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
  221. 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5,
  222. 115792089210356248762697446949407573529996955224135760342422259061068512044369
  223. )
  224. # NIST Curve P-384:
  225. SECP384R1_CURVE = PrimeCurve(
  226. 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319, # noqa
  227. -3,
  228. 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
  229. )
  230. SECP384R1_BASE_POINT = PrimePoint(
  231. SECP384R1_CURVE,
  232. 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7,
  233. 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f,
  234. 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
  235. )
  236. # NIST Curve P-521:
  237. SECP521R1_CURVE = PrimeCurve(
  238. 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151, # noqa
  239. -3,
  240. 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 # noqa
  241. )
  242. SECP521R1_BASE_POINT = PrimePoint(
  243. SECP521R1_CURVE,
  244. 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66, # noqa
  245. 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650, # noqa
  246. 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449 # noqa
  247. )