-
Notifications
You must be signed in to change notification settings - Fork 9
/
Curve25519.py
83 lines (63 loc) · 2.46 KB
/
Curve25519.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
75
76
77
78
79
80
81
82
83
import msgpack
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey,
Ed25519PublicKey,
)
from ops.address_ops import make_address
def unhex(hexed):
return b"".fromhex(hexed)
def sign(private_key, message):
private_bytes = unhex(private_key)
private_key_raw = Ed25519PrivateKey.generate().from_private_bytes(private_bytes)
signed = private_key_raw.sign(message).hex()
return signed
def verify(signed, public_key, message):
try:
public_bytes = unhex(public_key)
public_key_raw = Ed25519PublicKey.from_public_bytes(public_bytes)
public_key_raw.verify(unhex(signed), message)
return True
except Exception:
raise ValueError("Invalid signature") #sadly, the underlying mechanism does not propagate error messages
def from_private_key(private_key):
private_bytes = unhex(private_key)
private_key_raw = Ed25519PrivateKey.from_private_bytes(private_bytes)
public_key_raw = private_key_raw.public_key()
public_bytes = public_key_raw.public_bytes(
encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw
)
keydict = {
"private_key": private_bytes.hex(),
"public_key": public_bytes.hex(),
"address": make_address(public_bytes.hex()),
}
return keydict
def generate_keydict():
private_key_raw = Ed25519PrivateKey.generate()
public_key_raw = private_key_raw.public_key()
private_bytes = private_key_raw.private_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PrivateFormat.Raw,
encryption_algorithm=serialization.NoEncryption(),
)
public_bytes = public_key_raw.public_bytes(
encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw
)
keydict = {
"private_key": private_bytes.hex(),
"public_key": public_bytes.hex(),
"address": make_address(public_bytes.hex()),
}
return keydict
if __name__ == "__main__":
keydict = generate_keydict()
test_message = "5adf8c531d6698a647c54435386618a0bacd8c3f91b3f1ce1d2ac7c1601a829c"
print(keydict["private_key"])
print(keydict["public_key"])
print(keydict["address"])
signature = sign(private_key=keydict["private_key"], message=unhex(test_message))
print(signature)
print(
verify(message=unhex(test_message), public_key=keydict["public_key"], signed=signature)
)