aboutsummaryrefslogtreecommitdiff
path: root/pyecsca
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca')
-rw-r--r--pyecsca/sca/re/epa.py28
-rw-r--r--pyecsca/sca/re/rpa.py83
2 files changed, 71 insertions, 40 deletions
diff --git a/pyecsca/sca/re/epa.py b/pyecsca/sca/re/epa.py
index 1f276d9..32abb45 100644
--- a/pyecsca/sca/re/epa.py
+++ b/pyecsca/sca/re/epa.py
@@ -2,34 +2,26 @@
Provides functionality inspired by the Exceptional Procedure Attack [EPA]_.
"""
-from typing import Callable, Literal, Type, Union
+from typing import Callable, Literal, Union
from public import public
-from pyecsca.ec.context import local
-from pyecsca.ec.formula.fake import FakePoint
-from pyecsca.ec.mult import ScalarMultiplier
-from pyecsca.ec.mult.fake import cached_fake_mult
-from pyecsca.ec.params import DomainParameters
+from pyecsca.ec.point import Point
from pyecsca.sca.re.rpa import MultipleContext
@public
def errors_out(
- scalar: int,
- params: DomainParameters,
- mult_class: Type[ScalarMultiplier],
- mult_factory: Callable,
+ ctx: MultipleContext,
+ out: Point,
check_funcs: dict[str, Callable],
check_condition: Union[Literal["all"], Literal["necessary"]],
precomp_to_affine: bool,
) -> bool:
"""
- :param scalar:
- :param params:
- :param mult_class:
- :param mult_factory:
+ :param ctx: The context containing the points and formulas.
+ :param out: The output point to check.
:param check_funcs:
:param check_condition:
:param precomp_to_affine:
@@ -38,14 +30,6 @@ def errors_out(
.. note::
The scalar multiplier must not short-circuit.
"""
- mult = cached_fake_mult(mult_class, mult_factory, params)
- ctx = MultipleContext(keep_base=True)
- with local(ctx, copy=False):
- mult.init(params, FakePoint(params.curve.coordinate_model))
-
- with local(ctx, copy=False):
- out = mult.multiply(scalar)
-
affine_points = {out, *ctx.precomp.values()} if precomp_to_affine else {out}
if check_condition == "all":
points = set(ctx.points.keys())
diff --git a/pyecsca/sca/re/rpa.py b/pyecsca/sca/re/rpa.py
index f9ccd1b..a150b9c 100644
--- a/pyecsca/sca/re/rpa.py
+++ b/pyecsca/sca/re/rpa.py
@@ -15,6 +15,7 @@ from typing import (
Type,
Literal,
Union,
+ Tuple,
)
from sympy import FF, sympify, Poly, symbols
@@ -421,20 +422,14 @@ class RPA(RE):
@public
-def multiples_computed(
+def multiple_graph(
scalar: int,
params: DomainParameters,
mult_class: Type[ScalarMultiplier],
mult_factory: Callable,
use_init: bool = True,
use_multiply: bool = True,
- kind: Union[
- Literal["all"],
- Literal["input"],
- Literal["necessary"],
- Literal["precomp+necessary"],
- ] = "all",
-) -> set[int]:
+) -> Tuple[MultipleContext, Point]:
"""
Compute the multiples computed for a given scalar and multiplier (quickly).
@@ -444,17 +439,8 @@ def multiples_computed(
: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).
- :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`.
+ :return: The context with the computed multiples and the resulting point.
"""
- if kind != "all" and not use_init:
- raise ValueError("Cannot use kind other than 'all' with use_init=False.")
-
mult = cached_fake_mult(mult_class, mult_factory, params)
ctx = MultipleContext(keep_base=True)
if use_init:
@@ -468,7 +454,27 @@ def multiples_computed(
out = mult.multiply(scalar)
else:
out = mult.multiply(scalar)
+ return ctx, out
+
+@public
+def multiples_from_graph(
+ ctx: MultipleContext,
+ out: Point,
+ kind: Union[
+ Literal["all"],
+ Literal["input"],
+ Literal["necessary"],
+ Literal["precomp+necessary"],
+ ] = "all",
+):
+ """
+
+ :param ctx:
+ :param out:
+ :param kind:
+ :return: A set of multiples computed for the scalar.
+ """
if kind == "all":
res = set(ctx.points.values())
elif kind == "input":
@@ -496,3 +502,44 @@ def multiples_computed(
else:
raise ValueError(f"Invalid kind {kind}")
return res - {0}
+
+
+@public
+def multiples_computed(
+ scalar: int,
+ params: DomainParameters,
+ mult_class: Type[ScalarMultiplier],
+ mult_factory: Callable,
+ use_init: bool = True,
+ use_multiply: bool = True,
+ kind: Union[
+ Literal["all"],
+ Literal["input"],
+ Literal["necessary"],
+ Literal["precomp+necessary"],
+ ] = "all",
+) -> 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).
+ :param kind: The kind of multiples to return. Can be one of "all", "input", "necessary", or "precomp+necessary".
+ :return: A set of multiples computed for the scalar.
+
+ .. 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.")
+
+ ctx, out = multiple_graph(
+ scalar, params, mult_class, mult_factory, use_init, use_multiply
+ )
+
+ return multiples_from_graph(ctx, out, kind) if ctx else set()