-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathpsec.sage
79 lines (74 loc) · 1.49 KB
/
psec.sage
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
# Algorithm 4.47 PSEC encryption
# Require:
# generator point P of elliptic curve E
# order n of P and the field Zn defined by n
# Input:
# message m
# public key Q
# Output:
# Ciphertext (R,C,s,t).
#
def psec_encrypt(Q, m):
r = randint(1, n - 1)
l = ceil(math.log(n, 2)/8)
rstr = I2OSP(r, l)
str = KDF(rstr, 96, '')
kstr = str[0:32]
k = int(kstr, 16) % n
k1 = str[32:64]
k2 = str[64:96]
R = k * P
Z = k * Q
rstr = point2str(R, l)
zstr = point2str(Z, l)
addstr = KDF(rstr, l, zstr)
num = int(addstr, 16)
r = int(r)
s = xor(r, num)
aesobj = AES.new(k1)
C = aesobj.encrypt(pad(m))
print C
hmacobj = hmac.new(k2)
hmacobj.update(C)
t = hmacobj.digest()
print t
return [R, C, s, t]
# Algorithm 4.48 ECIES decryption
# Require:
# generator point P of elliptic curve E
# order n of P and the field Zn defined by n
# Input:
# private key d
# ciphertext (R,C,s,t)
# Output:
# Plaintext m or rejection of the ciphertext.
#
def psec_decrypt(R, C, s, t, d):
Z = d * R
l = ceil(math.log(n, 2)/8)
Rstr = point2str(R, l)
Zstr = point2str(Z, l)
addstr = KDF(Rstr, l, Zstr)
num = int(addstr, 16)
s = int(s)
r = xor(s, num)
rstr = I2OSP(r, l)
str = KDF(rstr, 48, '')
kstr = str[0:32]
k = int(kstr, 16) % n
k1 = str[32:64]
k2 = str[64:96]
Rp = k * P
(rpx, rpy) = Rp.xy()
(rx, ry) = R.xy()
if rx != rpx or ry != rpy:
return "Reject"
hmacobj = hmac.new(k2)
hmacobj.update(C)
t1 = hmacobj.digest()
print t1
if t1 != t:
return "Reject"
aesobj = AES.new(k1)
m = aesobj.decrypt(C)
return m