From 4eca16bf95b918f700535e055fda98da41fc28e1 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 21 Jun 2021 16:44:34 +0100 Subject: [PATCH] update code add results --- results/results_32_128.txt | Bin 0 -> 4914 bytes results/results_64_128.txt | Bin 0 -> 11256 bytes scripts.py | 234 ++++++++++++++++++++++++++++++++++--- 3 files changed, 220 insertions(+), 14 deletions(-) create mode 100644 results/results_32_128.txt create mode 100644 results/results_64_128.txt diff --git a/results/results_32_128.txt b/results/results_32_128.txt new file mode 100644 index 0000000000000000000000000000000000000000..29b1df5412fbd41ca5b74b507aad4a604850ea14 GIT binary patch literal 4914 zcmZwLWq2J`5C-7XU2zXytQ072gB~bQpjeU6lyaMs7T2@ltvb3yst|S-L z@6oYau7keFS8rd3>sq&xuY8Ts`I_zWwc5NuL7Xf#`* zx*Qd1G)JO(j;6&L&6TLWqp68T^CW8EXiBJ>FHu8BlS8yXqDGD;kse$qQDa9FCGpR- zNTMc=#wS{}SfZwm#)W8!M9mzHjkRj2M9m$IA&r(vw1cD3lKA$^CEC%^s1U7?XeUP_ z5{gLe)Bn_HfiMMC&Em z(@~#raDzm9If_EnMv3-z)GI`rB-+POk8p6aM1_t@L$pPreI1pAXsbl~<%;tAdtk-# z7yP`iasVr+)Cg7%uyU$Z04t}p<(~~kPWOL=4PqN-cpHV%fpge6lOeOZAg)C4;$w*ghUU*MjM6@YXln?@X!bmY+T4TNULDu zBDNukZx0)78A75}uyHX%h&6(ZOL%C62sSQd8>CgR(T;6M;@iWfL{Vzu zdN$F)n+OMCqL={`OU4agq9X%HG=hm6I4aZ#COWYR(g-GQWD}D3_X{R+3?R`enCQ&I zA=U^cO4vk*V4@3~AgzLlQZ^xpZx0h)89<^{Fwu>NL#z=@bY~MGf{7k%g0u=I%GiV? zzCBFzWB`d)!9*`R9AF~PCc;6OhCH8ChPF_=vZVH4>l0TV+xB54*(3}XNl8o@-&ktF{8f{Eb_ zAkiwA7-26Am>6j<444>YFASI%%_c&7m>6R(444>eFASI%XDCT>ej+@6}aBQn0SsaidZu41ryJ+ ziBJU-FJw);=%`z$f{B+Lbq*0syqubNB{lJCYT`9E@wzt=%SnC+n0O;=;!QSDtW_}a zmR%lT;%&P;z{ERtd4P#`?eYK+0VY1Q%L7b&WS0k+_&96g z6T3XX#HV(7fQirS@&FT`+vNc!zTo8{ysI$rrClCi;w!s6z{J;fd4P#;vL?QD)KfkU zuMl(MJG(r<#P|NAhJ_ze3qPh7eo8I;%ocw69}Bje3mn}%*+rz?49tMe4!NRPph1qN& z)+)@0Ic$M6f`z$kK@#5{7UpFw%+Fd_U>8YPSjbC5tnFc85nBlDVPSFB!VUj zizF;8%UW2TT3C@3JNkDqH23>kj1c@4R8sJ1tw!MNrzVQ&<%s#Vz-XnirqSPD|X9$ z*Ylib?ep39`VY?6ciwgOhWq=>-rRhl4oz(~?a;Kqrm4GZUYqdG8C_57*x1f@>fEtw zyH1_EHFj+DOP+t)xs9jlqG`e7m$A8y4XyrZT4-?7!bdhOa?m65=g%M7w5V+>!m>7J zFLKbMpv8>Ziyi|lZUhNakAs#--Rx3RPk@#*>LPj)w3JaIdJ433>WaCdr$NgYHH)4B zEosK&u)hqE|tyrEY2=dJVL?5hSdC9kfR3revCW1GHx9CRd_2L2DT~ z(OaOkQ#Yv)y$xE&2ol!616ntA6EjV{3rbQqp%T3ZTF=Od-UqFpy77hR1JDLWiKqf? zn7VPf=tIy(sT*5~J_2oQQuGPP{!EWaM4y5-OI>p=`V6#r>PDBM&p}(H zZd9E50<>l7Mn?J)v{mXxINkUas9oxYL&E#@HE8S9U0Q1D8&E^)E{XIlXq(gx%{BEM zXxr2caiZ@*+of(WB&?qY+CFuIBK-i`A$0>v-S{JD$JF)DML&UdN?ji5XVA{6>lf)4 z&@QR#gZsjXzk+s6UC%i68)&!G^@#L4X!q1z7;pRov`6ZEoca^=pVW1U^cQH))SVx1 z{2Sy_*D2CJpuJMpG19-Fy&F3;?GrLK2mir-Ubbjoqb?%0Xg{Mw#1`#uNtr8Ri&CRp z#1M8p;yY2nF5Y|&9xnM%YK9c`3}*rH>sGNp(uI@Tx=u|>yOcnT3)bi5HH z{PAInPO$J~nqrGiw91qsw&*0IM8p=IY~d+HY*7azNLbGnonqn1G{qL3YL%%(Y*A+9 zL?7Uf&uJE(Lc|uGZUhPI*`hNnJej80qBE^Bm542BG;$)g=qw9QA!3U<8bQK(w&-kY zQ6#pglZB_$jcn057M@(h7M*M1aU!MO|d$cfmVX%?DN#P&=#NT znS~}7u|1a?LBe{r=L!o=rYW}PN()UcVtcN#haM+ld#<+jL}GicvG!mntY>?!wa}Eh zk?pz8LX(Twp6l(QClcFpgSE$LitV}4+5-ve*`Av$G^M84o|`Q+xrptVV-G!%*q&Rg zJx)_>&#l%TNLbJI+?Kk&G$Xd>_SE%`Q*6&2_RtfF?YT2`-Q$gH&t0kO7N^*ryHnQ` zr`Vo*Qr9_7u|4;u?wm+$&wZgTY|j0)<~&eq&V$yRheC7WdN!vtivM$Ga~`&IRM>Aj z*_=m=nni5Rqef1|<~(Ku3GWx1^SISyj;7e0CyX)?oAabmTM?V{lm(^`u{lp0LBe`A z=NSu3t|>O>Sqn@hVsoA|aw0b8c?(P-Vsl=DcfxDMf6~dq#J~B!~ zY|h8l94BIPKC$LN!g@C6QwvO~DK_Ubd$`F(Y|iJ_oJefW7uFo7DK_UzYYrr=XLG)? zz?7O|bH28Rn_R@^d}Gat#O8c!&2gGybH20YK*D-9=X(oGsVO#RUh9V&Hs=RxPP~!L z`OzM3a^1-0{FJ(j;uM?nvpw9zDK_U9d$@_j=KN~Si8r!2zqS5U#pe8;y0haHoAXDl zIe*rg^H;4oe_M0@3C+oHr@d@8=U<~l#OBPmbj%f@Ilj#TZQ7XTQe?+3Ky8qsJbpoF zQArUWzYw*MqCb9NYI`XXE~IFh zPpH6f8nWisgN`aSi?aFkp|wwLh@0O4IwIFB`sO!;);_->aegD{FpP%NP&vObwDu_u zq4S$ShnCul*7;4LLvkr{=Qo4aKF*G4YWs`MG5`3&*LOVu982wJBv5kJ`mMeS=^t-fN;gg`>)vg*l_}%Q6(8<^&bkgr`Y#O&C zm3|NC>=JD6J!|J z)^b1S%u=(g<^I$}%37w-8M&0TJb(%ef7)2f1EJG1&9asUL8p~c*79I#B4sTPf!01R zvX+NZF&a)|Ef0fE$+UsBJRCZ?lCqZVsZPpT9s!+HNLkAxslad=Yk3rOVy0Qv@@VLU zO3GRuLv>Qt@>uBjLdsemM+Jt{Sj*#~<8sZimM1{RR#MjTM5>drmM1~S6jIjmWGXP6 z##(lOHs_jUEl+`tE~TvHsnFWD>#Su49T_*UmZw2SIBj4pPlpZ%hM$48JOf($rk%As z6I%P+$yzo-hsM)b%d?q8f$qrbYKa#pMkaP1RW5SwLAyfKi4d4c`h_} zQr7Z3Xg^?hZLH<_&^}RF%g)fAxi+wt7eIT&S=O=(v|F5IEt{Y|&a##s%It)nfwk-k zJvYv>mffIdMP)57G_BRLd&?DT*`wu(wY3PmrzTGMRq1@*~|EUYuOt*dyZyV z%Rbah%3AiNww1D${h&oDWi2nJ=2F%&r#47g%l^<=rIfWCKy^~qav*eOA!RKGQGwxI zW-SLpXJndXEr&p-S5nq;DAh?>%S)is3Mp%ODHRw_V=ae4>uWh2I;GME)^Y^ZNm|O5T26x2zJy~fCsPy6vX)bzV{$2LIh6_wr?HmPptUdLSj*|q(QyN7IRiS% zX)kLz6I%ObjIs_PA8*6zb zbWo{T*77Q7eJ!ts4#+jjT3!R~@1(5dwNQ?R(^$*vpnb`vtmXC4-cec08=yV0Hf&%m zZ-jP_v#jM!(Aqb7tmVzn`dZF`UJ&=PmbXA_U+J-yx0;47vXZy8T>U-Y{vQ+m_LeJF z@{X1(R`O1}vP#}%zx2;?WL^beNSVEBOVqzLH-;d&gN;@+;^?Tw!}z$*-Z^<18!r4Ya z20l}M2kjg;u#(?H>nl0Wv{uOFW@O8!9whWDJ6{1aOH8xcNB{zc8SftCE5+E&U+{sXPA 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"}) + 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"}) security_level = get_security_level(estimate) - n += 1 + if (-1 * sd > log(q, 2)): + print("target security level is unatainable") + break - print("the finalised parameters are {}, {}, with a security level of {}".format(n, q, security_level)) + # final estimate (we went too far in the above loop) + 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"}) + 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"}) + security_level = get_security_level(estimate) + + print("the finalised parameters are n = {}, log2(sd) = {}, log2(q) = {}, with a security level of {}-bits".format(n, + sd, + log(q, + 2), + security_level)) + + # final sanity check so we don't return insecure (or inf) parameters + if security_level < target_security or security_level == oo: + n = None + + return n - return ZZ(n) def automated_param_select_sd(n, sd=None, q=2**32, reduction_cost_model=BKZ.sieve, secret_distribution=(0, 1), @@ -357,7 +404,7 @@ def generate_parameter_matrix(n_range, sd=None, q=2**32, reduction_cost_model=BK sd_ = sd - for n in range(n_min, n_max): + for n in range(n_min, n_max + 1): 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 @@ -366,6 +413,40 @@ 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, + 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: 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 + :param secret_distribution: the LWE secret distribution + :param target_security: the target number of bits of security, 128 is default + + TODO: we should probably parallelise this function for speed + TODO: code seems to fail when the initial estimate is < target_security bits + + EXAMPLE: + sage: X = generate_parameter_matrix([788, 790]) + sage: X + [(788, 4294967296, -20.0), (789, 4294967296, -20.0)] + """ + + RESULTS = [] + + # grab min and max value/s of n + (sd_min, sd_max) = sd_range + + n = n + + for sd in range(sd_min, sd_max + 1): + n = automated_param_select_n(sd, n=n, q=q, reduction_cost_model=reduction_cost_model, + secret_distribution=secret_distribution, target_security=target_security) + RESULTS.append((n, q, sd)) + + return RESULTS + + def generate_parameter_step(results, label = None, torus_sd = True): """ Plot results @@ -473,6 +554,7 @@ def test_params(n, q, sd, secret_distribution): return est + def generate_iso_lines(N = [256, 2048], SD = [0, 32], q = 2**32): RESULTS = [] @@ -491,6 +573,7 @@ def generate_iso_lines(N = [256, 2048], SD = [0, 32], q = 2**32): return RESULTS + def plot_iso_lines(results): x1 = [] @@ -529,10 +612,133 @@ def test_multiple_sd(n, q, secret_distribution, reduction_cost_model, split = 33 return est, Y -def estimate_lwe_sd(n, sd, q, secret_distribution, reduction_cost_model, skip = ("bkw","mitm","dec","arora-gb"), m = oo): +def output_secret_distribution(m): + """ + generate the correct secret_distirbution for the given input + :param m: the number of elements in the secret distribution + """ - alpha = sqrt(2*pi) * sd/q - x = estimate_lwe(n = n, alpha = alpha , q = q, m = m, secret_distribution = secret_distribution, reduction_cost_model = reduction_cost_model, skip = skip) + # the code doesn't work for m < 2 + assert m >= 2 - return x + 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) + 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): + try: + result_j.append(int(results[i][j][0])) + except: + result_j.append(str(results[i][j][0])) + + new_results.append(result_j) + + 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)) \ No newline at end of file