-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathecdsa.py
More file actions
97 lines (84 loc) · 2.81 KB
/
ecdsa.py
File metadata and controls
97 lines (84 loc) · 2.81 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# This code is generated by AI
import os
import hashlib
class EllipticCurve(object):
def __init__(self, a, b, F):
self.a = a
self.b = b
self.F = F
def is_valid(self, P):
if P is None:
return True
x, y = P
return (y * y - x * x * x - self.a * x - self.b) % self.F == 0
def add(self, P, Q):
if not (self.is_valid(P) and self.is_valid(Q)):
raise ValueError("Invalid inputs")
if P is None:
return Q
if Q is None:
return P
x1, y1 = P
x2, y2 = Q
if x1 == x2 and y1 != y2:
return None
if x1 == x2:
m = (3 * x1 * x1 + self.a) * invert(2 * y1, self.F)
else:
m = (y1 - y2) * invert(x1 - x2, self.F)
x3 = m*m - x1 - x2
y3 = y1 + m*(x3 - x1)
result = (x3 % self.F, -y3 % self.F)
return result
class ECDSA(object):
def __init__(self, curve, G, n):
self.curve = curve
self.G = G
self.n = n
def sign(self, private_key, message):
e = hashlib.sha256(message).digest()
z = int.from_bytes(e, byteorder='big')
r = 0
s = 0
while not r or not s:
k = random.randrange(1, self.n)
x, y = scalar_mult(self.curve, self.G, k)
r = x % self.n
s = ((z + r * private_key) * invert(k, self.n)) % self.n
return (r, s)
def verify(self, public_key, message, signature):
e = hashlib.sha256(message).digest()
z = int.from_bytes(e, byteorder='big')
r, s = signature
w = invert(s, self.n)
u1 = (z * w) % self.n
u2 = (r * w) % self.n
x, y = add_points(self.curve, scalar_mult(self.curve, self.G, u1),
scalar_mult(self.curve, public_key, u2))
if (r % self.n) == (x % self.n):
return 'signature matches'
else:
return 'signature does not match'
# helper functions
def invert(x, n):
return pow(x, n - 2, n)
def random_secret():
rnd = random.randrange(2**256)
return rnd.to_bytes(32, 'big')
# Test ECDSA with secp256k1
if __name__ == "__main__":
# Using secp256k1 parameters
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
a = 0
b = 7
Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
curve = EllipticCurve(a, b, p)
G = (Gx, Gy)
ecdsa = ECDSA(curve, G, n)
priv_key = int.from_bytes(random_secret(), 'big')
pub_key = scalar_mult(curve, G, priv_key)
msg = b'Hello, world'
signature = ecdsa.sign(priv_key, msg)
print(ecdsa.verify(pub_key, msg, signature))