Skip to content

Commit

Permalink
Merge pull request #86 from hkippen-SBAQ/dev/NTRU
Browse files Browse the repository at this point in the history
Add overstretched NTRU estimation functionality
  • Loading branch information
malb authored Nov 1, 2023
2 parents 0dba276 + 1d49e6c commit f711fd4
Show file tree
Hide file tree
Showing 15 changed files with 1,015 additions and 34 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ At present, this estimator is maintained by Martin Albrecht. Contributors are:
- Fernando Virdia
- Florian Göpfert
- Hamish Hunt
- Hunter Kippen
- James Owen
- Léo Ducas
- Ludo Pulles
Expand Down
3 changes: 3 additions & 0 deletions docs/api_doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ API Reference
estimator.lwe_primal
estimator.lwe_dual
estimator.lwe
estimator.ntru_parameters
estimator.ntru_primal
estimator.ntru
estimator.gb
estimator.nd
estimator.prob
Expand Down
4 changes: 3 additions & 1 deletion docs/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ References
.. [AC:AGPS20] Albrecht, M. R., Gheorghiu, V., Postlethwaite, E. W., & Schanck, J. M. (2020). Estimating quantum speedups for lattice sieves. In S. Moriai, & H. Wang, ASIACRYPT 2020, Part II (pp. 583–613). : Springer, Heidelberg.
.. [AC:AGVW17] Martin R. Albrecht, Florian Göpfert, Fernando Virdia & Thomas Wunderer. Revisiting the expected cost of solving uSVP and applications to LWE. In T. Takagi, & T. Peyrin, ASIACRYPT 2017, Part I (pp. 297–322). : Springer, Heidelberg.
.. [AC:CheNgu11] Yuanmi Chen & Phong Q. Nguyen. BKZ 2.0: better lattice security estimates. In D. H. Lee, & X. Wang, ASIACRYPT 2011 (pp. 1–20): Springer, Heidelberg.
.. [AC:DucWoe21] Ducas, L., van Woerden, W. (2021). NTRU Fatigue: How Stretched is Overstretched?. In: Tibouchi, M., Wang, H. (eds) Advances in Cryptology – ASIACRYPT 2021. ASIACRYPT 2021. Lecture Notes in Computer Science(), vol 13093. Springer, Cham. https://doi.org/10.1007/978-3-030-92068-5_1
.. [AC:GuoJoh21] Qian Guo, Thomas Johansson. Faster Dual Lattice Attacks for Solving LWE with Applications to CRYSTALS. In International Conference on the Theory and Application of Cryptology and Information Security (pp. 33-62). Springer, Cham.
.. [ACISP:BaiGal14] Shi Bai & Steven D. Galbraith. Lattice decoding attacks on binary LWE. In W. Susilo, & Y. Mu, ACISP 14 (pp. 322–337). : Springer, Heidelberg.
.. [C:ABFKSW20] Martin R. Albrecht, Shi Bai, Pierre-Alain Fouque, Paul Kirchner, Damien Stehlé and Weiqiang Wen. Faster Enumeration-based Lattice Reduction: Root Hermite Factor $beta^{1/(2k)}$ in Time $beta^{beta/8 + o(beta)}$. CRYPTO 2020.
Expand All @@ -15,6 +16,7 @@ References
.. [CheNgu12] Yuanmi Chen and Phong Q. Nguyen. BKZ 2.0: Better lattice security estimates (Full Version). 2012. http://www.di.ens.fr/~ychen/research/Full_BKZ.pdf
.. [EC:Albrecht17] Albrecht, M. R. (2017). On dual lattice attacks against small-secret LWE and parameter choices in HElib and SEAL. In J. Coron, & J. B. Nielsen, EUROCRYPT 2017, Part II (pp. 103–129). : Springer, Heidelberg.
.. [EC:Ducas18] Léo Ducas (2018). Shortest vector from lattice sieving: A few dimensions for free. In J. B. Nielsen, & V. Rijmen, EUROCRYPT 2018, Part I (pp. 125–145). : Springer, Heidelberg.
.. [EC:KirFou17] Kirchner, P., Fouque, PA. (2017). Revisiting Lattice Attacks on Overstretched NTRU Parameters. In: Coron, JS., Nielsen, J. (eds) Advances in Cryptology – EUROCRYPT 2017. EUROCRYPT 2017. Lecture Notes in Computer Science(), vol 10210. Springer, Cham. https://doi.org/10.1007/978-3-319-56620-7_1
.. [EPRINT:CHHS19] Cheon, J.H., Hhan, M., Hong, S. and Son, Y., 2019. A hybrid of dual and meet-in-the-middle attack on sparse and ternary secret LWE. IEEE Access, 7, pp.89497-89506. https://ia.cr/2019/1114pri
.. [EPRINT:LaaMosPol14] Thijs Laarhoven, Michele Mosca, & Joop van de Pol. Finding shortest lattice vectors faster using quantum search. Cryptology ePrint Archive, Report 2014/907, 2014. https://eprint.iacr.org/2014/907.
.. [EPRINT:SonChe19] Son, Y. and Cheon, J.H., 2019. Revisiting the Hybrid Attack on sparse abd ternary LWE. Workshop on Applied Homomorphic Cryptography, WAHC2019.
Expand All @@ -32,4 +34,4 @@ References
.. [SAC:AlbCurWun19] Albrecht, M. R., Curtis, B. R., & Wunderer, T.. Exploring trade-offs in batch bounded distance decoding. In K. G. Paterson, & D. Stebila, SAC 2019 (pp. 467–491). : Springer, Heidelberg.
.. [SODA:BDGL16] Becker, A., Ducas, L., Gama, N., & Laarhoven, T. (2016). New directions in nearest neighbor searching with applications to lattice sieving. In SODA 2016, (pp. 10–24).
.. [Schnorr03] Claus-Peter Schnorr. Lattice Reduction by Random Sampling and Birthday Methods. In: STACS2003, 20th Annual Symposium on Theoretical Aspects of Computer Science, Berlin, Germany, February 27 - March 1, 2003, Proceedings. Ed. by Helmut Alt and Michel Habib. Vol. 2607. Lecture Notes in Computer Science. Springer, 2003, pp. 145–156.doi:10.1007/3-540-36494-3_14. url: http://dx.doi.org/10.1007/3-540-36494-3_14.
.. [USENIX:ADPS16] Edem Alkim, Léo Ducas, Thomas Pöppelmann, & Peter Schwabe (2016). Post-quantum key exchange - A New Hope. In T. Holz, & S. Savage, 25th USENIX Security Symposium, USENIX Security 16 (pp. 327–343). USENIX Association.
.. [USENIX:ADPS16] Edem Alkim, Léo Ducas, Thomas Pöppelmann, & Peter Schwabe (2016). Post-quantum key exchange - A New Hope. In T. Holz, & S. Savage, 25th USENIX Security Symposium, USENIX Security 16 (pp. 327–343). USENIX Association.
18 changes: 9 additions & 9 deletions docs/schemes/nist-pqc-round-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,30 @@ NIST PQC Round 3 Finalists

