fork(1) download
  1. #! /usr/bin/env python
  2.  
  3. import random
  4.  
  5. class CurveFp( object ):
  6. def __init__( self, p, a, b ):
  7. self.__p = p
  8. self.__a = a
  9. self.__b = b
  10.  
  11. def p( self ):
  12. return self.__p
  13.  
  14. def a( self ):
  15. return self.__a
  16.  
  17. def b( self ):
  18. return self.__b
  19.  
  20. def contains_point( self, x, y ):
  21. return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
  22.  
  23. class Point( object ):
  24. def __init__( self, curve, x, y, order = None ):
  25. self.__curve = curve
  26. self.__x = x
  27. self.__y = y
  28. self.__order = order
  29. if self.__curve: assert self.__curve.contains_point( x, y )
  30. if order: assert self * order == INFINITY
  31.  
  32. def __add__( self, other ):
  33. if other == INFINITY: return self
  34. if self == INFINITY: return other
  35. assert self.__curve == other.__curve
  36. if self.__x == other.__x:
  37. if ( self.__y + other.__y ) % self.__curve.p() == 0:
  38. return INFINITY
  39. else:
  40. return self.double()
  41.  
  42. p = self.__curve.p()
  43. l = ( ( other.__y - self.__y ) * \
  44. inverse_mod( other.__x - self.__x, p ) ) % p
  45. x3 = ( l * l - self.__x - other.__x ) % p
  46. y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  47. return Point( self.__curve, x3, y3 )
  48.  
  49. def __mul__( self, other ):
  50. def leftmost_bit( x ):
  51. assert x > 0
  52. result = 1L
  53. while result <= x: result = 2 * result
  54. return result / 2
  55.  
  56. e = other
  57. if self.__order: e = e % self.__order
  58. if e == 0: return INFINITY
  59. if self == INFINITY: return INFINITY
  60. assert e > 0
  61. e3 = 3 * e
  62. negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
  63. i = leftmost_bit( e3 ) / 2
  64. result = self
  65. while i > 1:
  66. result = result.double()
  67. if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
  68. if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
  69. i = i / 2
  70. return result
  71.  
  72. def __rmul__( self, other ):
  73. return self * other
  74.  
  75. def __str__( self ):
  76. if self == INFINITY: return "infinity"
  77. return "(%d,%d)" % ( self.__x, self.__y )
  78.  
  79. def double( self ):
  80. if self == INFINITY:
  81. return INFINITY
  82.  
  83. p = self.__curve.p()
  84. a = self.__curve.a()
  85. l = ( ( 3 * self.__x * self.__x + a ) * \
  86. inverse_mod( 2 * self.__y, p ) ) % p
  87. x3 = ( l * l - 2 * self.__x ) % p
  88. y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  89. return Point( self.__curve, x3, y3 )
  90.  
  91. def x( self ):
  92. return self.__x
  93.  
  94. def y( self ):
  95. return self.__y
  96.  
  97. def curve( self ):
  98. return self.__curve
  99.  
  100. def order( self ):
  101. return self.__order
  102.  
  103. INFINITY = Point( None, None, None )
  104.  
  105. def inverse_mod( a, m ):
  106. if a < 0 or m <= a: a = a % m
  107. c, d = a, m
  108. uc, vc, ud, vd = 1, 0, 0, 1
  109. while c != 0:
  110. q, c, d = divmod( d, c ) + ( c, )
  111. uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
  112. assert d == 1
  113. if ud > 0: return ud
  114. else: return ud + m
  115.  
  116.  
  117. _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
  118. _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
  119. _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
  120. _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
  121. _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
  122. _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  123.  
  124. class Signature( object ):
  125. def __init__( self, r, s ):
  126. self.r = r
  127. self.s = s
  128.  
  129. class Public_key( object ):
  130. def __init__( self, generator, point ):
  131. self.curve = generator.curve()
  132. self.generator = generator
  133. self.point = point
  134. n = generator.order()
  135. if not n:
  136. raise RuntimeError, "Generator point must have order."
  137. if not n * point == INFINITY:
  138. raise RuntimeError, "Generator point order is bad."
  139. if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
  140. raise RuntimeError, "Generator point has x or y out of range."
  141.  
  142. def verifies( self, hash, signature ):
  143. G = self.generator
  144. n = G.order()
  145. r = signature.r
  146. s = signature.s
  147. if r < 1 or r > n-1: return False
  148. if s < 1 or s > n-1: return False
  149. c = inverse_mod( s, n )
  150. u1 = ( hash * c ) % n
  151. u2 = ( r * c ) % n
  152. xy = u1 * G + u2 * self.point
  153. v = xy.x() % n
  154. return v == r
  155.  
  156. print(c)
  157. print(u1)
  158. print(u2)
  159. print(xy)
  160. print(v)
  161. print(r)
Success #stdin #stdout 0.04s 65472KB
stdin
Standard input is empty
stdout
Standard output is empty