diff --git a/docs/algorithms/ntru.rst b/docs/algorithms/ntru.rst new file mode 100644 index 0000000..53d1c9a --- /dev/null +++ b/docs/algorithms/ntru.rst @@ -0,0 +1,56 @@ +.. _NTRU Primal Attacks: + +NTRU Primal Attacks +===================== + +We construct an (easy) example NTRU instance:: + + from estimator import * + params = NTRU.Parameters(n=200, q=7981, Xs=ND.UniformMod(3), Xe=ND.UniformMod(3)) + params + +The simplest (and quickest to estimate) model is solving via uSVP and assuming the Geometric Series +Assumption (GSA) [Schnorr03]_. The success condition was formulated in [USENIX:ADPS16]_ and +studied/verified in [AC:AGVW17]_, [C:DDGR20]_, [PKC:PosVir21]_. The treatment of small secrets is +from [ACISP:BaiGal14]_. Here, the NTRU instance is treated as a homoegeneous LWE instance:: + + NTRU.primal_usvp(params, red_shape_model="gsa") + +We get a similar result if we use the ``GSA`` simulator. We do not get the identical result because +we optimize β and d separately:: + + NTRU.primal_usvp(params, red_shape_model=Simulator.GSA) + +To get a more precise answer we may use the CN11 simulator by Chen and Nguyen [AC:CheNgu11]_ (as +`implemented in FPyLLL +_`):: + + NTRU.primal_usvp(params, red_shape_model=Simulator.CN11) + +We can then improve on this result by first preprocessing the basis with block size β followed by a +single SVP call in dimension η [RSA:LiuNgu13]_. We call this the BDD approach since this is +essentially the same strategy as preprocessing a basis and then running a CVP solver:: + + NTRU.primal_bdd(params, red_shape_model=Simulator.CN11) + +We can improve these results further by exploiting the sparse secret in the hybrid attack +[C:HowgraveGraham07]_ guessing ζ positions of the secret:: + + NTRU.primal_hybrid(params, red_shape_model=Simulator.CN11) + +In addition to the primal secret key recovery attack, this module supports the dense sublattice +attack as formulated in [EC:KirFou17]_, and refined/verified in [AC:DucWoe21]_. The baseline +dense sublattice attack uses a 'z-shape' variant of the Geometric Series Assumption, called the +ZGSA:: + + params.possibly_overstretched + NTRU.primal_dsd(params, red_shape_model=Simulator.ZGSA) + +Of course we can also use the CN11 simulator for this attack as well:: + + NTRU.primal_dsd(params, red_dhape_model=Simulator.CN11) + +**Note:** Currently, dense sublattice attack estimation is only supported if the distributions of +``f`` and ``g`` are equal. ``NTRU.primal_dsd()`` will return a ``NotImplementedError`` if this is +not the case. + diff --git a/docs/index.rst b/docs/index.rst index 7d20907..8e5e53a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,7 @@ Lattice Estimator algorithms/lwe-dual algorithms/lwe-bkw algorithms/gb + algorithms/ntru contributing diff --git a/estimator/ntru.py b/estimator/ntru.py index d9cdc37..e8ccfe3 100644 --- a/estimator/ntru.py +++ b/estimator/ntru.py @@ -104,14 +104,14 @@ def __call__( EXAMPLE :: >>> from estimator import * - >>> _ = NTRU.estimate(schemes.NTRUHPS2048509Enc) - usvp :: rop: ≈2^134.5, red: ≈2^134.5, δ: 1.004179, β: 373, d: 923, tag: usvp - bdd :: rop: ≈2^130.9, red: ≈2^129.9, svp: ≈2^129.9, β: 356, η: 389, d: 917, tag: bdd - bdd_hybrid :: rop: ≈2^130.9, red: ≈2^129.9, svp: ≈2^129.9, β: 356, η: 389, ζ: 0, |S|: 1, ... - bdd_mitm_hybrid :: rop: ≈2^185.3, red: ≈2^184.5, svp: ≈2^184.2, β: 371, η: 2, ζ: 159, |S|: ≈2^228.0... + >>> _ = NTRU.estimate(schemes.NTRUHRSS701Enc) + usvp :: rop: ≈2^162.1, red: ≈2^162.1, δ: 1.003557, β: 470, d: 1317, tag: usvp + bdd :: rop: ≈2^158.7, red: ≈2^157.7, svp: ≈2^157.7, β: 454, η: 489, d: 1306, tag: bdd + bdd_hybrid :: rop: ≈2^158.7, red: ≈2^157.7, svp: ≈2^157.7, β: 454, η: 489, ζ: 0, |S|: 1, d: ... + bdd_mitm_hybrid :: rop: ≈2^233.0, red: ≈2^232.1, svp: ≈2^232.0, β: 469, η: 2, ζ: 178, |S|: ... >>> params = NTRU.Parameters(n=113, q=512, Xs=ND.UniformMod(3), Xe=ND.UniformMod(3)) - >>> _ = NTRU.estimate(params) + >>> _ = NTRU.estimate(params, catch_exceptions=False) usvp :: rop: ≈2^46.0, red: ≈2^46.0, δ: 1.011516, β: 59, d: 221, tag: usvp dsd :: rop: ≈2^37.9, red: ≈2^37.9, δ: 1.013310, β: 31, d: 226, tag: dsd bdd :: rop: ≈2^42.4, red: ≈2^41.0, svp: ≈2^41.8, β: 41, η: 70, d: 225, tag: bdd diff --git a/estimator/ntru_primal.py b/estimator/ntru_primal.py index 4b32aa2..3b12732 100644 --- a/estimator/ntru_primal.py +++ b/estimator/ntru_primal.py @@ -182,8 +182,8 @@ def __call__( EXAMPLE:: >>> from estimator import * - >>> NTRU.primal_dsd(schemes.NTRUHPS2048509Enc) - rop: ≈2^157.1, red: ≈2^157.1, δ: 1.003645, β: 453, d: 1016, tag: dsd + >>> NTRU.primal_dsd(schemes.NTRUHRSS701Enc) + rop: ≈2^190.2, red: ≈2^190.2, δ: 1.003095, β: 571, d: 1400, tag: dsd >>> params = NTRU.Parameters(n=113, q=512, Xs=ND.UniformMod(3), Xe=ND.UniformMod(3)) >>> NTRU.primal_dsd(params, red_shape_model="zgsa") @@ -200,6 +200,9 @@ def __call__( .. note :: Non-overstretched parameters (where the probability of Dense sublattice discovery is 0) will return β = d. """ + if params.Xs.stddev != params.Xe.stddev: + raise NotImplementedError("Dense sublattice attack not supported for Xs != Xe") + params = NTRUParameters.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