fork download
  1. #Bad-Rabbit
  2.  
  3. import collections
  4. import random
  5.  
  6. EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')
  7.  
  8. curve = EllipticCurve(
  9. 'secp256k1',
  10. # Простой модуль.
  11. p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
  12. # Параметры переменных.
  13. a=0,
  14. b=7,
  15. # Базовая точка.
  16. g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
  17. 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
  18. # РџРѕСЂСЏРґРѕРє РєСЂРёРІРѕР№.
  19. n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
  20. # РџРѕРґРіСЂСѓРїРїР°.
  21. h=1,
  22. )
  23.  
  24. # Модульная арифметика ##########################################################
  25.  
  26. def inverse_mod(k, p):
  27. """Returns the inverse of k modulo p.
  28.  
  29. This function returns the only integer x such that (x * k) % p == 1.
  30.  
  31. k must be non-zero and p must be a prime.
  32. """
  33. if k == 0:
  34. raise ZeroDivisionError('division by zero')
  35.  
  36. if k < 0:
  37. # k ** -1 = p - (-k) ** -1 (mod p)
  38. return p - inverse_mod(-k, p)
  39.  
  40. # Расширенный Алгоритм Евклида.
  41. s, old_s = 0, 1
  42. t, old_t = 1, 0
  43. r, old_r = p, k
  44.  
  45. while r != 0:
  46. quotient = old_r // r
  47. old_r, r = r, old_r - quotient * r
  48. old_s, s = s, old_s - quotient * s
  49. old_t, t = t, old_t - quotient * t
  50.  
  51. gcd, x, y = old_r, old_s, old_t
  52.  
  53. assert gcd == 1
  54. assert (k * x) % p == 1
  55.  
  56. return x % p
  57.  
  58.  
  59. # Функция для работы арифметики точек #########################################
  60.  
  61. def is_on_curve(point):
  62. """Returns True if the given point lies on the elliptic curve."""
  63. if point is None:
  64. # Для точек с возможностью рекурсии.
  65. return True
  66.  
  67. x, y = point
  68.  
  69. return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0
  70.  
  71.  
  72. def point_neg(point):
  73. """Returns -point."""
  74. assert is_on_curve(point)
  75.  
  76. if point is None:
  77. # -0 = 0
  78. return None
  79.  
  80. x, y = point
  81. result = (x, -y % curve.p)
  82.  
  83. assert is_on_curve(result)
  84.  
  85. return result
  86.  
  87.  
  88. def point_add(point1, point2):
  89. """Returns the result of point1 + point2 according to the group law."""
  90. assert is_on_curve(point1)
  91. assert is_on_curve(point2)
  92.  
  93. if point1 is None:
  94. # 0 + point2 = point2
  95. return point2
  96. if point2 is None:
  97. # point1 + 0 = point1
  98. return point1
  99.  
  100. x1, y1 = point1
  101. x2, y2 = point2
  102.  
  103. if x1 == x2 and y1 != y2:
  104. # point1 + (-point1) = 0
  105. return None
  106.  
  107. if x1 == x2:
  108. # Удвоение точки point1 == point2.
  109. m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)
  110. else:
  111. # Сложение точек point1 != point2.
  112. m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)
  113.  
  114. x3 = m * m - x1 - x2
  115. y3 = y1 + m * (x3 - x1)
  116. result = (x3 % curve.p,
  117. -y3 % curve.p)
  118.  
  119. assert is_on_curve(result)
  120.  
  121. return result
  122.  
  123.  
  124. def scalar_mult(k, point):
  125. """Returns k * point computed using the double and point_add algorithm."""
  126. assert is_on_curve(point)
  127.  
  128. if k % curve.n == 0 or point is None:
  129. return None
  130.  
  131. if k < 0:
  132. # k * point = -k * (-point)
  133. return scalar_mult(-k, point_neg(point))
  134.  
  135. result = None
  136. addend = point
  137.  
  138. while k:
  139. if k & 1:
  140. # Создали.
  141. result = point_add(result, addend)
  142.  
  143. # Повторили.
  144. addend = point_add(addend, addend)
  145.  
  146. k >>= 1
  147.  
  148. assert is_on_curve(result)
  149.  
  150. return result
  151.  
  152. # Скалярное деление такое же как и умножение ##########################################
  153. def chetchek(point):
  154. vic = scalar_mult(0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9050, curve.g)
  155. chek1 = scalar_mult(0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1, curve.g)
  156. chek2 = point_add(curve.g, chek1)
  157. brpoint = point_add(curve.g, point_neg(point))
  158. p1 = point_add(point, point_neg(vic))
  159. p2 = point_add(brpoint, point_neg(vic))
  160. br1p = point_add(curve.g, point_neg(p1))
  161. br2p = point_add(curve.g, point_neg(p2))
  162. chekpoint1 = point_add(p1, p2)
  163. chekpoint2 = point_add(br1p, br2p)
  164. if chekpoint1 == chek1:
  165. return "первая половина"
  166. else:
  167. return "вторая половина"
  168.  
  169. # В будующем из этого генерируют ECDSA ################################################
  170.  
  171. def make_keypair():
  172. """Generates a random private-public key pair."""
  173. private_key = random.randrange(1, curve.n)
  174. public_key = scalar_mult(private_key, curve.g)
  175.  
  176. #тело программы, самая сложная хуета###################################################
  177. P = (0xf98c0f45dd33ed5fc6c942755089f0c7937cc864475d5fb2159c68cb102167f6, 0xcf2f4444e97a33a3d92eefcb600d0a4952dea14868528d5c92c91f5085256a3c)
  178. t = 0
  179. r = scalar_mult(2, curve.g)
  180. t = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1
  181. e = point_neg(P)
  182. i = scalar_mult(t, P)
  183. print(e, i)
Success #stdin #stdout 0.09s 10080KB
stdin
Standard input is empty
stdout
(112873363296029204490322695484212332590776618774762512318312751966578383349750, 22079816591919479012116135744279227482981123326082226054012663440710827676147) (70658565986272646223083610616153218831082773635066128235415055333335339924228, 21719120460065512188268925433416467561844551359432883305364146355300986677322)