mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-15 15:15:06 -05:00
keep local copy on repo
This commit is contained in:
427
scripts.py
427
scripts.py
@@ -2,17 +2,15 @@ import matplotlib.pyplot as plt
|
||||
from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionIntegerSampler
|
||||
from concrete_params import concrete_LWE_params, concrete_RLWE_params
|
||||
import numpy as np
|
||||
from pytablewriter import MarkdownTableWriter
|
||||
#from pytablewriter import MarkdownTableWriter
|
||||
from hybrid_decoding import parameter_search
|
||||
from random import uniform
|
||||
from mpl_toolkits import mplot3d
|
||||
# easier to just load the estimator
|
||||
load("estimator.py")
|
||||
import estimator.estimator as est
|
||||
|
||||
# define the four cost models used for Concrete (2 classical, 2 quantum)
|
||||
# note that classical and quantum are the two models used in the "HE Std"
|
||||
|
||||
|
||||
def classical(beta, d, B):
|
||||
return ZZ(2) ** RR(0.292 * beta + 16.4 + log(8 * d, 2))
|
||||
|
||||
@@ -28,10 +26,9 @@ def classical_conservative(beta, d, B):
|
||||
def quantum_conservative(beta, d, B):
|
||||
return ZZ(2) ** RR(0.265 * beta)
|
||||
|
||||
# we add an enumeration model for completeness
|
||||
cost_models = [classical, quantum, classical_conservative, quantum_conservative, est.BKZ.enum]
|
||||
|
||||
cost_models = [classical, quantum, classical_conservative, quantum_conservative, BKZ.enum]
|
||||
|
||||
# functions to automate parameter selection
|
||||
|
||||
def get_security_level(estimate, decimal_places = 2):
|
||||
""" Function to get the security level from an LWE Estimator output,
|
||||
@@ -115,6 +112,7 @@ def get_all_security_levels(params):
|
||||
|
||||
return RESULTS
|
||||
|
||||
|
||||
def get_hybrid_security_levels(params):
|
||||
""" A function which gets the security levels of a collection of TFHE parameters,
|
||||
using the four cost models: classical, quantum, classical_conservative, and
|
||||
@@ -207,7 +205,7 @@ def inequality(x, y):
|
||||
return -1
|
||||
|
||||
|
||||
def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sieve, secret_distribution=(0, 1),
|
||||
def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=est.BKZ.sieve, secret_distribution=(0, 1),
|
||||
target_security=128):
|
||||
""" A function used to generate the smallest value of n which allows for
|
||||
target_security bits of security, for the input values of (sd,q)
|
||||
@@ -233,7 +231,6 @@ def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sie
|
||||
|
||||
|
||||
# initial estimate, to determine if we are above or below the target security level
|
||||
print("estimating for n = {}, q, sd".format(n))
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo,
|
||||
@@ -243,18 +240,12 @@ def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sie
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo,
|
||||
skip={"bkw", "dec", "arora-gb", "mitm", "dual"})
|
||||
print("the estimate is {}".format(estimate))
|
||||
security_level = get_security_level(estimate)
|
||||
print("the security level is: {}".format(security_level))
|
||||
z = inequality(security_level, target_security)
|
||||
print("the result of Z is{}".format(z))
|
||||
|
||||
while z * security_level < z * target_security and n > 80:
|
||||
n += z * 8
|
||||
print("N = {}".format(n))
|
||||
print("SECURITY LEVEL = {}".format(security_level))
|
||||
alpha = sqrt(2 * pi) * sd / RR(q)
|
||||
print("estimating for n = {}, q, sd".format(n))
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo, skip = {"bkw","dec","arora-gb","mitm"})
|
||||
@@ -264,7 +255,7 @@ def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sie
|
||||
skip={"bkw", "dec", "arora-gb", "mitm", "dual"})
|
||||
security_level = get_security_level(estimate)
|
||||
|
||||
if (-1 * sd > log(q, 2)):
|
||||
if (-1 * sd > 0):
|
||||
print("target security level is unatainable")
|
||||
break
|
||||
|
||||
@@ -272,8 +263,6 @@ def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sie
|
||||
if security_level < target_security:
|
||||
n -= z * 8
|
||||
alpha = sqrt(2 * pi) * sd / RR(q)
|
||||
print("N = {}".format(n))
|
||||
print("SECURITY LEVEL = {}".format(security_level))
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo, skip = {"bkw","dec","arora-gb","mitm"})
|
||||
@@ -296,8 +285,7 @@ def automated_param_select_n(sd, n=None, q=2 ** 32, reduction_cost_model=BKZ.sie
|
||||
return n
|
||||
|
||||
|
||||
|
||||
def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.sieve, secret_distribution=(0, 1),
|
||||
def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=est.BKZ.sieve, secret_distribution=(0, 1),
|
||||
target_security=128):
|
||||
""" A function used to generate the smallest value of sd which allows for
|
||||
target_security bits of security, for the input values of (n,q)
|
||||
@@ -325,7 +313,6 @@ def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.siev
|
||||
alpha = sqrt(2 * pi) * sd_ / RR(q)
|
||||
|
||||
# initial estimate, to determine if we are above or below the target security level
|
||||
print("estimating for n, q, sd = {}".format(log(sd_,2)))
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo,
|
||||
@@ -338,10 +325,10 @@ def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.siev
|
||||
z = inequality(security_level, target_security)
|
||||
|
||||
while z * security_level < z * target_security and sd > -log(q,2):
|
||||
sd += z * 1
|
||||
|
||||
sd += z * (0.5)
|
||||
sd_ = (2 ** sd) * q
|
||||
alpha = sqrt(2 * pi) * sd_ / RR(q)
|
||||
print("estimating for n, q, sd = {}".format(log(sd_,2)))
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo, skip = {"bkw","dec","arora-gb","mitm"})
|
||||
@@ -351,13 +338,14 @@ def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.siev
|
||||
skip={"bkw", "dec", "arora-gb", "mitm", "dual"})
|
||||
security_level = get_security_level(estimate)
|
||||
|
||||
if (-1 * sd > log(q, 2)):
|
||||
## THIS IS WHERE THE PROBLEM IS, CORRECT THIS CONDITION?
|
||||
if (sd > log(q, 2)):
|
||||
print("target security level is unatainable")
|
||||
break
|
||||
return None
|
||||
|
||||
# final estimate (we went too far in the above loop)
|
||||
if security_level < target_security:
|
||||
sd -= z * 1
|
||||
sd -= z * (0.5)
|
||||
sd_ = (2 ** sd) * q
|
||||
alpha = sqrt(2 * pi) * sd_ / RR(q)
|
||||
try:
|
||||
@@ -378,7 +366,7 @@ def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.siev
|
||||
return sd
|
||||
|
||||
|
||||
def generate_parameter_matrix(n_range, sd=None, q=2**32, reduction_cost_model=BKZ.sieve,
|
||||
def generate_parameter_matrix(n_range, sd=None, q=2**32, reduction_cost_model=est.BKZ.sieve,
|
||||
secret_distribution=(0, 1), target_security=128):
|
||||
"""
|
||||
:param n_range: a tuple (n_min, n_max) giving the values of n for which to generate parameters
|
||||
@@ -399,12 +387,16 @@ def generate_parameter_matrix(n_range, sd=None, q=2**32, reduction_cost_model=BK
|
||||
|
||||
RESULTS = []
|
||||
|
||||
# grab min and max value/s of n
|
||||
(n_min, n_max) = n_range
|
||||
# grab min and max value/s of n, with a granularity (if given as input)
|
||||
try:
|
||||
(n_min, n_max, gran) = n_range
|
||||
except:
|
||||
(n_min, n_max) = n_range
|
||||
gran = 1
|
||||
|
||||
sd_ = sd
|
||||
|
||||
for n in range(n_min, n_max + 1):
|
||||
for n in range(n_min, n_max + 1, gran):
|
||||
sd = automated_param_select_sd(n, sd=sd_, q=q, reduction_cost_model=reduction_cost_model,
|
||||
secret_distribution=secret_distribution, target_security=target_security)
|
||||
sd_ = sd
|
||||
@@ -413,10 +405,10 @@ def generate_parameter_matrix(n_range, sd=None, q=2**32, reduction_cost_model=BK
|
||||
return RESULTS
|
||||
|
||||
|
||||
def generate_parameter_matrix_sd(sd_range, n=None, q=2**32, reduction_cost_model=BKZ.sieve,
|
||||
def generate_parameter_matrix_sd(sd_range, n=None, q=2**32, reduction_cost_model=est.BKZ.sieve,
|
||||
secret_distribution=(0, 1), target_security=128):
|
||||
"""
|
||||
:param n_range: a tuple (n_min, n_max) giving the values of n for which to generate parameters
|
||||
:param sd_range: a tuple (sd_min, sd_max) giving the values of sd for which to generate parameters
|
||||
:param sd: the standard deviation of the LWE error
|
||||
:param q: the LWE modulus (q = 2**32, 2**64 in TFHE)
|
||||
:param reduction_cost_model: the BKZ cost model considered, BKZ.sieve is default
|
||||
@@ -476,71 +468,6 @@ def generate_parameter_step(results, label = None, torus_sd = True):
|
||||
return plt
|
||||
|
||||
|
||||
def test_rounded_gaussian(sigma, number_samples, q = None):
|
||||
"""
|
||||
TODO: actually use a _rounded_ gaussian to match Concrete
|
||||
|
||||
A function which simulates sampling from a Discrete Gaussian distribution
|
||||
:param sigma: the standard deviation
|
||||
:param number_samples: the number of samples to draw
|
||||
|
||||
returns: a list of (value, count) pairs (essentially a histogram)
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
sage: X = test_rounded_gaussian(2/3, 100000)
|
||||
sage: X
|
||||
[(-3, 2), (-2, 714), (-1, 19495), (0, 59658), (1, 19452), (2, 678), (3, 1)]
|
||||
"""
|
||||
|
||||
D = DiscreteGaussianDistributionIntegerSampler(sigma)
|
||||
samples = []
|
||||
|
||||
for i in range(number_samples):
|
||||
if q:
|
||||
samples.append(D() % q)
|
||||
else:
|
||||
samples.append(D())
|
||||
# now create a histogram
|
||||
hist = []
|
||||
for val in set(samples):
|
||||
hist.append((val, samples.count(val)))
|
||||
|
||||
# sort (values)
|
||||
hist.sort(key=lambda x:x[0])
|
||||
return hist
|
||||
|
||||
|
||||
def test_uniform(number_samples, q):
|
||||
"""
|
||||
TODO: actually use a _rounded_ gaussian to match Concrete
|
||||
|
||||
A function which simulates sampling from a Discrete Gaussian distribution
|
||||
:param sigma: the standard deviation
|
||||
:param number_samples: the number of samples to draw
|
||||
|
||||
returns: a list of (value, count) pairs (essentially a histogram)
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
sage: X = test_rounded_gaussian(2/3, 100000)
|
||||
sage: X
|
||||
[(-3, 2), (-2, 714), (-1, 19495), (0, 59658), (1, 19452), (2, 678), (3, 1)]
|
||||
"""
|
||||
|
||||
samples = []
|
||||
|
||||
for i in range(number_samples):
|
||||
samples.append(round(uniform(0, q)))
|
||||
# now create a histogram
|
||||
hist = []
|
||||
for val in set(samples):
|
||||
hist.append((val, samples.count(val)))
|
||||
|
||||
# sort (values)
|
||||
hist.sort(key=lambda x: x[0])
|
||||
return hist
|
||||
|
||||
# dual bug example
|
||||
# n = 256; q = 2**32; sd = 2**(-4); reduction_cost_model = BKZ.sieve
|
||||
# _ = estimate_lwe(n, alpha, q, reduction_cost_model)
|
||||
@@ -550,7 +477,7 @@ def test_params(n, q, sd, secret_distribution):
|
||||
sd = sd * q
|
||||
alpha = RR(sqrt(2*pi) * sd / q)
|
||||
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = secret_distribution, reduction_cost_model = BKZ.sieve, skip = ("arora-gb", "bkw", "mitm", "dec"))
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = secret_distribution, reduction_cost_model = est.BKZ.sieve, skip = ("arora-gb", "bkw", "mitm", "dec"))
|
||||
|
||||
return est
|
||||
|
||||
@@ -564,10 +491,10 @@ def generate_iso_lines(N = [256, 2048], SD = [0, 32], q = 2**32):
|
||||
sd = 2**sd
|
||||
alpha = sqrt(2*pi) * sd / q
|
||||
try:
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = (0,1), reduction_cost_model = BKZ.sieve, skip = ("bkw", "mitm", "arora-gb", "dec"))
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = (0,1), reduction_cost_model = est.BKZ.sieve, skip = ("bkw", "mitm", "arora-gb", "dec"))
|
||||
est = get_security_level(est, 2)
|
||||
except:
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = (0,1), reduction_cost_model = BKZ.sieve, skip = ("bkw", "mitm", "arora-gb", "dual", "dec"))
|
||||
est = estimate_lwe(n, alpha, q, secret_distribution = (0,1), reduction_cost_model = est.BKZ.sieve, skip = ("bkw", "mitm", "arora-gb", "dual", "dec"))
|
||||
est = get_security_level(est, 2)
|
||||
RESULTS.append((n, sd, est))
|
||||
|
||||
@@ -578,17 +505,14 @@ def plot_iso_lines(results):
|
||||
|
||||
x1 = []
|
||||
x2 = []
|
||||
x3 = []
|
||||
|
||||
for z in results:
|
||||
x1.append(z[0])
|
||||
# use log(q)
|
||||
# use -ve values to match Pascal's diagram
|
||||
x2.append(-1 * log(z[1],2))
|
||||
x3.append(z[3])
|
||||
x2.append(z[2])
|
||||
|
||||
plt.scatter(x1, x2, c = x3)
|
||||
plt.colorbar()
|
||||
plt.plot(x1, x2)
|
||||
|
||||
return plt
|
||||
|
||||
@@ -604,7 +528,6 @@ def test_multiple_sd(n, q, secret_distribution, reduction_cost_model, split = 33
|
||||
es = estimate_lwe(n=512, alpha=alpha, q=q, secret_distribution=(0, 1), reduction_cost_model = reduction_cost_model,
|
||||
skip=("bkw", "mitm", "dec", "arora-gb"), m = m)
|
||||
except:
|
||||
print("except")
|
||||
es = estimate_lwe(n=512, alpha=alpha, q=q, secret_distribution=(0, 1), reduction_cost_model = reduction_cost_model,
|
||||
skip=("bkw", "mitm", "dec", "arora-gb", "dual"), m = m)
|
||||
est.append(get_security_level(es,2))
|
||||
@@ -612,133 +535,183 @@ def test_multiple_sd(n, q, secret_distribution, reduction_cost_model, split = 33
|
||||
return est, Y
|
||||
|
||||
|
||||
def output_secret_distribution(m):
|
||||
"""
|
||||
generate the correct secret_distirbution for the given input
|
||||
:param m: the number of elements in the secret distribution
|
||||
## parameter curves
|
||||
|
||||
def get_parameter_curves_data_sd(sec_levels, sd_range, q):
|
||||
|
||||
Results = []
|
||||
for sec in sec_levels:
|
||||
try:
|
||||
result_sec = generate_parameter_matrix_sd(n = None, sd_range=sd_range, q=q, reduction_cost_model=est.BKZ.sieve,
|
||||
secret_distribution=(0,1), target_security=sec)
|
||||
Results.append(result_sec)
|
||||
except:
|
||||
pass
|
||||
|
||||
return Results
|
||||
|
||||
|
||||
def get_parameter_curves_data_n(sec_levels, n_range, q):
|
||||
|
||||
Results = []
|
||||
for sec in sec_levels:
|
||||
try:
|
||||
result_sec = generate_parameter_matrix(n_range, sd = None, q=q, reduction_cost_model=est.BKZ.sieve,
|
||||
secret_distribution=(0,1), target_security=sec)
|
||||
Results.append(result_sec)
|
||||
except:
|
||||
pass
|
||||
|
||||
return Results
|
||||
|
||||
|
||||
def interpolate_result(result, log_q):
|
||||
|
||||
import numpy as np
|
||||
# linear function interpolation
|
||||
x = []
|
||||
y = []
|
||||
|
||||
# 1. filter out any points which reccomend sd = -log(q) + 2
|
||||
new_result= []
|
||||
for res in result:
|
||||
if res[2] >= - log_q + 2:
|
||||
new_result.append(res)
|
||||
|
||||
result = new_result
|
||||
for res in result:
|
||||
x.append(res[0])
|
||||
y.append(res[2])
|
||||
|
||||
|
||||
(a,b) = np.polyfit(x, y, 1)
|
||||
|
||||
return (a,b)
|
||||
|
||||
|
||||
def plot_interpolants(interpolants, n_range, log_q, degree = 1):
|
||||
for x in interpolants:
|
||||
if degree == 1:
|
||||
vals = [x[0] * n + x[1] for n in range(n_range[0],n_range[1])]
|
||||
elif degree == 2:
|
||||
vals = [x[0] * n**2 + x[1]*n + x[2] for n in range(n_range[0],n_range[1])]
|
||||
# any values which fall outside of the range and edited to give at least two bits of noise.
|
||||
|
||||
vvals = []
|
||||
for v in vals:
|
||||
if v < -log_q + 2:
|
||||
vvals.append(-log_q + 2)
|
||||
else:
|
||||
vvals.append(v)
|
||||
|
||||
plt.plot(range(n_range[0], n_range[0] + len(vvals)), vvals)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
## currently running
|
||||
# sage: n_range = (256, 2048, 16)
|
||||
# sage: sec_levels = [80 + 16*k for k in range(0,12)]
|
||||
# sage: results = get_parameter_curves_data_n(sec_levels, n_range, q = 2**64)
|
||||
|
||||
def verify_results(results, security_level, secret_distribution = (0,1), reduction_cost_model = est.BKZ.sieve):
|
||||
""" A function which verifies that a set of results match a given security level
|
||||
:param results : a set of tuples of the form (n, q, sd)
|
||||
:param security_level: the target security level for these params
|
||||
"""
|
||||
|
||||
# the code doesn't work for m < 2
|
||||
assert m >= 2
|
||||
estimates = []
|
||||
|
||||
if m % 2 ==1:
|
||||
# m is odd
|
||||
b = (m - 1)/2
|
||||
secret_distribution = (-b, b)
|
||||
else:
|
||||
# m is even
|
||||
b = m / 2 - 1
|
||||
secret_distribution = (-b, b + 1)
|
||||
# 1. Grab the parameters
|
||||
for (n, q, sd) in results:
|
||||
if sd is not None:
|
||||
sd = 2**sd
|
||||
alpha = sqrt(2*pi) * sd
|
||||
|
||||
return secret_distribution
|
||||
|
||||
def get_marcs_curves(n_range, q, m_max):
|
||||
|
||||
# the final result will be a list of m_max elements, each containing
|
||||
# a parameter matrix
|
||||
RESULTS = []
|
||||
|
||||
for m in range(2, m_max + 1):
|
||||
secret_distribution = output_secret_distribution(m)
|
||||
result_m = generate_parameter_matrix(n_range, sd=None, q=q, reduction_cost_model=BKZ.sieve,
|
||||
secret_distribution=secret_distribution, target_security=128)
|
||||
RESULTS.append(result_m)
|
||||
return RESULTS
|
||||
|
||||
|
||||
def get_marcs_curves_n(sd_range, q, m_max):
|
||||
|
||||
# the final result will be a list of m_max elements, each containing
|
||||
# a parameter matrix
|
||||
RESULTS = []
|
||||
|
||||
for m in range(2, m_max + 1):
|
||||
secret_distribution = output_secret_distribution(m)
|
||||
result_m = generate_parameter_matrix_sd(n = None, sd_range=sd_range, q=q, reduction_cost_model=BKZ.sieve,
|
||||
secret_distribution=secret_distribution, target_security=128)
|
||||
RESULTS.append(result_m)
|
||||
return RESULTS
|
||||
|
||||
|
||||
def tabulate_results(results):
|
||||
""" Put the results from get_marcs_curves into a LaTeX table
|
||||
"""
|
||||
|
||||
new_results = []
|
||||
num_results = len(results[0])
|
||||
num_entries = len(results)
|
||||
|
||||
key = []
|
||||
key.append("n")
|
||||
key.append("q")
|
||||
for i in range(num_entries):
|
||||
key.append("m = {}".format(i + 2))
|
||||
|
||||
new_results.append(key)
|
||||
|
||||
|
||||
|
||||
|
||||
for j in range(num_results):
|
||||
result_j = []
|
||||
result_j.append(results[0][j][0])
|
||||
result_j.append(int(log(results[0][0][1],2)))
|
||||
|
||||
for i in range(num_entries):
|
||||
result_j.append(int(results[i][j][2]))
|
||||
|
||||
new_results.append(result_j)
|
||||
|
||||
return new_results
|
||||
|
||||
def tabulate_results_sd(results):
|
||||
|
||||
new_results = []
|
||||
num_results = len(results[0])
|
||||
num_entries = len(results)
|
||||
|
||||
key = []
|
||||
key.append("sd")
|
||||
key.append("q")
|
||||
|
||||
for i in range(num_entries):
|
||||
key.append("m = {}".format(i + 2))
|
||||
|
||||
new_results.append(key)
|
||||
|
||||
for j in range(num_results):
|
||||
result_j = []
|
||||
result_j.append(results[0][j][2])
|
||||
result_j.append(int(log(results[0][0][1],2)))
|
||||
|
||||
for i in range(num_entries):
|
||||
# 2. Test that these parameters satisfy the given security level
|
||||
try:
|
||||
result_j.append(int(results[i][j][0]))
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo, skip = {"bkw","dec","arora-gb","mitm"})
|
||||
except:
|
||||
result_j.append(str(results[i][j][0]))
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo,
|
||||
skip={"bkw", "dec", "arora-gb", "mitm", "dual"})
|
||||
|
||||
estimates.append(estimate)
|
||||
|
||||
new_results.append(result_j)
|
||||
return estimates
|
||||
|
||||
return new_results
|
||||
|
||||
# code to cross-check the security levels for marc/pascal results
|
||||
# sage: with open("results_32_128.txt", "rb") as fp: # Unpickling
|
||||
# ....: ... X = pickle.load(fp)
|
||||
# res = []
|
||||
# sage: for i in range(len(X)):
|
||||
# ....: x = X[i]
|
||||
# ....: m = i + 2
|
||||
# ....: secret_distribution = output_secret_distribution(m)
|
||||
# ....: for (n, q, sd) in x:
|
||||
# ....: if n is not None:
|
||||
# ....: sd = 2**(sd)
|
||||
# ....: alpha = sqrt(2*pi) * sd
|
||||
# ....: print((n, q, sd))
|
||||
# ....: try:
|
||||
# ....: _ = estimate_lwe(n, alpha, q, secret_distribution = secret_distribution, reduction_cost_model = BKZ.sieve, skip = ("arora-gb", "mitm", "bkw", "dec"))
|
||||
# ....: except:
|
||||
# ....: _ = estimate_lwe(n, alpha, q, secret_distribution = secret_distribution, reduction_cost_model = BKZ.sieve, skip = ("arora-gb", "mitm", "bkw", "dec", "dual"))
|
||||
# ....: else:
|
||||
# ....: print("None")
|
||||
# ....: res.append(get_security_level(_))
|
||||
# ....:print(min(res))
|
||||
def verify_interpolants(interpolant, n_range, log_q, secret_distribution = (0,1), reduction_cost_model = est.BKZ.sieve):
|
||||
|
||||
estimates = []
|
||||
q = 2**log_q
|
||||
(a, b) = interpolant
|
||||
|
||||
for n in range(n_range[0], n_range[1]):
|
||||
print(n)
|
||||
# we take the max here to ensure that the "cut-off" for the minimal error is met.
|
||||
sd = max(a * n + b, -log_q + 2)
|
||||
sd = 2 ** sd
|
||||
alpha = sqrt(2*pi) * sd
|
||||
|
||||
try:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo, skip = {"bkw","dec","arora-gb","mitm"})
|
||||
except:
|
||||
estimate = estimate_lwe(n, alpha, q, secret_distribution=secret_distribution,
|
||||
reduction_cost_model=reduction_cost_model, m=oo,
|
||||
skip={"bkw", "dec", "arora-gb", "mitm", "dual"})
|
||||
estimates.append(get_security_level(estimate))
|
||||
|
||||
return estimates
|
||||
|
||||
def get_zama_curves():
|
||||
|
||||
# hardcode the parameters for now
|
||||
n_range = [128, 2048, 32]
|
||||
sec_levels = [80 + 16*k for k in range(0,12)]
|
||||
results = get_parameter_curves_data_n(sec_levels, n_range, q = 2**64)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def test_curves():
|
||||
|
||||
# a small hardcoded example for testing purposes
|
||||
|
||||
n_range = [256, 1024, 128]
|
||||
sec_levels = [80, 128, 256]
|
||||
results = get_parameter_curves_data_n(sec_levels, n_range, q = 2**64)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
## we start with 80/128/192/256-bits of security
|
||||
|
||||
## lambda = 80
|
||||
## z = verify_interpolants(interps[0], (128,2048), 64)
|
||||
## i = 0
|
||||
## min(z[i:]) = 80.36
|
||||
## so the model is sd(n) = max(-0.04047677865612648 * n + 1.1433465085639063, log_q - 2), n >= 128
|
||||
|
||||
|
||||
## lambda = 128
|
||||
## z = verify_interpolants(interps[3], (128,2048), 64)
|
||||
## i = 83
|
||||
## min(z[i:]) = 128.02
|
||||
## so the model is sd(n) = max(-0.026374888765705498 * n + 2.012143923330495, log_q - 2), n >= 211 ( = 128 + 83)
|
||||
|
||||
|
||||
## lambda = 192
|
||||
## z = verify_interpolants(interps[7], (128,2048), 64)
|
||||
## i = 304
|
||||
## min(z[i:]) = 192.19
|
||||
## so the model is sd(n) = max(-0.018504919354426233 * n + 2.6634073426215843, log_q - 2), n >= 432 ( = 128 + 212)
|
||||
|
||||
|
||||
## lambda = 256
|
||||
## z = verify_interpolants(interps[-1], (128,2048), 64)
|
||||
## i = 653
|
||||
## min(z[i:]) = 256.25
|
||||
## so the model is sd(n) = max(-0.014327640360322604 * n + 2.899270827311091), log_q - 2), n >= 781 ( = 128 + 653)
|
||||
|
||||
Reference in New Issue
Block a user