-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathb_dhke.py
95 lines (75 loc) · 2.18 KB
/
b_dhke.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
84
85
86
87
88
89
90
91
92
93
94
95
# Don't trust me with cryptography.
"""
Implementation of https://gist.github.com/RubenSomsen/be7a4760dd4596d06963d67baf140406
Alice:
A = a*G
return A
Bob:
Y = hash_to_curve(secret_message)
r = random blinding factor
B'= Y + r*G
return B'
Alice:
C' = a*B'
(= a*Y + a*r*G)
return C'
Bob:
C = C' - r*A
(= C' - a*r*G)
(= a*Y)
return C, secret_message
Alice:
Y = hash_to_curve(secret_message)
C == a*Y
If true, C must have originated from Alice
"""
import hashlib
from secp import PrivateKey, PublicKey
def hash_to_curve(secret_msg):
"""Generates x coordinate from the message hash and checks if the point lies on the curve.
If it does not, it tries computing again a new x coordinate from the hash of the coordinate."""
point = None
msg = secret_msg
while point is None:
_hash = hashlib.sha256(msg).hexdigest().encode("utf-8")
try:
# We construct compressed pub which has x coordinate encoded with even y
_hash = list(_hash[:33]) # take the 33 bytes and get a list of bytes
_hash[0] = 0x02 # set first byte to represent even y coord
_hash = bytes(_hash)
point = PublicKey(_hash, raw=True)
except:
msg = _hash
return point
def step1_bob(secret_msg):
secret_msg = secret_msg.encode("utf-8")
Y = hash_to_curve(secret_msg)
r = PrivateKey()
B_ = Y + r.pubkey
return B_, r
def step2_alice(B_, a):
C_ = B_.mult(a)
return C_
def step3_bob(C_, r, A):
C = C_ - A.mult(r)
return C
def verify(a, C, secret_msg):
Y = hash_to_curve(secret_msg.encode("utf-8"))
return C == Y.mult(a)
### Below is a test of a simple positive and negative case
# # Alice's keys
# a = PrivateKey()
# A = a.pubkey
# secret_msg = "test"
# B_, r = step1_bob(secret_msg)
# C_ = step2_alice(B_, a)
# C = step3_bob(C_, r, A)
# print("C:{}, secret_msg:{}".format(C, secret_msg))
# assert verify(a, C, secret_msg)
# assert verify(a, C + C, secret_msg) == False # adding C twice shouldn't pass
# assert verify(a, A, secret_msg) == False # A shouldn't pass
# # Test operations
# b = PrivateKey()
# B = b.pubkey
# assert -A -A + A == -A # neg
# assert B.mult(a) == A.mult(b) # a*B = A*b