aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyecsca/ec/context.py2
-rw-r--r--pyecsca/ec/mult/__init__.py1
-rw-r--r--pyecsca/ec/mult/fake.py37
-rw-r--r--pyecsca/sca/re/rpa.py47
-rw-r--r--pyecsca/sca/re/zvp.py27
-rw-r--r--test/sca/test_rpa.py8
6 files changed, 96 insertions, 26 deletions
diff --git a/pyecsca/ec/context.py b/pyecsca/ec/context.py
index 674393b..de6e202 100644
--- a/pyecsca/ec/context.py
+++ b/pyecsca/ec/context.py
@@ -308,6 +308,8 @@ current: Optional[Context] = None
class _ContextManager:
+ old_context: Optional[Context]
+ new_context: Optional[Context]
def __init__(self, new_context: Optional[Context] = None, copy: bool = True):
if copy:
if new_context is not None:
diff --git a/pyecsca/ec/mult/__init__.py b/pyecsca/ec/mult/__init__.py
index 14f1c99..433e0b8 100644
--- a/pyecsca/ec/mult/__init__.py
+++ b/pyecsca/ec/mult/__init__.py
@@ -3,6 +3,7 @@
from .base import *
from .binary import *
from .comb import *
+from .fake import *
from .fixed import *
from .ladder import *
from .naf import *
diff --git a/pyecsca/ec/mult/fake.py b/pyecsca/ec/mult/fake.py
new file mode 100644
index 0000000..5d5ad64
--- /dev/null
+++ b/pyecsca/ec/mult/fake.py
@@ -0,0 +1,37 @@
+from typing import List, Type, Callable
+
+from pyecsca.ec.formula import Formula, AdditionFormula, DifferentialAdditionFormula, DoublingFormula, LadderFormula, \
+ NegationFormula
+from pyecsca.ec.formula.fake import FakeFormula
+from pyecsca.ec.mult import ScalarMultiplier
+from pyecsca.ec.params import DomainParameters
+
+
+def fake_mult(mult_class: Type[ScalarMultiplier], mult_factory: Callable, params: DomainParameters) -> ScalarMultiplier:
+ """
+ Get a multiplier with FakeFormulas.
+
+ :param mult_class: The class of the scalar multiplier to use.
+ :param mult_factory: A callable that takes the formulas and instantiates the multiplier.
+ :param params: The domain parameters to use.
+ :return: The multiplier.
+ """
+ formula_classes: List[Type[Formula]] = list(
+ filter(
+ lambda klass: klass in mult_class.requires,
+ [
+ AdditionFormula,
+ DifferentialAdditionFormula,
+ DoublingFormula,
+ LadderFormula,
+ NegationFormula,
+ ],
+ )
+ )
+ formulas = []
+ for formula in formula_classes:
+ for subclass in formula.__subclasses__():
+ if issubclass(subclass, FakeFormula):
+ formulas.append(subclass(params.curve.coordinate_model))
+ mult = mult_factory(*formulas)
+ return mult
diff --git a/pyecsca/sca/re/rpa.py b/pyecsca/sca/re/rpa.py
index c65c3f6..395f698 100644
--- a/pyecsca/sca/re/rpa.py
+++ b/pyecsca/sca/re/rpa.py
@@ -4,11 +4,13 @@ Provides functionality inspired by the Refined-Power Analysis attack by Goubin [
from copy import copy, deepcopy
from public import public
-from typing import MutableMapping, Optional, Callable, List, Set, cast
+from typing import MutableMapping, Optional, Callable, List, Set, cast, Type, Tuple
from sympy import FF, sympify, Poly, symbols
from pyecsca.ec.error import NonInvertibleError
+from pyecsca.ec.formula.fake import FakePoint
+from pyecsca.ec.mult.fake import fake_mult
from pyecsca.sca.re.base import RE
from pyecsca.sca.re.tree import Tree, Map
from pyecsca.ec.coordinates import AffineCoordinateModel
@@ -19,8 +21,7 @@ from pyecsca.ec.formula import (
TriplingFormula,
NegationFormula,
DifferentialAdditionFormula,
- LadderFormula,
-)
+ LadderFormula, )
from pyecsca.ec.mod import Mod, mod
from pyecsca.ec.mult import (
ScalarMultiplicationAction,
@@ -380,3 +381,43 @@ class RPA(RE):
log([mult.__class__.__name__ for mult in mults])
log()
return mults
+
+
+@public
+def multiples_computed(
+ scalar: int,
+ params: DomainParameters,
+ mult_class: Type[ScalarMultiplier],
+ mult_factory: Callable,
+ use_init: bool = False,
+ use_multiply: bool = True
+) -> set[int]:
+ """
+ Compute the multiples computed for a given scalar and multiplier (quickly).
+
+ :param scalar: The scalar to compute for.
+ :param params: The domain parameters to use.
+ :param mult_class: The class of the scalar multiplier to use.
+ :param mult_factory: A callable that takes the formulas and instantiates the multiplier.
+ :param use_init: Whether to consider the point multiples that happen in scalarmult initialization.
+ :param use_multiply: Whether to consider the point multiples that happen in scalarmult multiply (after initialization).
+ :return: A list of tuples, where the first element is the formula shortname (e.g. "add") and the second is a tuple of the dlog
+ relationships to the input of the input points to the formula.
+ """
+ mult = fake_mult(mult_class, mult_factory, params)
+ ctx = MultipleContext()
+ if use_init:
+ with local(ctx, copy=False):
+ mult.init(params, FakePoint(params.curve.coordinate_model))
+ else:
+ mult.init(params, FakePoint(params.curve.coordinate_model))
+
+ if use_multiply:
+ with local(ctx, copy=False):
+ mult.multiply(scalar)
+ else:
+ mult.multiply(scalar)
+
+ return set(ctx.points.values()) - {0}
+
+
diff --git a/pyecsca/sca/re/zvp.py b/pyecsca/sca/re/zvp.py
index 74c8902..b143260 100644
--- a/pyecsca/sca/re/zvp.py
+++ b/pyecsca/sca/re/zvp.py
@@ -3,7 +3,7 @@ Provides functionality inspired by the Zero-value point attack [ZVP]_.
Implements ZVP point construction from [FFD]_.
"""
-from typing import List, Set, Tuple, Dict, Type
+from typing import List, Set, Tuple, Dict, Type, Callable
from public import public
import warnings
from astunparse import unparse
@@ -25,7 +25,7 @@ from pyecsca.ec.formula import (
from pyecsca.ec.formula.fake import FakePoint, FakeFormula
from pyecsca.ec.formula.unroll import unroll_formula
from pyecsca.ec.mod import Mod, mod
-from pyecsca.ec.mult import ScalarMultiplier
+from pyecsca.ec.mult import ScalarMultiplier, fake_mult
from pyecsca.ec.params import DomainParameters
from pyecsca.ec.point import Point
@@ -585,11 +585,12 @@ def solve_hard_dcp_cypari(
return res
+@public
def addition_chain(
scalar: int,
params: DomainParameters,
mult_class: Type[ScalarMultiplier],
- mult_factory,
+ mult_factory: Callable,
use_init: bool = False,
use_multiply: bool = True
) -> List[Tuple[str, Tuple[int, ...]]]:
@@ -605,26 +606,8 @@ def addition_chain(
:return: A list of tuples, where the first element is the formula shortname (e.g. "add") and the second is a tuple of the dlog
relationships to the input of the input points to the formula.
"""
- formula_classes: List[Type[Formula]] = list(
- filter(
- lambda klass: klass in mult_class.requires,
- [
- AdditionFormula,
- DifferentialAdditionFormula,
- DoublingFormula,
- LadderFormula,
- NegationFormula,
- ],
- )
- )
- formulas = []
- for formula in formula_classes:
- for subclass in formula.__subclasses__():
- if issubclass(subclass, FakeFormula):
- formulas.append(subclass(params.curve.coordinate_model))
-
+ mult = fake_mult(mult_class, mult_factory, params)
ctx = MultipleContext()
- mult = mult_factory(*formulas)
if use_init:
with local(ctx, copy=False):
mult.init(params, FakePoint(params.curve.coordinate_model))
diff --git a/test/sca/test_rpa.py b/test/sca/test_rpa.py
index d87e248..0d2860b 100644
--- a/test/sca/test_rpa.py
+++ b/test/sca/test_rpa.py
@@ -28,7 +28,7 @@ from pyecsca.sca.re.rpa import (
MultipleContext,
rpa_point_0y,
rpa_point_x0,
- rpa_distinguish,
+ rpa_distinguish, multiples_computed,
)
@@ -71,6 +71,12 @@ def rpa_params(model, coords):
return DomainParameters(curve, g, 0x85D265932D90785C, 1)
+def test_multiples(rpa_params):
+ multiples = multiples_computed(17, rpa_params, LTRMultiplier, LTRMultiplier, True, True)
+ assert 1 in multiples
+ assert 17 in multiples
+ assert 0 not in multiples
+
def test_x0_point(rpa_params):
res = rpa_point_x0(rpa_params)
assert res is not None