-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsecp256r1_recovery_pubkey.py
42 lines (35 loc) · 1.02 KB
/
secp256r1_recovery_pubkey.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
import random
import secp256r1
prikey = secp256r1.Fr(0x5f6717883bef25f45a129c11fcac1567d74bda5a9ad4cbffc8203c0da2a1473c)
pubkey = secp256r1.G * prikey
# Hash of messages. Generated by "sha256sum secp256r1.py"
m = secp256r1.Fr(0x72a963cdfb01bc37cd283106875ff1f07f02bc9ad6121b75c3d17629df128d4e)
print(f'hash={m}')
# Sign
while True:
k = secp256r1.Fr(random.randint(0, secp256r1.N))
R = secp256r1.G * k
r = secp256r1.Fr(R.x.x)
if r.x == 0:
continue
s = (m + prikey * r) / k
if s.x == 0:
continue
print(f'sigr={r}')
print(f'sigs={s}')
break
# https://www.secg.org/sec1-v2.pdf, 4.1.6
for j in range(2):
x = r.x + secp256r1.N * j
x = secp256r1.Fq(x)
yy = x ** 3 + secp256r1.A * x + secp256r1.B
y = yy.sqrt()
if y ** 2 != yy:
continue
r0 = +secp256r1.Pt(x, y)
r1 = -secp256r1.Pt(x, y)
q0 = (r0 * s - secp256r1.G * m) * (r ** -1)
q1 = (r1 * s - secp256r1.G * m) * (r ** -1)
if q0 == pubkey or q1 == pubkey:
print(f'nice')
break