Skip to content

Commit

Permalink
Merge pull request #98 from hunterkipt/dev/SIS
Browse files Browse the repository at this point in the history
Minor SIS euclidean norm dimension Fix
  • Loading branch information
malb authored Feb 7, 2024
2 parents 49d8e4f + b9602bb commit 4195c66
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 22 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ Quick Start
SISParameters(n=512, q=12289, length_bound=5833.9072, m=1024, norm=2, tag='Falcon512_Unf')
>>> r = SIS.estimate.rough(schemes.Falcon512_Unf)
lattice :: rop: ≈2^121.2, red: ≈2^121.2, δ: 1.003882, β: 415, d: 1024, tag: euclidian
lattice :: rop: ≈2^121.2, red: ≈2^121.2, δ: 1.003882, β: 415, d: 1024, tag: euclidean
>>> r = SIS.estimate(schemes.Falcon512_Unf)
lattice :: rop: ≈2^146.4, red: ≈2^146.4, δ: 1.003882, β: 415, d: 1024, tag: euclidian
lattice :: rop: ≈2^146.4, red: ≈2^146.4, δ: 1.003882, β: 415, d: 1024, tag: euclidean
- `Try it in your browser <https://mybinder.org/v2/gh/malb/lattice-estimator/jupyter-notebooks?labpath=..%2F..%2Ftree%2Fprompt.ipynb>`__.
- `Read the documentation <https://lattice-estimator.readthedocs.io/en/latest/>`__.
Expand Down
8 changes: 4 additions & 4 deletions docs/algorithms/sis-lattice.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ We construct an (easy) example SIS instance::
params = SIS.Parameters(n=113, q=2048, length_bound=512, norm=2)
params

The simplest (and quickest to estimate) model is solving for the SIS instance with a euclidian norm length bound and assuming the Gaussian heuristic.Then, we can solve for the required root hermite factor [EC:GamNgu08]_ that will guarantee BKZ outputs a short enough vector::
The simplest (and quickest to estimate) model is solving for the SIS instance with a euclidean norm length bound and assuming the Gaussian heuristic.Then, we can solve for the required root hermite factor [EC:GamNgu08]_ that will guarantee BKZ outputs a short enough vector::

SIS.lattice(params)

The exact reduction shape model does not matter when using euclidian norm bounds, as the required block size is calculated directly from the length bound.
The exact reduction shape model does not matter when using euclidean norm bounds, as the required block size is calculated directly from the length bound.

For infinity norm length bounds, we have two separate analyses. Both follow the same basic strategy. We use the worst case euclidian norm bound as a lower bound on the hardness. Then, we analyze the probability of obtaining a short vector where every coordinate meets the infinity norm constraint. When sqrt(m)*length_bound is less than the modulus q, we follow the analysis of the MATZOV report ([MATZOV22]_ P.18). We simulate the cost of generating *many* short vectors and treat each coordinate of the vector as an i.i.d Gaussian random variable with standard deviation equal to the length(s) of these short vectors divided by the square root of the dimension.::
For infinity norm length bounds, we have two separate analyses. Both follow the same basic strategy. We use the worst case euclidean norm bound as a lower bound on the hardness. Then, we analyze the probability of obtaining a short vector where every coordinate meets the infinity norm constraint. When sqrt(m)*length_bound is less than the modulus q, we follow the analysis of the MATZOV report ([MATZOV22]_ P.18). We simulate the cost of generating *many* short vectors and treat each coordinate of the vector as an i.i.d Gaussian random variable with standard deviation equal to the length(s) of these short vectors divided by the square root of the dimension.::

params = SIS.Parameters(n=113, q=2048, length_bound=50, norm=oo)
SIS.lattice(params)
Expand All @@ -32,5 +32,5 @@ Another option is to simulate a rerandomization of the basis, such that the q-ve

SIS.lattice(params.updated(length_bound=70), red_shape_model=Simulator.LGSA)

**Note:** Currently, lattice attack estimation is only avalailable for euclidian (``2``) and infinity (``oo``) norms. ``SIS.lattice()`` will return a ``NotImplementedError`` if one of these two norms are not selected.
**Note:** Currently, lattice attack estimation is only avalailable for euclidean (``2``) and infinity (``oo``) norms. ``SIS.lattice()`` will return a ``NotImplementedError`` if one of these two norms are not selected.