>>> from estimator import *
>>> schemes.NTRUHPS2048509Enc
LWEParameters(n=508, q=2048, Xs=D(σ=0.82), Xe=D(σ=0.71), m=508, tag='NTRUHPS2048509Enc')
>>> LWE.primal_bdd(schemes.NTRUHPS2048509Enc)
NTRUParameters(n=508, q=2048, Xs=D(σ=0.82), Xe=D(σ=0.71), m=508, tag='NTRUHPS2048509Enc', ntru_type='matrix')
>>> NTRU.primal_bdd(schemes.NTRUHPS2048509Enc)
rop: ≈2^131.1, red: ≈2^130.1, svp: ≈2^130.2, β: 357, η: 390, d: 916, tag: bdd

::

>>> from estimator import *
>>> schemes.NTRUHPS2048677Enc
LWEParameters(n=676, q=2048, Xs=D(σ=0.82), Xe=D(σ=0.61), m=676, tag='NTRUHPS2048677Enc')
>>> LWE.primal_bdd(schemes.NTRUHPS2048677Enc)
NTRUParameters(n=676, q=2048, Xs=D(σ=0.82), Xe=D(σ=0.61), m=676, tag='NTRUHPS2048677Enc', ntru_type='matrix')
>>> NTRU.primal_bdd(schemes.NTRUHPS2048677Enc)
rop: ≈2^170.8, red: ≈2^169.6, svp: ≈2^169.9, β: 498, η: 533, d: 1179, tag: bdd

