From 73169e7f03c8cc431056b69ca304fb93d431f9a1 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 9 Aug 2021 13:01:04 +0100 Subject: [PATCH] remove files which are not needed --- Makefile | 20 -- __init__.py | 2 - __pycache__/__init__.cpython-37.pyc | Bin 173 -> 0 bytes __pycache__/estimator.cpython-37.pyc | Bin 93391 -> 0 bytes bitbucket-pipelines.yml | 31 --- bkw_legacy.py | 315 --------------------------- doctest.sh | 12 - fix-doctest.sh | 13 -- pyproject.toml | 2 - readthedocs.yml | 1 - requirements.txt | 2 - 11 files changed, 398 deletions(-) delete mode 100644 Makefile delete mode 100644 __init__.py delete mode 100644 __pycache__/__init__.cpython-37.pyc delete mode 100644 __pycache__/estimator.cpython-37.pyc delete mode 100644 bitbucket-pipelines.yml delete mode 100644 bkw_legacy.py delete mode 100755 doctest.sh delete mode 100755 fix-doctest.sh delete mode 100644 pyproject.toml delete mode 100644 readthedocs.yml delete mode 100644 requirements.txt diff --git a/Makefile b/Makefile deleted file mode 100644 index 757cd2dd3..000000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = LWEEstimator -SOURCEDIR = doc -BUILDDIR = doc/_build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/__init__.py b/__init__.py deleted file mode 100644 index a8977649b..000000000 --- a/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -from estimator import * # noqa diff --git a/__pycache__/__init__.cpython-37.pyc b/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index d11121607bc2e60d83eba762946bb7e1b663121b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmZ?b<>g`k0+WA}6U>41V-N=hn1BoiATH(s5-AKRj5!P;3@J>(44TX@fg%i=jJFuI z{D359YH>+sZemG((MpCQ7N886_+_IXTAW%`te=#cr|*(loL!P%pzoepl2MwZUyxXo rn5$cynv2KczG$)ehv0&mj8%V^l0` diff --git a/__pycache__/estimator.cpython-37.pyc b/__pycache__/estimator.cpython-37.pyc deleted file mode 100644 index 0229024a5b51c0743aacdebc018d9b6f3ad8c7ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93391 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 yVq*V=RIcN(@ORe>sdRt7 - -""" -from collections import OrderedDict -from estimator import cost_reorder, stddevf, sigmaf -from estimator import preprocess_params, amplify_sigma, secret_distribution_variance -from sage.functions.log import log -from sage.functions.other import ceil, sqrt -from sage.matrix.all import Matrix -from sage.modules.all import vector -from sage.rings.all import RealField -from sage.rings.all import ZZ -from sage.rings.infinity import PlusInfinity -from sage.structure.element import parent -from sage.symbolic.all import pi - - -oo = PlusInfinity() - - -def bkw_decision(n, alpha, q, success_probability=0.99, prec=None): - """ - Estimate the cost of running BKW to solve Decision-LWE following [DCC:ACFFP15]_. - - :param n: dimension > 0 - :param alpha: fraction of the noise α < 1.0 - :param q: modulus > 0 - :param success_probability: probability of success < 1.0 - :param prec: precision used for floating point computations - :param m: the number of available samples - - .. [DCC:ACFFP15] Albrecht, M. R., Cid, C., Jean-Charles Faugère, Fitzpatrick, R., & - Perret, L. (2015). On the complexity of the BKW algorithm on LWE. - Designs, Codes & Cryptography, Volume 74, Issue 2, pp 325-354 - """ - n, alpha, q, success_probability = preprocess_params(n, alpha, q, success_probability) - sigma = alpha*q - - RR = parent(alpha) - - def _run(t): - a = RR(t*log(n, 2)) # target number of adds: a = t*log_2(n) - b = RR(n/a) # window width - sigma_final = RR(n**t).sqrt() * sigma # after n^t adds we get this σ - - m = amplify_sigma(success_probability, sigma_final, q) - - tmp = a*(a-1)/2 * (n+1) - b*a*(a-1)/4 - b/6 * RR((a-1)**3 + 3/2*(a-1)**2 + (a-1)/2) - stage1a = RR(q**b-1)/2 * tmp - stage1b = m * (a/2 * (n + 2)) - stage1 = stage1a + stage1b - - nrops = RR(stage1) - nbops = RR(log(q, 2) * nrops) - ncalls = RR(a * ceil(RR(q**b)/RR(2)) + m) - nmem = ceil(RR(q**b)/2) * a * (n + 1 - b * (a-1)/2) - - current = OrderedDict([(u"t", t), - (u"bop", nbops), - (u"oracle", ncalls), - (u"m", m), - (u"mem", nmem), - (u"rop", nrops), - (u"a", a), - (u"b", b), - ]) - - current = cost_reorder(current, ("rop", u"oracle", u"t")) - return current - - best_runtime = None - t = RR(2*(log(q, 2) - log(sigma, 2))/log(n, 2)) - while True: - current = _run(t) - if not best_runtime: - best_runtime = current - else: - if best_runtime["rop"] > current["rop"]: - best_runtime = current - else: - break - t += 0.05 - - return best_runtime - - -def bkw_search(n, alpha, q, success_probability=0.99, prec=None): - """ - Estimate the cost of running BKW to solve Search-LWE following [C:DucTraVau15]_. - - :param n: dimension > 0 - :param alpha: fraction of the noise α < 1.0 - :param q: modulus > 0 - :param success_probability: probability of success < 1.0 - :param prec: precision used for floating point computations - - .. [EC:DucTraVau15] Duc, A., Florian Tramèr, & Vaudenay, S. (2015). Better algorithms for - LWE and LWR. - """ - n, alpha, q, success_probability = preprocess_params(n, alpha, q, success_probability) - sigma = stddevf(alpha*q) - eps = success_probability - - RR = parent(alpha) - - # "To simplify our result, we considered operations over C to have the same - # complexity as operations over Z_q . We also took C_FFT = 1 which is the - # best one can hope to obtain for a FFT." - c_cost = 1 - c_mem = 1 - c_fft = 1 - - def _run(t): - a = RR(t*log(n, 2)) # target number of adds: a = t*log_2(n) - b = RR(n/a) # window width - epp = (1- eps)/a - - m = lambda j, eps: 8 * b * log(q/eps) * (1 - (2 * pi**2 * sigma**2)/(q**2))**(-2**(a-j)) # noqa - - c1 = (q**b-1)/2 * ((a-1)*(a-2)/2 * (n+1) - b/6 * (a*(a-1) * (a-2))) - c2 = sum([m(j, epp) * (a-1-j)/2 * (n+2) for j in range(a)]) - c3 = (2*sum([m(j, epp) for j in range(a)]) + c_fft * n * q**b * log(q, 2)) * c_cost - c4 = (a-1)*(a-2) * b * (q**b - 1)/2 - - nrops = RR(c1 + c2 + c3 + c4) - nbops = RR(log(q, 2) * nrops) - ncalls = (a-1) * (q**b - 1)/2 + m(0, eps) - nmem = ((q**b - 1)/2 * (a-1) * (n + 1 - b*(a-2)/2)) + m(0, eps) + c_mem * q**b - - current = OrderedDict([(u"t", t), - (u"bop", nbops), - (u"oracle", ncalls), - (u"m", m(0, eps)), - (u"mem", nmem), - (u"rop", nrops), - (u"a", a), - (u"b", b), - ]) - - current = cost_reorder(current, ("rop", u"oracle", u"t")) - return current - - best_runtime = None - best = None - t = RR(2*(log(q, 2) - log(sigma, 2))/log(n, 2)) - while True: - current = _run(t) - - if not best_runtime: - best_runtime = current - else: - if best_runtime["rop"] > current["rop"]: - best_runtime = current - else: - break - t += 0.05 - - return best - - -def bkw_small_secret_variances(q, a, b, kappa, o, RR=None): - """ - Helper function for small secret BKW variant. - - :param q: - :param a: - :param b: - :param kappa: - :param o: - :param RR: - :returns: - :rtype: - - """ - if RR is None: - RR = RealField() - q = RR(q) - a = RR(a).round() - b = RR(b) - n = a*b - kappa = RR(kappa) - T = RR(2)**(b*kappa) - n = RR(o)/RR(T*(a+1)) + RR(1) - - U_Var = lambda x: (x**2 - 1)/12 # noqa - red_var = 2*U_Var(q/(2**kappa)) - - if o: - c_ = map(RR, [0.0000000000000000, - 0.4057993538687922, 0.6924478992819291, 0.7898852691349439, - 0.8441959360364506, 0.8549679124679972, 0.8954469872316165, - 0.9157093365103325, 0.9567635780119543, 0.9434245442818547, - 0.9987153221343770]) - - M = Matrix(RR, a, a) # rows are tables, columns are entries those tables - for l in range(M.ncols()): - for c in range(l, M.ncols()): - M[l, c] = U_Var(q) - - for l in range(1, a): - for i in range(l): - M[l, i] = red_var + sum(M[i+1:l].column(i)) - - bl = b*l - if round(bl) < len(c_): - c_tau = c_[round(bl)] - else: - c_tau = RR(1)/RR(5)*RR(sqrt(bl)) + RR(1)/RR(3) - - f = (c_tau*n**(~bl) + 1 - c_tau)**2 - for i in range(l): - M[l, i] = M[l, i]/f - - v = vector(RR, a) - for i in range(a): - v[i] = red_var + sum(M[i+1:].column(i)) - else: - v = vector(RR, a) - for i in range(a)[::-1]: - v[i] = 2**(a-i-1) * red_var - - return v - - -def bkw_small_secret(n, alpha, q, secret_distribution=True, success_probability=0.99, t=None, o=0, samples=None): # noqa - """ - :param n: number of variables in the LWE instance - :param alpha: standard deviation of the LWE instance - :param q: size of the finite field (default: n^2) - """ - - def sigma2f(kappa): - v = bkw_small_secret_variances(q, a, b, kappa, o, RR=RR) - return sigmaf(sum([b * e * secret_variance for e in v], RR(0)).sqrt()) - - def Tf(kappa): - return min(q**b, ZZ(2)**(b*kappa))/2 - - def ops_tf(kappa): - T = Tf(kappa) - return T * (a*(a-1)/2 * (n+1) - b*a*(a-1)/4 - b/6 * ((a-1)**3 + 3/2*(a-1)**2 + 1/RR(2)*(a-1))) - - def bkwssf(kappa): - ret = OrderedDict() - ret[u"κ"] = kappa - m = amplify_sigma(success_probability, [sigma_final, sigma2f(kappa)], q) - ret["m"] = m - ropsm = (m + o) * (a/2 * (n + 2)) - ropst = ops_tf(kappa) - ret["rop"] = ropst + ropsm - T = Tf(kappa) - ret["mem"] = T * a * (n + 1 - b * (a-1)/2) - ret["oracle"] = T * a + ret["m"] + o - return ret - - n, alpha, q, success_probability = preprocess_params(n, alpha, q, success_probability, prec=4*n) - RR = alpha.parent() - sigma = alpha*q - - if o is None: - best = bkw_small_secret(n, alpha, q, secret_distribution, success_probability, t=t, o=0) - o = best["oracle"]/2 - while True: - current = bkw_small_secret(n, alpha, q, secret_distribution, success_probability, t=t, o=o) - if best is None or current["rop"] < best["rop"]: - best = current - if current["rop"] > best["rop"]: - break - - o = o/2 - return best - - if t is None: - t = RR(2*(log(q, 2) - log(sigma, 2))/log(n, 2)) - best = None - while True: - current = bkw_small_secret(n, alpha, q, secret_distribution, success_probability, t=t, o=o) - if best is None or current["rop"] < best["rop"]: - best = current - if current["rop"] > best["rop"]: - break - t += 0.01 - return best - - secret_variance = secret_distribution_variance(secret_distribution) - secret_variance = RR(secret_variance) - - a = RR(t*log(n, 2)) # the target number of additions: a = t*log_2(n) - b = n/a # window width b = n/a - sigma_final = RR(n**t).sqrt() * sigma # after n^t additions we get this stddev - transformation_noise = sqrt(n * 1/RR(12) * secret_variance) - kappa = ceil(log(round(q*transformation_noise/stddevf(sigma)), 2.0)) + 1 - - if kappa > ceil(log(q, 2)): - kappa = ceil(log(q, 2)) - - best = None - while kappa > 0: - current = bkwssf(kappa) - if best is None or current["rop"] < best["rop"]: - best = current - if current["rop"] > best["rop"]: - break - kappa -= 1 - - best["o"] = o - best["t"] = t - best["a"] = a - best["b"] = b - best = cost_reorder(best, ["rop", "oracle", "t", "m", "mem"]) - return best diff --git a/doctest.sh b/doctest.sh deleted file mode 100755 index a173383c8..000000000 --- a/doctest.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -############################################################################### -# Run Sage doctests -############################################################################### -SAGE_ROOT=$(sage -c "import os; print(os.environ['SAGE_ROOT'])") -export SAGE_ROOT="$SAGE_ROOT" - -# shellcheck source=/dev/null -source "$SAGE_ROOT/local/bin/sage-env" -for file in "$@"; do - PYTHONIOENCODING=UTF-8 PYTHONPATH=$(pwd) sage-runtests "$file" -done diff --git a/fix-doctest.sh b/fix-doctest.sh deleted file mode 100755 index 7e17f7a32..000000000 --- a/fix-doctest.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -############################################################################### -# Fix-up Doctests -# -# Please don't just blindly call this to make failures go away, -# but review all changes. -############################################################################### -SAGE_ROOT=$(sage -c "import os; print(os.environ['SAGE_ROOT'])") -export SAGE_ROOT="$SAGE_ROOT" - -# shellcheck source=/dev/null -source "$SAGE_ROOT/local/bin/sage-env" -PYTHONIOENCODING=UTF-8 PYTHONPATH=$(pwd) sage-fixdoctests "$@" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 55ec8d784..000000000 --- a/pyproject.toml +++ /dev/null @@ -1,2 +0,0 @@ -[tool.black] -line-length = 120 diff --git a/readthedocs.yml b/readthedocs.yml deleted file mode 100644 index cad993e27..000000000 --- a/readthedocs.yml +++ /dev/null @@ -1 +0,0 @@ -DOCKER_IMAGE: sagemath/sagemath diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e4ce18027..000000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -flake8 -sphinx==1.4.4