-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathsolve2.py
74 lines (60 loc) · 1.82 KB
/
solve2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import web3
from eth_keys import keys, datatypes
from eth_account._utils.typed_transactions import TypedTransaction
from fastecdsa.curve import secp256k1
from fastecdsa.point import Point
from tqdm import tqdm
def recover_public_key(tx_raw):
tx = TypedTransaction.from_bytes(tx_raw)
sig = datatypes.Signature(vrs=tx.vrs())
return keys.ecdsa_recover(tx.hash(), sig)
def hash_point(P):
return (P.x, P.y)
def MITM_naive(lhs, rhs, M):
tbl = {}
for low in tqdm(range(M)):
tbl[hash_point(lhs - low * rhs)] = low
rhsM = rhs * M
for high in tqdm(range(M)):
if hash_point(high * rhsM) in tbl:
return tbl[hash_point(high * rhsM)] + high * M
def MITM_optimized(lhs, rhs, M):
tbl = {}
tmp = lhs
for low in tqdm(range(M)):
tbl[(tmp.x, tmp.y)] = low
tmp -= rhs
rhsM = rhs * M
tmp = rhsM * 0
for high in tqdm(range(M)):
if (tmp.x, tmp.y) in tbl:
return tbl[(tmp.x, tmp.y)] + high * M
tmp += rhsM
sepolia = web3.providers.HTTPProvider("https://rpc.sepolia.org/")
w3 = web3.Web3(sepolia)
tx_raw = w3.eth.get_raw_transaction(
"0x39f9e9279472d9ab7986fe380fae9693e91003104bb892c953e73b6a2f878ac2"
)
print(tx_raw)
pub = recover_public_key(tx_raw)
print(pub)
assert pub.to_checksum_address() == "0x891cf17281bF2a57b25620b144A4E71B395603D4"
pb = pub.to_bytes()
x = int.from_bytes(pb[:32], "big")
y = int.from_bytes(pb[32:], "big")
P = Point(x, y, curve=secp256k1)
print(P)
# P = x * G = (c + s * r) * G
# c = ictf{??????}
# s = 256
# r = ??????
# P - c * G = r * (s * G)
# lhs = P - c * G
# rhs = s * G
c = int.from_bytes(b"ictf{\x00\x00\x00\x00\x00\x00}".rjust(32, b"\x00"), "big")
lhs = P - c * secp256k1.G
rhs = 256 * secp256k1.G
# r = MITM_naive(lhs, rhs, 1 << 24)
r = MITM_optimized(lhs, rhs, 1 << 24)
print(r)
print(r.to_bytes(6, "big"))