::

>>> from estimator import *
>>> schemes.NTRUHPS4096821Enc
LWEParameters(n=820, q=4096, Xs=D(σ=0.82), Xe=D(σ=0.79), m=820, tag='NTRUHPS4096821Enc')
>>> LWE.primal_bdd(schemes.NTRUHPS4096821Enc)
NTRUParameters(n=820, q=4096, Xs=D(σ=0.82), Xe=D(σ=0.79), m=820, tag='NTRUHPS4096821Enc', ntru_type='matrix')
>>> NTRU.primal_bdd(schemes.NTRUHPS4096821Enc)
rop: ≈2^199.7, red: ≈2^198.7, svp: ≈2^198.6, β: 601, η: 636, d: 1485, tag: bdd

::

>>> from estimator import *
>>> schemes.NTRUHRSS701Enc
LWEParameters(n=700, q=8192, Xs=D(σ=0.82), Xe=D(σ=0.82), m=700, tag='NTRUHRSS701')
>>> LWE.primal_bdd(schemes.NTRUHRSS701Enc)
rop: ≈2^158.9, red: ≈2^157.9, svp: ≈2^158.0, β: 455, η: 490, d: 1294, tag: bdd
NTRUParameters(n=700, q=8192, Xs=D(σ=0.82), Xe=D(σ=0.82), m=700, tag='NTRUHRSS701', ntru_type='matrix')
>>> NTRU.primal_bdd(schemes.NTRUHRSS701Enc)
rop: ≈2^158.7, red: ≈2^157.7, svp: ≈2^157.7, β: 454, η: 489, d: 1306, tag: bdd
3 changes: 2 additions & 1 deletion estimator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-

__all__ = ['ND', 'Logging', 'RC', 'Simulator', 'LWE', 'schemes']
__all__ = ['ND', 'Logging', 'RC', 'Simulator', 'LWE', 'NTRU', 'schemes']

from .nd import NoiseDistribution as ND
from .io import Logging
from .reduction import RC
from . import simulator as Simulator
from . import lwe as LWE
from . import ntru as NTRU
from . import schemes
8 changes: 7 additions & 1 deletion estimator/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
Default values.
"""

from .reduction import RC
from .simulator import GSA
from .reduction import RC
from sage.all import exp

red_cost_model = RC.MATZOV
red_cost_model_classical_poly_space = RC.ABLR21
red_shape_model = "gsa"
red_simulator = GSA
mitm_opt = "analytical"
max_n_cache = 10000


def ntru_fatigue_lb(n):
return int((n**2.484)/exp(6))
4 changes: 4 additions & 0 deletions estimator/lwe_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def __post_init__(self, **kwds):
self.Xe = copy(self.Xe)
self.Xe.n = self.m

@property
def _homogeneous(self):
return False

def normalize(self):
"""
EXAMPLES:
Expand Down
58 changes: 45 additions & 13 deletions estimator/lwe_primal.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,16 @@ def _solve_for_d(params, m, beta, tau, xi):
# Find the smallest d ∈ [n,m] s.t. a*d^2 + b*d + c >= 0
delta = deltaf(beta)
a = -log(delta)
C = log(params.Xe.stddev**2 * (beta - 1) + tau**2) / 2.0

if not tau:
C = log(params.Xe.stddev**2 * (beta - 1)) / 2.0
c = params.n * log(xi) - (params.n + 1) * log(params.q)

