diff options
| author | J08nY | 2025-06-19 15:44:41 +0200 |
|---|---|---|
| committer | J08nY | 2025-06-19 15:44:41 +0200 |
| commit | b244e5747258ad14e226a6f9df56ebc4be0f353b (patch) | |
| tree | 61ec77fc351b059a6bf4e4d08ad0ebe79fac50a6 | |
| parent | e355d741135d22a8fcfe620d6961e71aa6c38b31 (diff) | |
| download | pyecsca-b244e5747258ad14e226a6f9df56ebc4be0f353b.tar.gz pyecsca-b244e5747258ad14e226a6f9df56ebc4be0f353b.tar.zst pyecsca-b244e5747258ad14e226a6f9df56ebc4be0f353b.zip | |
| -rw-r--r-- | pyecsca/sca/re/rpa.py | 14 | ||||
| -rw-r--r-- | pyecsca/sca/re/zvp.py | 10 | ||||
| -rw-r--r-- | test/sca/test_rpa.py | 10 | ||||
| -rw-r--r-- | test/sca/test_zvp.py | 5 |
4 files changed, 34 insertions, 5 deletions
diff --git a/pyecsca/sca/re/rpa.py b/pyecsca/sca/re/rpa.py index adef84d..3fa1e5b 100644 --- a/pyecsca/sca/re/rpa.py +++ b/pyecsca/sca/re/rpa.py @@ -81,6 +81,8 @@ class MultipleContext(Context): def enter_action(self, action: Action) -> None: if isinstance(action, (ScalarMultiplicationAction, PrecomputationAction)): self.inside.append(action) + print("Entering action:", action) + print("base", self.base) if self.base: # If we already did some computation with this context try to see if we are building on top of it. if self.base != action.point: @@ -104,6 +106,7 @@ class MultipleContext(Context): self.parents = {self.base: [], self.neutral: []} self.formulas = {self.base: "", self.neutral: ""} self.precomp = {} + print("after", self.base) def exit_action(self, action: Action) -> None: if isinstance(action, (ScalarMultiplicationAction, PrecomputationAction)): @@ -113,6 +116,8 @@ class MultipleContext(Context): if isinstance(action, FormulaAction) and self.inside: action = cast(FormulaAction, action) shortname = action.formula.shortname + print(action.input_points, action.output_points) + print(self.points) if shortname == "dbl": inp = action.input_points[0] out = action.output_points[0] @@ -424,7 +429,10 @@ class RPA(RE): def _cached_fake_mult( mult_class: Type[ScalarMultiplier], mult_factory: Callable, params: DomainParameters ) -> ScalarMultiplier: - return fake_mult(mult_class, mult_factory, params) + fm = fake_mult(mult_class, mult_factory, params) + if fm.short_circuit: + raise ValueError("The multiplier must not short-circuit.") + return fm @public @@ -454,6 +462,10 @@ def multiples_computed( :param kind: The kind of multiples to return. Can be one of "all", "input", "necessary", or "precomp+necessary". :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. + + .. note:: + The scalar multiplier must not short-circuit. + If `kind` is not "all", `use_init` must be `True`. """ if kind != "all" and not use_init: raise ValueError("Cannot use kind other than 'all' with use_init=False.") diff --git a/pyecsca/sca/re/zvp.py b/pyecsca/sca/re/zvp.py index 956d0c2..2b4de20 100644 --- a/pyecsca/sca/re/zvp.py +++ b/pyecsca/sca/re/zvp.py @@ -588,7 +588,10 @@ def solve_hard_dcp_cypari( def _cached_fake_mult( mult_class: Type[ScalarMultiplier], mult_factory: Callable, params: DomainParameters ) -> ScalarMultiplier: - return fake_mult(mult_class, mult_factory, params) + fm = fake_mult(mult_class, mult_factory, params) + if fm.short_circuit: + raise ValueError("The multiplier must not short-circuit.") + return fm @public @@ -611,9 +614,12 @@ def addition_chain( :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. + + .. note:: + The scalar multiplier must not short-circuit. """ mult = _cached_fake_mult(mult_class, mult_factory, params) - ctx = MultipleContext() + ctx = MultipleContext(keep_base=True) 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 07757fd..8ba719c 100644 --- a/test/sca/test_rpa.py +++ b/test/sca/test_rpa.py @@ -82,6 +82,16 @@ def test_multiples(rpa_params): assert multiples == {1, 2, 4, 8, 16, 17} +def test_multiples_no_init(rpa_params): + multiples = multiples_computed( + 78699, rpa_params, LTRMultiplier, + lambda add, dbl, *args, **kwargs: LTRMultiplier( + add, dbl, None, False, AccumulationOrder.PeqPR, True, False + ), False, True + ) + assert multiples + + def test_multiples_bnaf(rpa_params): mult_partial = partial(BinaryNAFMultiplier, always=True, direction=ProcessingDirection.LTR) multiples = multiples_computed( diff --git a/test/sca/test_zvp.py b/test/sca/test_zvp.py index 496810b..6a06884 100644 --- a/test/sca/test_zvp.py +++ b/test/sca/test_zvp.py @@ -248,11 +248,12 @@ def test_addition_chain(secp128r1): secp128r1, LTRMultiplier, lambda add, dbl, *args, **kwargs: LTRMultiplier( - add, dbl, None, False, AccumulationOrder.PeqPR, True, True + add, dbl, None, False, AccumulationOrder.PeqPR, True, False ), ) assert res is not None - assert len(res) == 25 + # Plenty of operations on infty point, due to complete=True and no short_circuit + assert len(res) == 138 @pytest.mark.parametrize("k", [7, 25, 31]) |
