-
Notifications
You must be signed in to change notification settings - Fork 2
/
derive-shared-secret.py
executable file
·67 lines (51 loc) · 1.51 KB
/
derive-shared-secret.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
#!/usr/bin/python3
import sys
import cypari2
from cypari2.convert import gen_to_integer, integer_to_gen
from salsa import HSalsa20
def hexdump(b):
"""Convert byte array to hex string"""
return ' '.join(["{:02X}".format(v) for v in b])
def clamp(n):
"""Curve25519 clamping by Matthew Dempsky"""
n &= ~7
n &= ~(128 << 8 * 31)
n |= 64 << 8 * 31
return n
def curve25519_pk_mult(pari, s, x):
# E: y^2 = x^3 + 486662 * x^2 + x on GF(2^255-19)
E = pari.ellinit([0,486662,0,1,0], 2**255-19)
x_elem = pari.Mod(x, 2**255-19)
# y = Sqrt(x^3 + 486662 * x^2 + x)
y = x**3 + 486662 * x**2 + x
y_elem = pari.sqrt(pari.Mod(y, 2**255-19))
P = [x_elem, y_elem]
return pari.ellmul(E, P, s)
if len(sys.argv) < 3:
print("Usage: {} MY_SK_FILE OTHER_PK_FILE".format(sys.argv[0]))
sys.exit(-1)
# Open file with my SK
with open(sys.argv[1], "rb") as f:
my_sk_bytes = f.read()
# Open file with other PK
with open(sys.argv[2], "rb") as f:
other_pk_bytes = f.read()
# Convert and clamp SK
my_sk = int.from_bytes( my_sk_bytes, "little" )
my_sk = clamp(my_sk)
# Init Pari
pari = cypari2.Pari()
# Read and convert PK
other_pk = int.from_bytes( other_pk_bytes, "little" )
# Calculate Diffie-Hellman shared key
dh_p = curve25519_pk_mult(pari, my_sk, other_pk)
dh_i = gen_to_integer(pari.lift(dh_p[0]))
dhkey = dh_i.to_bytes(32, byteorder='little')
# Build input of salsa
kdfinput = {}
kdfinput["nonce"] = bytearray(16)
kdfinput["key"] = dhkey
hsalsa = HSalsa20()
k = hsalsa(**kdfinput)
# Print shared key as hex dump
print(hexdump(k))