else:
C = log(params.Xe.stddev**2 * (beta - 1) + tau**2) / 2.0
c = log(tau) + params.n * log(xi) - (params.n + 1) * log(params.q)

b = log(delta) * (2 * beta - 1) + log(params.q) - C
c = log(tau) + params.n * log(xi) - (params.n + 1) * log(params.q)
n = params.n
if a * n * n + b * n + c >= 0: # trivial case
return n
Expand Down Expand Up @@ -87,18 +94,30 @@ def cost_gsa(
xi = PrimalUSVP._xi_factor(params.Xs, params.Xe)
m = min(2 * ceil(sqrt(params.n * log(params.q) / log(delta))), m)
tau = params.Xe.stddev if tau is None else tau
# Account for homogeneous instances
if params._homogeneous:
tau = False # Tau false ==> instance is homogeneous

d = PrimalUSVP._solve_for_d(params, m, beta, tau, xi) if d is None else d
# if d == β we assume one SVP call, otherwise poly calls. This makes the cost curve jump, so
# we avoid it here.
if d == beta and d < m:
d += 1
assert d <= m + 1

lhs = log(sqrt(params.Xe.stddev**2 * (beta - 1) + tau**2))
rhs = RR(
log(delta) * (2 * beta - d - 1)
+ (log(tau) + log(xi) * params.n + log(params.q) * (d - params.n - 1)) / d
)
if not tau:
lhs = log(sqrt(params.Xe.stddev**2 * (beta - 1)))
rhs = RR(
log(delta) * (2 * beta - d - 1)
+ (log(xi) * params.n + log(params.q) * (d - params.n - 1)) / d
)

else:
lhs = log(sqrt(params.Xe.stddev**2 * (beta - 1) + tau**2))
rhs = RR(
log(delta) * (2 * beta - d - 1)
+ (log(tau) + log(xi) * params.n + log(params.q) * (d - params.n - 1)) / d
)

return costf(red_cost_model, beta, d, predicate=lhs <= rhs)

Expand All @@ -120,8 +139,18 @@ def cost_simulator(
xi = PrimalUSVP._xi_factor(params.Xs, params.Xe)
tau = params.Xe.stddev if tau is None else tau

if params._homogeneous:
tau = False
d -= 1 # Remove extra dimension in homogeneous instances

r = simulator(d=d, n=params.n, q=params.q, beta=beta, xi=xi, tau=tau)
lhs = params.Xe.stddev**2 * (beta - 1) + tau**2

if not tau:
lhs = params.Xe.stddev**2 * (beta - 1)

else:
lhs = params.Xe.stddev**2 * (beta - 1) + tau**2

predicate = r[d - beta] > lhs

return costf(red_cost_model, beta, d, predicate=predicate)
Expand Down Expand Up @@ -174,10 +203,8 @@ def __call__(
"""
params = LWEParameters.normalize(params)

# allow for a larger embedding lattice dimension: Bai and Galbraith
m = params.m + params.n if params.Xs <= params.Xe else params.m

if red_shape_model == "gsa":
with local_minimum(40, max(2 * params.n, 41), precision=5) as it:
for beta in it:
Expand Down Expand Up @@ -311,12 +338,17 @@ def cost(
delta = deltaf(beta)
d = min(ceil(sqrt(params.n * log(params.q) / log(delta))), m) + 1
d -= zeta
xi = PrimalUSVP._xi_factor(params.Xs, params.Xe)

xi = PrimalUSVP._xi_factor(params.Xs, params.Xe)
tau = 1
# 1. Simulate BKZ-β
# TODO: pick τ
# TODO: pick τ as non default value

if params._homogeneous:
tau = False
d -= 1

r = simulator(d, params.n - zeta, params.q, beta, xi=xi, dual=True)
r = simulator(d, params.n - zeta, params.q, beta, xi=xi, tau=tau, dual=True)

bkz_cost = costf(red_cost_model, beta, d)

Expand Down
Loading

0 comments on commit f711fd4

Please sign in to comment.