diff options
| author | J08nY | 2023-07-27 23:23:00 +0200 |
|---|---|---|
| committer | J08nY | 2023-07-27 23:23:00 +0200 |
| commit | a20952455b5dc4a2b3166807ef1205fdfc7d911e (patch) | |
| tree | 5402fe5a442f17fad0d0bce2f22e63b9f4816144 | |
| parent | f40b69968ad9bbb8300b451640a82e1ac83aa7ba (diff) | |
| download | pyecsca-a20952455b5dc4a2b3166807ef1205fdfc7d911e.tar.gz pyecsca-a20952455b5dc4a2b3166807ef1205fdfc7d911e.tar.zst pyecsca-a20952455b5dc4a2b3166807ef1205fdfc7d911e.zip | |
Add utilites for construction of RPA points.
| -rw-r--r-- | pyecsca/ec/mult.py | 6 | ||||
| -rw-r--r-- | pyecsca/sca/re/rpa.py | 44 |
2 files changed, 50 insertions, 0 deletions
diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index 53e593e..f50d664 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -48,6 +48,9 @@ class PrecomputationAction(Action): self.params = params self.point = point + def __repr__(self): + return f"{self.__class__.__name__}({self.params}, {self.point})" + @public class ScalarMultiplier(ABC): @@ -152,6 +155,9 @@ class ScalarMultiplier(ABC): self._params.curve.prime, point, **self._params.curve.parameters )[0] + def __repr__(self): + return f"{self.__class__.__name__}({tuple(self.formulas.values())}, short_circuit={self.short_circuit})" + def init(self, params: DomainParameters, point: Point): """ Initialize the scalar multiplier with :paramref:`~.init.params` and a :paramref:`~.init.point`. diff --git a/pyecsca/sca/re/rpa.py b/pyecsca/sca/re/rpa.py index 51b9738..7a7ca17 100644 --- a/pyecsca/sca/re/rpa.py +++ b/pyecsca/sca/re/rpa.py @@ -7,6 +7,9 @@ Provides functionality inspired by the Refined-Power Analysis attack by Goubin. from public import public from typing import MutableMapping, Optional +from sympy import FF, sympify, Poly, symbols + +from ...ec.coordinates import AffineCoordinateModel from ...ec.formula import ( FormulaAction, DoublingFormula, @@ -16,7 +19,10 @@ from ...ec.formula import ( DifferentialAdditionFormula, LadderFormula, ) +from ...ec.mod import Mod from ...ec.mult import ScalarMultiplicationAction, PrecomputationAction +from ...ec.params import DomainParameters +from ...ec.model import ShortWeierstrassModel, MontgomeryModel from ...ec.point import Point from ...ec.context import Context, Action @@ -79,3 +85,41 @@ class MultipleContext(Context): def __repr__(self): return f"{self.__class__.__name__}({self.base!r}, multiples={self.points.values()!r})" + + +def rpa_point_0y(params: DomainParameters): + """Construct a RPA point (0, y) for given domain parameters.""" + if isinstance(params.curve.model, ShortWeierstrassModel): + if not params.curve.parameters["b"].is_residue(): + return None + y = params.curve.parameters["b"].sqrt() + # TODO: We can take the negative as well. + return Point(AffineCoordinateModel(params.curve.model), x=Mod(0, params.curve.prime), y=y) + elif isinstance(params.curve.model, MontgomeryModel): + return Point(AffineCoordinateModel(params.curve.model), x=Mod(0, params.curve.prime), + y=Mod(0, params.curve.prime)) + else: + raise NotImplementedError + + +def rpa_point_x0(params: DomainParameters): + """Construct a RPA point (x, 0) for given domain parameters.""" + if isinstance(params.curve.model, ShortWeierstrassModel): + if (params.order * params.cofactor) % 2 != 0: + return None + k = FF(params.curve.prime) + expr = sympify("x^3 + a * x + b", evaluate=False) + expr = expr.subs("a", k(int(params.curve.parameters["a"]))) + expr = expr.subs("b", k(int(params.curve.parameters["b"]))) + poly = Poly(expr, symbols("x"), domain=k) + roots = poly.ground_roots() + # TODO: There may be more roots. + if not roots: + return None + x = Mod(int(roots[0]), params.curve.prime) + return Point(AffineCoordinateModel(params.curve.model), x=x, y=Mod(0, params.curve.prime)) + elif isinstance(params.curve.model, MontgomeryModel): + return Point(AffineCoordinateModel(params.curve.model), x=Mod(0, params.curve.prime), + y=Mod(0, params.curve.prime)) + else: + raise NotImplementedError |
