#Bad-Rabbit
import collections
import random
EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')
curve = EllipticCurve(
'secp256k1',
# Простой модуль.
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
# Параметры переменных.
a=0,
b=7,
# Базовая точка.
g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
# РџРѕСЂСЏРґРѕРє РєСЂРёРІРѕР№.
n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
# РџРѕРґРіСЂСѓРїРїР°.
h=1,
)
# Модульная арифметика ##########################################################
def inverse_mod(k, p):
"""Returns the inverse of k modulo p.
This function returns the only integer x such that (x * k) % p == 1.
k must be non-zero and p must be a prime.
"""
if k == 0:
raise ZeroDivisionError('division by zero')
if k < 0:
# k ** -1 = p - (-k) ** -1 (mod p)
return p - inverse_mod(-k, p)
# Расширенный Алгоритм Евклида.
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = p, k
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
gcd, x, y = old_r, old_s, old_t
assert gcd == 1
assert (k * x) % p == 1
return x % p
# Функция для работы арифметики точек #########################################
def is_on_curve(point):
"""Returns True if the given point lies on the elliptic curve."""
if point is None:
# Для точек с возможностью рекурсии.
return True
x, y = point
return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0
def point_neg(point):
"""Returns -point."""
assert is_on_curve(point)
if point is None:
# -0 = 0
return None
x, y = point
result = (x, -y % curve.p)
assert is_on_curve(result)
return result
def point_add(point1, point2):
"""Returns the result of point1 + point2 according to the group law."""
assert is_on_curve(point1)
assert is_on_curve(point2)
if point1 is None:
# 0 + point2 = point2
return point2
if point2 is None:
# point1 + 0 = point1
return point1
x1, y1 = point1
x2, y2 = point2
if x1 == x2 and y1 != y2:
# point1 + (-point1) = 0
return None
if x1 == x2:
# Удвоение точки point1 == point2.
m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)
else:
# Сложение точек point1 != point2.
m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)
x3 = m * m - x1 - x2
y3 = y1 + m * (x3 - x1)
result = (x3 % curve.p,
-y3 % curve.p)
assert is_on_curve(result)
return result
def scalar_mult(k, point):
"""Returns k * point computed using the double and point_add algorithm."""
assert is_on_curve(point)
if k % curve.n == 0 or point is None:
return None
if k < 0:
# k * point = -k * (-point)
return scalar_mult(-k, point_neg(point))
result = None
addend = point
while k:
if k & 1:
# Создали.
result = point_add(result, addend)
# Повторили.
addend = point_add(addend, addend)
k >>= 1
assert is_on_curve(result)
return result
# Скалярное деление такое же как и умножение ##########################################
def chetchek(point):
vic = scalar_mult(0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9050, curve.g)
chek1 = scalar_mult(0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1, curve.g)
chek2 = point_add(curve.g, chek1)
brpoint = point_add(curve.g, point_neg(point))
p1 = point_add(point, point_neg(vic))
p2 = point_add(brpoint, point_neg(vic))
br1p = point_add(curve.g, point_neg(p1))
br2p = point_add(curve.g, point_neg(p2))
chekpoint1 = point_add(p1, p2)
chekpoint2 = point_add(br1p, br2p)
if chekpoint1 == chek1:
return "первая половина"
else:
return "вторая половина"
# В будующем из этого генерируют ECDSA ################################################
def make_keypair():
"""Generates a random private-public key pair."""
private_key = random.randrange(1, curve.n)
public_key = scalar_mult(private_key, curve.g)
#тело программы, самая сложная хуета###################################################
P = (0xf98c0f45dd33ed5fc6c942755089f0c7937cc864475d5fb2159c68cb102167f6, 0xcf2f4444e97a33a3d92eefcb600d0a4952dea14868528d5c92c91f5085256a3c)
t = 0
r = scalar_mult(2, curve.g)
t = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1
e = point_neg(P)
i = scalar_mult(t, P)
print(e, i)
I0JhZC1SYWJiaXQKCmltcG9ydCBjb2xsZWN0aW9ucwppbXBvcnQgcmFuZG9tCgpFbGxpcHRpY0N1cnZlID0gY29sbGVjdGlvbnMubmFtZWR0dXBsZSgnRWxsaXB0aWNDdXJ2ZScsICduYW1lIHAgYSBiIGcgbiBoJykKCmN1cnZlID0gRWxsaXB0aWNDdXJ2ZSgKICAgICdzZWNwMjU2azEnLAogICAgIyDQoNGf0KHQgtCg0ZXQodCD0KHigJrQoNGV0KDihJYg0KDRmNCg0ZXQoNKR0KHRk9CgwrvQodCKLgogICAgcD0weGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZjMmYsCiAgICAjINCg0Z/QoMKw0KHQgtCgwrDQoNGY0KDCtdCh4oCa0KHQgtCh4oC5INCg0ZfQoMK10KHQgtCgwrXQoNGY0KDCtdCg0IXQoNCF0KHigLnQoeKApi4KICAgIGE9MCwKICAgIGI9NywKICAgICMg0KDigJjQoMKw0KDCt9Cg0ZXQoNCG0KDCsNCh0I8g0KHigJrQoNGV0KHigKHQoNGU0KDCsC4KICAgIGc9KDB4NzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCwKICAgICAgIDB4NDgzYWRhNzcyNmEzYzQ2NTVkYTRmYmZjMGUxMTA4YThmZDE3YjQ0OGE2ODU1NDE5OWM0N2QwOGZmYjEwZDRiOCksCiAgICAjINCg0Z/QoNGV0KHQgtCh0I/QoNKR0KDRldCg0ZQg0KDRlNCh0ILQoNGR0KDQhtCg0ZXQoOKEli4KICAgIG49MHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWJhYWVkY2U2YWY0OGEwM2JiZmQyNWU4Y2QwMzY0MTQxLAogICAgIyDQoNGf0KDRldCg0pHQoNGW0KHQgtCh0ZPQoNGX0KDRl9CgwrAuCiAgICBoPTEsCikKCiMg0KDRmtCg0ZXQoNKR0KHRk9CgwrvQodCK0KDQhdCgwrDQodCPINCgwrDQodCC0KDRkdCh4oCe0KDRmNCgwrXQoeKAmtCg0ZHQoNGU0KDCsCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpkZWYgaW52ZXJzZV9tb2QoaywgcCk6CiAgICAiIiJSZXR1cm5zIHRoZSBpbnZlcnNlIG9mIGsgbW9kdWxvIHAuCgogICAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBvbmx5IGludGVnZXIgeCBzdWNoIHRoYXQgKHggKiBrKSAlIHAgPT0gMS4KCiAgICBrIG11c3QgYmUgbm9uLXplcm8gYW5kIHAgbXVzdCBiZSBhIHByaW1lLgogICAgIiIiCiAgICBpZiBrID09IDA6CiAgICAgICAgcmFpc2UgWmVyb0RpdmlzaW9uRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKQoKICAgIGlmIGsgPCAwOgogICAgICAgICMgayAqKiAtMSA9IHAgLSAoLWspICoqIC0xICAobW9kIHApCiAgICAgICAgcmV0dXJuIHAgLSBpbnZlcnNlX21vZCgtaywgcCkKCiAgICAjINCgINCgwrDQodCD0KHigqzQoNGR0KHQgtCgwrXQoNCF0KDQhdCh4oC50KDihJYg0KDRktCgwrvQoNGW0KDRldCh0ILQoNGR0KHigJrQoNGYINCg4oCi0KDQhtCg0ZTQoMK70KDRkdCg0pHQoMKwLgogICAgcywgb2xkX3MgPSAwLCAxCiAgICB0LCBvbGRfdCA9IDEsIDAKICAgIHIsIG9sZF9yID0gcCwgawoKICAgIHdoaWxlIHIgIT0gMDoKICAgICAgICBxdW90aWVudCA9IG9sZF9yIC8vIHIKICAgICAgICBvbGRfciwgciA9IHIsIG9sZF9yIC0gcXVvdGllbnQgKiByCiAgICAgICAgb2xkX3MsIHMgPSBzLCBvbGRfcyAtIHF1b3RpZW50ICogcwogICAgICAgIG9sZF90LCB0ID0gdCwgb2xkX3QgLSBxdW90aWVudCAqIHQKCiAgICBnY2QsIHgsIHkgPSBvbGRfciwgb2xkX3MsIG9sZF90CgogICAgYXNzZXJ0IGdjZCA9PSAxCiAgICBhc3NlcnQgKGsgKiB4KSAlIHAgPT0gMQoKICAgIHJldHVybiB4ICUgcAoKCiMg0KDCpNCh0ZPQoNCF0KDRlNCh4oCg0KDRkdCh0I8g0KDSkdCgwrvQodCPINCh0ILQoMKw0KDCsdCg0ZXQoeKAmtCh4oC5INCgwrDQodCC0KDRkdCh4oCe0KDRmNCgwrXQoeKAmtCg0ZHQoNGU0KDRkSDQoeKAmtCg0ZXQoeKAodCgwrXQoNGUICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpkZWYgaXNfb25fY3VydmUocG9pbnQpOgogICAgIiIiUmV0dXJucyBUcnVlIGlmIHRoZSBnaXZlbiBwb2ludCBsaWVzIG9uIHRoZSBlbGxpcHRpYyBjdXJ2ZS4iIiIKICAgIGlmIHBvaW50IGlzIE5vbmU6CiAgICAgICAgIyDQoOKAndCgwrvQodCPINCh4oCa0KDRldCh4oCh0KDCtdCg0ZQg0KHQgyDQoNCG0KDRldCgwrfQoNGY0KDRldCgwrbQoNCF0KDRldCh0IPQoeKAmtCh0IrQodCLINCh0ILQoMK10KDRlNCh0ZPQodCC0KHQg9Cg0ZHQoNGRLgogICAgICAgIHJldHVybiBUcnVlCgogICAgeCwgeSA9IHBvaW50CgogICAgcmV0dXJuICh5ICogeSAtIHggKiB4ICogeCAtIGN1cnZlLmEgKiB4IC0gY3VydmUuYikgJSBjdXJ2ZS5wID09IDAKCgpkZWYgcG9pbnRfbmVnKHBvaW50KToKICAgICIiIlJldHVybnMgLXBvaW50LiIiIgogICAgYXNzZXJ0IGlzX29uX2N1cnZlKHBvaW50KQoKICAgIGlmIHBvaW50IGlzIE5vbmU6CiAgICAgICAgIyAtMCA9IDAKICAgICAgICByZXR1cm4gTm9uZQoKICAgIHgsIHkgPSBwb2ludAogICAgcmVzdWx0ID0gKHgsIC15ICUgY3VydmUucCkKCiAgICBhc3NlcnQgaXNfb25fY3VydmUocmVzdWx0KQoKICAgIHJldHVybiByZXN1bHQKCgpkZWYgcG9pbnRfYWRkKHBvaW50MSwgcG9pbnQyKToKICAgICIiIlJldHVybnMgdGhlIHJlc3VsdCBvZiBwb2ludDEgKyBwb2ludDIgYWNjb3JkaW5nIHRvIHRoZSBncm91cCBsYXcuIiIiCiAgICBhc3NlcnQgaXNfb25fY3VydmUocG9pbnQxKQogICAgYXNzZXJ0IGlzX29uX2N1cnZlKHBvaW50MikKCiAgICBpZiBwb2ludDEgaXMgTm9uZToKICAgICAgICAjIDAgKyBwb2ludDIgPSBwb2ludDIKICAgICAgICByZXR1cm4gcG9pbnQyCiAgICBpZiBwb2ludDIgaXMgTm9uZToKICAgICAgICAjIHBvaW50MSArIDAgPSBwb2ludDEKICAgICAgICByZXR1cm4gcG9pbnQxCgogICAgeDEsIHkxID0gcG9pbnQxCiAgICB4MiwgeTIgPSBwb2ludDIKCiAgICBpZiB4MSA9PSB4MiBhbmQgeTEgIT0geTI6CiAgICAgICAgIyBwb2ludDEgKyAoLXBvaW50MSkgPSAwCiAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBpZiB4MSA9PSB4MjoKICAgICAgICAjINCg0IjQoNKR0KDQhtCg0ZXQoMK10KDQhdCg0ZHQoMK1INCh4oCa0KDRldCh4oCh0KDRlNCg0ZEgcG9pbnQxID09IHBvaW50Mi4KICAgICAgICBtID0gKDMgKiB4MSAqIHgxICsgY3VydmUuYSkgKiBpbnZlcnNlX21vZCgyICogeTEsIGN1cnZlLnApCiAgICBlbHNlOgogICAgICAgICMg0KDQjtCgwrvQoNGV0KDCttCgwrXQoNCF0KDRkdCgwrUg0KHigJrQoNGV0KHigKHQoMK10KDRlCBwb2ludDEgIT0gcG9pbnQyLgogICAgICAgIG0gPSAoeTEgLSB5MikgKiBpbnZlcnNlX21vZCh4MSAtIHgyLCBjdXJ2ZS5wKQoKICAgIHgzID0gbSAqIG0gLSB4MSAtIHgyCiAgICB5MyA9IHkxICsgbSAqICh4MyAtIHgxKQogICAgcmVzdWx0ID0gKHgzICUgY3VydmUucCwKICAgICAgICAgICAgICAteTMgJSBjdXJ2ZS5wKQoKICAgIGFzc2VydCBpc19vbl9jdXJ2ZShyZXN1bHQpCgogICAgcmV0dXJuIHJlc3VsdAoKCmRlZiBzY2FsYXJfbXVsdChrLCBwb2ludCk6CiAgICAiIiJSZXR1cm5zIGsgKiBwb2ludCBjb21wdXRlZCB1c2luZyB0aGUgZG91YmxlIGFuZCBwb2ludF9hZGQgYWxnb3JpdGhtLiIiIgogICAgYXNzZXJ0IGlzX29uX2N1cnZlKHBvaW50KQoKICAgIGlmIGsgJSBjdXJ2ZS5uID09IDAgb3IgcG9pbnQgaXMgTm9uZToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGlmIGsgPCAwOgogICAgICAgICMgayAqIHBvaW50ID0gLWsgKiAoLXBvaW50KQogICAgICAgIHJldHVybiBzY2FsYXJfbXVsdCgtaywgcG9pbnRfbmVnKHBvaW50KSkKCiAgICByZXN1bHQgPSBOb25lCiAgICBhZGRlbmQgPSBwb2ludAoKICAgIHdoaWxlIGs6CiAgICAgICAgaWYgayAmIDE6CiAgICAgICAgICAgICMg0KDQjtCg0ZXQoMK30KDSkdCgwrDQoMK70KDRkS4KICAgICAgICAgICAgcmVzdWx0ID0gcG9pbnRfYWRkKHJlc3VsdCwgYWRkZW5kKQoKICAgICAgICAjINCg0Z/QoNGV0KDQhtCh4oCa0KDRldCh0ILQoNGR0KDCu9Cg0ZEuCiAgICAgICAgYWRkZW5kID0gcG9pbnRfYWRkKGFkZGVuZCwgYWRkZW5kKQoKICAgICAgICBrID4+PSAxCgogICAgYXNzZXJ0IGlzX29uX2N1cnZlKHJlc3VsdCkKCiAgICByZXR1cm4gcmVzdWx0CgojINCg0I7QoNGU0KDCsNCgwrvQodCP0KHQgtCg0IXQoNGV0KDCtSDQoNKR0KDCtdCgwrvQoMK10KDQhdCg0ZHQoMK1INCh4oCa0KDCsNCg0ZTQoNGV0KDCtSDQoMK20KDCtSDQoNGU0KDCsNCg0ZQg0KDRkSDQodGT0KDRmNCg0IXQoNGV0KDCttCgwrXQoNCF0KDRkdCgwrUgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCmRlZiBjaGV0Y2hlayhwb2ludCk6CiAgICB2aWMgPSBzY2FsYXJfbXVsdCgweDNmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYWVhYmI3MzlhYmQyMjgwZWVmZjQ5N2EzMzQwZDkwNTAsIGN1cnZlLmcpCiAgICBjaGVrMSA9IHNjYWxhcl9tdWx0KDB4N2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY1ZDU3NmU3MzU3YTQ1MDFkZGZlOTJmNDY2ODFiMjBhMSwgY3VydmUuZykKICAgIGNoZWsyID0gcG9pbnRfYWRkKGN1cnZlLmcsIGNoZWsxKQogICAgYnJwb2ludCA9IHBvaW50X2FkZChjdXJ2ZS5nLCBwb2ludF9uZWcocG9pbnQpKQogICAgcDEgPSBwb2ludF9hZGQocG9pbnQsIHBvaW50X25lZyh2aWMpKQogICAgcDIgPSBwb2ludF9hZGQoYnJwb2ludCwgcG9pbnRfbmVnKHZpYykpCiAgICBicjFwID0gcG9pbnRfYWRkKGN1cnZlLmcsIHBvaW50X25lZyhwMSkpCiAgICBicjJwID0gcG9pbnRfYWRkKGN1cnZlLmcsIHBvaW50X25lZyhwMikpCiAgICBjaGVrcG9pbnQxID0gcG9pbnRfYWRkKHAxLCBwMikKICAgIGNoZWtwb2ludDIgPSBwb2ludF9hZGQoYnIxcCwgYnIycCkKICAgIGlmIGNoZWtwb2ludDEgPT0gY2hlazE6CiAgICAgICAgcmV0dXJuICLQv9C10YDQstCw0Y8g0L/QvtC70L7QstC40L3QsCIKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuICLQstGC0L7RgNCw0Y8g0L/QvtC70L7QstC40L3QsCIKICAgIAojINCg4oCZINCgwrHQodGT0KDSkdCh0ZPQodCL0KHigLDQoMK10KDRmCDQoNGR0KDCtyDQodCM0KHigJrQoNGV0KDRltCg0ZUg0KDRltCgwrXQoNCF0KDCtdCh0ILQoNGR0KHQgtCh0ZPQodCL0KHigJogRUNEU0EgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpkZWYgbWFrZV9rZXlwYWlyKCk6CiAgICAiIiJHZW5lcmF0ZXMgYSByYW5kb20gcHJpdmF0ZS1wdWJsaWMga2V5IHBhaXIuIiIiCiAgICBwcml2YXRlX2tleSA9IHJhbmRvbS5yYW5kcmFuZ2UoMSwgY3VydmUubikKICAgIHB1YmxpY19rZXkgPSBzY2FsYXJfbXVsdChwcml2YXRlX2tleSwgY3VydmUuZykKCiPQoeKAmtCgwrXQoMK70KDRlSDQoNGX0KHQgtCg0ZXQoNGW0KHQgtCgwrDQoNGY0KDRmNCh4oC5LCDQodCD0KDCsNCg0ZjQoMKw0KHQjyDQodCD0KDCu9Cg0ZXQoMK20KDQhdCgwrDQodCPINCh4oCm0KHRk9CgwrXQoeKAmtCgwrAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKUCAgPSAoMHhmOThjMGY0NWRkMzNlZDVmYzZjOTQyNzU1MDg5ZjBjNzkzN2NjODY0NDc1ZDVmYjIxNTljNjhjYjEwMjE2N2Y2LCAweGNmMmY0NDQ0ZTk3YTMzYTNkOTJlZWZjYjYwMGQwYTQ5NTJkZWExNDg2ODUyOGQ1YzkyYzkxZjUwODUyNTZhM2MpCnQgPSAwCnIgPSBzY2FsYXJfbXVsdCgyLCBjdXJ2ZS5nKQp0ID0gMHg3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjVkNTc2ZTczNTdhNDUwMWRkZmU5MmY0NjY4MWIyMGExCmUgPSBwb2ludF9uZWcoUCkKaSA9IHNjYWxhcl9tdWx0KHQsIFApCnByaW50KGUsIGkp