-
Notifications
You must be signed in to change notification settings - Fork 15
/
Kyber.py
78 lines (63 loc) · 2.8 KB
/
Kyber.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
from math import log
from Kyber_failure import p2_cyclotomic_error_probability
from MLWE_security import MLWE_summarize_attacks, MLWEParameterSet
from proba_util import build_mod_switching_error_law
class KyberParameterSet:
def __init__(self, n, m, ks, ke, q, rqk, rqc, rq2, ke_ct=None):
if ke_ct is None:
ke_ct = ke
self.n = n
self.m = m
self.ks = ks # binary distribution for the secret key
self.ke = ke # binary distribution for the ciphertext errors
self.ke_ct = ke_ct # binary distribution for the ciphertext errors
self.q = q
self.rqk = rqk # 2^(bits in the public key)
self.rqc = rqc # 2^(bits in the first ciphertext)
self.rq2 = rq2 # 2^(bits in the second ciphertext)
def Kyber_to_MLWE(kps):
if kps.ks != kps.ke:
raise "The security script does not handle different error parameter in secrets and errors (ks != ke) "
# Check whether ciphertext error variance after rounding is larger than secret key error variance
Rc = build_mod_switching_error_law(kps.q, kps.rqc)
var_rounding = sum([i*i*Rc[i] for i in Rc.keys()])
if kps.ke_ct/2. + var_rounding < kps.ke/2.:
raise "The security of the ciphertext MLWE may not be stronger than the one of the public key MLWE"
return MLWEParameterSet(kps.n, kps.m, kps.m + 1, kps.ks, kps.q)
def communication_costs(ps):
""" Compute the communication cost of a parameter set
:param ps: Parameter set (ParameterSet)
:returns: (cost_Alice, cost_Bob) (in Bytes)
"""
A_space = 256 + ps.n * ps.m * log(ps.rqk)/log(2)
B_space = ps.n * ps.m * log(ps.rqc)/log(2) + ps.n * log(ps.rq2)/log(2)
return (int(round(A_space))/8., int(round(B_space))/8.)
def summarize(ps):
print ("params: ", ps.__dict__)
print ("com costs: ", communication_costs(ps))
F, f = p2_cyclotomic_error_probability(ps)
print ("failure: %.1f = 2^%.1f"%(f, log(f + 2.**(-300))/log(2)))
if __name__ == "__main__":
# Parameter sets
ps_light = KyberParameterSet(256, 2, 3, 3, 3329, 2**12, 2**10, 2**4, ke_ct=2)
ps_recommended = KyberParameterSet(256, 3, 2, 2, 3329, 2**12, 2**10, 2**4)
ps_paranoid = KyberParameterSet(256, 4, 2, 2, 3329, 2**12, 2**11, 2**5)
# Analyses
print ("Kyber512 (light):")
print ("--------------------")
print ("security:")
MLWE_summarize_attacks(Kyber_to_MLWE(ps_light))
summarize(ps_light)
print ()
print ("Kyber768 (recommended):")
print ("--------------------")
print ("security:")
MLWE_summarize_attacks(Kyber_to_MLWE(ps_recommended))
summarize(ps_recommended)
print ()
print ("Kyber1024 (paranoid):")
print ("--------------------")
print ("security:")
MLWE_summarize_attacks(Kyber_to_MLWE(ps_paranoid))
summarize(ps_paranoid)
print ()