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 d11121607..000000000 Binary files a/__pycache__/__init__.cpython-37.pyc and /dev/null differ diff --git a/__pycache__/estimator.cpython-37.pyc b/__pycache__/estimator.cpython-37.pyc deleted file mode 100644 index 0229024a5..000000000 Binary files a/__pycache__/estimator.cpython-37.pyc and /dev/null differ diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml deleted file mode 100644 index 8534a98f5..000000000 --- a/bitbucket-pipelines.yml +++ /dev/null @@ -1,31 +0,0 @@ -# This is a sample build configuration for Python. -# Check our guides at https://confluence.atlassian.com/x/x4UWN for more examples. -# Only use spaces to indent your .yml configuration. -# ----- -# You can specify a custom docker image from Docker Hub as your build environment. -image: sagemath/sagemath - -pipelines: - default: - - step: - name: PEP8 - script: - - sudo apt-get update && sudo apt-get install -y python3-pip - - pip3 install flake8 - - $HOME/.local/bin/flake8 estimator.py - - step: - name: Doctest - script: - - export SAGE_ROOT=`sage -c "import os; print(os.environ['SAGE_ROOT'])" | tail -1` - - export PATH="$SAGE_ROOT/build/bin:$SAGE_ROOT/local/bin:$PATH" - - export SAGE_PYTHON_VERSION=3 - - export SAGE_LOCAL="$SAGE_ROOT/local" - - export DOT_SAGE=/home/sage/.sage/ - - mkdir stupid_workaround # sage doesn't like world writable but we're not allowed to change that - - chmod 700 stupid_workaround - - cp estimator.py stupid_workaround/ - - cp README.rst stupid_workaround/ - - cd stupid_workaround - - PYTHONIOENCODING=UTF-8 PYTHONPATH=`pwd` sage-runtests estimator.py - - PYTHONIOENCODING=UTF-8 PYTHONPATH=`pwd` sage-runtests README.rst - - cd .. diff --git a/bkw_legacy.py b/bkw_legacy.py deleted file mode 100644 index 3b208f22d..000000000 --- a/bkw_legacy.py +++ /dev/null @@ -1,315 +0,0 @@ -# -*- coding: utf-8 -*- -""" -BKW legacy code. - -.. moduleauthor:: Martin R. Albrecht - -""" -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