Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NotImplementedError to primal_dsd for Xs != Xe #90

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions docs/algorithms/ntru.rst
Original file line number Diff line number Diff line change
@@ -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
<https://github.com/fplll/fpylll/blob/master/src/fpylll/tools/bkz_simulator.py>_`)::

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.

1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Lattice Estimator
algorithms/lwe-dual
algorithms/lwe-bkw
algorithms/gb
algorithms/ntru

contributing

Expand Down
12 changes: 6 additions & 6 deletions estimator/ntru.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions estimator/ntru_primal.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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
Expand Down
Loading