diff options
| -rw-r--r-- | pyecsca/ec/context.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/mult/__init__.py | 1 | ||||
| -rw-r--r-- | pyecsca/ec/mult/fake.py | 37 | ||||
| -rw-r--r-- | pyecsca/sca/re/rpa.py | 47 | ||||
| -rw-r--r-- | pyecsca/sca/re/zvp.py | 27 | ||||
| -rw-r--r-- | test/sca/test_rpa.py | 8 |
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 |