7 changes: 3 additions & 4 deletions estimator/sis.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,10 @@ def __call__(
>>> params = SIS.Parameters(n=113, q=2048, length_bound=512, norm=2)
>>> _ = SIS.estimate(params)
lattice :: rop: ≈2^89.7, red: ≈2^89.7, δ: 1.006095, β: 210, d: 862, tag: euclidian
>>> _ = SIS.estimate(params.updated(norm=oo))
lattice :: rop: ≈2^55.7, red: ≈2^54.8, sieve: ≈2^54.5, β: 83, η: 107, ζ: 112, d: 750, ...
lattice :: rop: ≈2^47.0, red: ≈2^47.0, δ: 1.011391, β: 61, d: 276, tag: euclidean
>>> _ = SIS.estimate(params.updated(norm=oo), red_shape_model="cn11")
lattice :: rop: ≈2^43.6, red: ≈2^42.6, sieve: ≈2^42.7, β: 40, η: 67, ζ: 112, d: 750, ...
"""

algorithms = {}
Expand Down
34 changes: 22 additions & 12 deletions estimator/sis_lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"""
from functools import partial

from sage.all import oo, sqrt, log, RR, cached_function
from sage.all import oo, sqrt, log, RR, floor, cached_function
from .reduction import beta as betaf
from .reduction import cost as costf
from .util import local_minimum
Expand All @@ -27,16 +27,26 @@ class SISLattice:
Estimate cost of solving SIS via lattice reduction.
"""
@staticmethod
def _solve_for_delta_euclidian(params, d):
def _solve_for_delta_euclidean(params, d):
# root_volume = params.q**(params.n/d)
# delta = (params.length_bound / root_volume)**(1/(d - 1))
root_volume = (params.n/d) * log(params.q, 2)
log_delta = (1/(d - 1)) * (log(params.length_bound, 2) - root_volume)
return RR(2**log_delta)

@staticmethod
def _opt_sis_d(params):
"""
Optimizes SIS dimension for the given parameters, assuming the optimal
d \approx sqrt(n*log(q)/log(delta))
"""
log_delta = log(params.length_bound, 2)**2 / (4 * params.n * log(params.q, 2))
d = sqrt(params.n * log(params.q, 2) / log_delta)
return d

@staticmethod
@cached_function
def cost_euclidian(
def cost_euclidean(
params: SISParameters,
d=None,
red_cost_model=red_cost_model_default,
Expand All @@ -48,10 +58,10 @@ def cost_euclidian(
raise ValueError("SIS trivially easy. Please set norm bound < q.")

if d is None:
d = params.m
d = min(floor(SISLattice._opt_sis_d(params)), params.m)

# First solve for root hermite factor
delta = SISLattice._solve_for_delta_euclidian(params, d)
delta = SISLattice._solve_for_delta_euclidean(params, d)
# Then derive beta from the cost model(s)
if delta >= 1 and betaf(delta) <= d:
beta = betaf(delta)
Expand Down Expand Up @@ -181,7 +191,7 @@ def cost_zeta(
Ignored coordinates are set to 0 in the final SIS solution, so the dimension of the
instance is treated as d-ζ.
"""
# step 0. establish baseline cost using worst case euclidian norm estimate
# step 0. establish baseline cost using worst case euclidean norm estimate
params_baseline = params.updated(norm=2)
baseline_cost = lattice(
params_baseline,
Expand Down Expand Up @@ -260,7 +270,7 @@ def __call__(
>>> params = SIS.Parameters(n=113, q=2048, length_bound=512, norm=2)
>>> SIS.lattice(params)
rop: ≈2^89.7, red: ≈2^89.7, δ: 1.006095, β: 210, d: 862, tag: euclidian
rop: ≈2^47.0, red: ≈2^47.0, δ: 1.011391, β: 61, d: 276, tag: euclidean
>>> SIS.lattice(params.updated(norm=oo), red_shape_model="lgsa")
rop: ≈2^43.6, red: ≈2^42.6, sieve: ≈2^42.7, β: 40, η: 67, ζ: 112, d: 750, prob: 1, ↻: 1, tag: infinity
Expand All @@ -272,16 +282,16 @@ def __call__(
BKZ to produce the required output. For infinity norm bounds, the success conditions are derived using a
probabilistic analysis. Vectors are assumed to be short as in [MATZOV22]_ P.18, or [Dilithium21]_ P.35.
.. note :: When using euclidian norm bounds and the length bound is too small, this function returns
.. note :: When using euclidean norm bounds and the length bound is too small, this function returns
β = d, and rop: inf
"""
if params.norm == 2:
tag = "euclidian"
tag = "euclidean"
elif params.norm == oo:
tag = "infinity"
else:
raise NotImplementedError("SIS attack estimation currently only supports euclidian and infinity norms")
raise NotImplementedError("SIS attack estimation currently only supports euclidean and infinity norms")

if tag == "infinity":
red_shape_model = simulator_normalize(red_shape_model)
Expand Down Expand Up @@ -309,7 +319,7 @@ def __call__(
cost = f(zeta=zeta)

else:
cost = self.cost_euclidian(
cost = self.cost_euclidean(
params=params,
red_cost_model=red_cost_model,
log_level=log_level + 1,
Expand All @@ -318,7 +328,7 @@ def __call__(
cost["tag"] = tag
cost["problem"] = params

if tag == "euclidian":
if tag == "euclidean":
for k in ("sieve", "prob", "repetitions", "zeta"):
try:
del cost[k]
Expand Down

0 comments on commit 4195c66

Please sign in to comment.