-
Notifications
You must be signed in to change notification settings - Fork 4
/
nums.py
50 lines (37 loc) · 1.21 KB
/
nums.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
"""Tool to hash strings to a point on the secp256r1 curve.
"""
import hashlib
import click
from Crypto.PublicKey import ECC
from Crypto.Math._IntegerGMP import IntegerGMP
import impl
@click.command()
@click.argument("s", type=str, required=True)
def nums(s):
# secp256r1 constants
a = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC
b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
p = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
inc = 0
while True:
inc += 1
# construct a NUMS string and map it to a point on the curve
NUMS = hashlib.sha256(f"{s}/{inc}".encode("utf-8"))
x = int(NUMS.hexdigest(), 16)
x = IntegerGMP(x) % p
# ecc curve is of the form y**2 = x**3 + a*x + b
rhs = x ** 3 + x * a + b
try:
y = rhs.sqrt(modulus=p)
except ValueError:
continue
lhs = y ** 2
if lhs % p == rhs % p:
try:
point = ECC.EccPoint(x, y, curve="secp256r1")
break
except ValueError:
continue
click.echo(impl.point_to_b58(point))
if __name__ == "__main__":
nums()