-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy patheddsa.py
71 lines (60 loc) · 1.98 KB
/
eddsa.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
from pure25519.basic import (bytes_to_clamped_scalar,
bytes_to_scalar, scalar_to_bytes,
bytes_to_element, Base)
import hashlib, binascii
def H(m):
return hashlib.sha512(m).digest()
def publickey(seed):
# turn first half of SHA512(seed) into scalar, then into point
assert len(seed) == 32
a = bytes_to_clamped_scalar(H(seed)[:32])
A = Base.scalarmult(a)
return A.to_bytes()
def Hint(m):
h = H(m)
return int(binascii.hexlify(h[::-1]), 16)
def signature(m,sk,pk):
assert len(sk) == 32 # seed
assert len(pk) == 32
h = H(sk[:32])
a_bytes, inter = h[:32], h[32:]
a = bytes_to_clamped_scalar(a_bytes)
r = Hint(inter + m)
R = Base.scalarmult(r)
R_bytes = R.to_bytes()
S = r + Hint(R_bytes + pk + m) * a
return R_bytes + scalar_to_bytes(S)
def checkvalid(s, m, pk):
if len(s) != 64: raise Exception("signature length is wrong")
if len(pk) != 32: raise Exception("public-key length is wrong")
R = bytes_to_element(s[:32])
A = bytes_to_element(pk)
S = bytes_to_scalar(s[32:])
h = Hint(s[:32] + pk + m)
v1 = Base.scalarmult(S)
v2 = R.add(A.scalarmult(h))
return v1==v2
# wrappers
import os
def create_signing_key():
seed = os.urandom(32)
return seed
def create_verifying_key(signing_key):
return publickey(signing_key)
def sign(skbytes, msg):
"""Return just the signature, given the message and just the secret
key."""
if len(skbytes) != 32:
raise ValueError("Bad signing key length %d" % len(skbytes))
vkbytes = create_verifying_key(skbytes)
sig = signature(msg, skbytes, vkbytes)
return sig
def verify(vkbytes, sig, msg):
if len(vkbytes) != 32:
raise ValueError("Bad verifying key length %d" % len(vkbytes))
if len(sig) != 64:
raise ValueError("Bad signature length %d" % len(sig))
rc = checkvalid(sig, msg, vkbytes)
if not rc:
raise ValueError("rc != 0", rc)
return True