diff options
| -rw-r--r-- | pyecsca/ec/coordinates.py | 4 | ||||
| -rw-r--r-- | pyecsca/ec/curves.py | 9 | ||||
| -rw-r--r-- | pyecsca/ec/model.py | 6 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 82 | ||||
| -rw-r--r-- | pyecsca/ec/params.py | 2 | ||||
| -rw-r--r-- | pyecsca/sca/target/__init__.py | 1 | ||||
| -rw-r--r-- | test/ec/test_curves.py | 4 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 12 |
8 files changed, 67 insertions, 53 deletions
diff --git a/pyecsca/ec/coordinates.py b/pyecsca/ec/coordinates.py index 9043e76..1838659 100644 --- a/pyecsca/ec/coordinates.py +++ b/pyecsca/ec/coordinates.py @@ -20,7 +20,7 @@ class CoordinateModel(object): variables: List[str] satisfying: List[Module] parameters: List[str] - assumptions: List[Expression] + assumptions: List[Module] formulas: MutableMapping[str, Formula] def __repr__(self): @@ -99,7 +99,7 @@ class EFDCoordinateModel(CoordinateModel): self.parameters.append(line[10:]) elif line.startswith("assume"): self.assumptions.append( - parse(line[7:].replace("=", "==").replace("^", "**"), mode="eval")) + parse(line[7:].replace("^", "**"), mode="exec")) line = f.readline().decode("ascii") def __eq__(self, other): diff --git a/pyecsca/ec/curves.py b/pyecsca/ec/curves.py index 09964ea..e002a9c 100644 --- a/pyecsca/ec/curves.py +++ b/pyecsca/ec/curves.py @@ -60,7 +60,14 @@ def get_params(category: str, name: str, coords: str) -> DomainParameters: if coords not in model.coordinates: raise ValueError("Coordinate model not supported for curve.") coord_model = model.coordinates[coords] - params = {name: int(curve["params"][name], 16) for name in param_names} + params = {name: Mod(int(curve["params"][name], 16), field) for name in param_names} + for assumption in coord_model.assumptions: + locals = {} + compiled = compile(assumption, "", mode="exec") + exec(compiled, None, locals) + for param, value in locals.items(): + if params[param] != value: + raise ValueError(f"Coordinate model {coord_model} has an unsatisifed assumption on the {param} parameter (= {value}).") elliptic_curve = EllipticCurve(model, coord_model, field, params) affine = Point(AffineCoordinateModel(model), x=Mod(int(curve["generator"]["x"], 16), field), y=Mod(int(curve["generator"]["y"], 16), field)) diff --git a/pyecsca/ec/model.py b/pyecsca/ec/model.py index 093a3cb..90c99a3 100644 --- a/pyecsca/ec/model.py +++ b/pyecsca/ec/model.py @@ -10,6 +10,7 @@ from .coordinates import EFDCoordinateModel, CoordinateModel class CurveModel(object): """A model(form) of an elliptic curve.""" name: str + shortname: str coordinates: MutableMapping[str, CoordinateModel] parameter_names: List[str] coordinate_names: List[str] @@ -34,6 +35,7 @@ class EFDCurveModel(CurveModel): def __init__(self, efd_name: str): self._efd_name = efd_name + self.shortname = efd_name if self._loaded: return self.__class__._loaded = True @@ -91,6 +93,10 @@ class EFDCurveModel(CurveModel): def __read_coordinate_dir(self, cls, dir_path, name): cls.coordinates[name] = EFDCoordinateModel(dir_path, name, self) + @classmethod + def add(cls, one, other): + pass + def __eq__(self, other): if not isinstance(other, EFDCurveModel): return False diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index 35cb6fe..ae7155b 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -39,7 +39,7 @@ class ScalarMultiplier(ABC): optionals: ClassVar[Set[Type[Formula]]] short_circuit: bool formulas: Mapping[str, Formula] - _group: DomainParameters + _params: DomainParameters _point: Point _initialized: bool = False @@ -54,56 +54,56 @@ class ScalarMultiplier(ABC): if "add" not in self.formulas: raise NotImplementedError if self.short_circuit: - if one == self._group.neutral: + if one == self._params.neutral: return copy(other) - if other == self._group.neutral: + if other == self._params.neutral: return copy(one) - return self.formulas["add"](one, other, **self._group.curve.parameters)[0] + return self.formulas["add"](one, other, **self._params.curve.parameters)[0] def _dbl(self, point: Point) -> Point: if "dbl" not in self.formulas: raise NotImplementedError if self.short_circuit: - if point == self._group.neutral: + if point == self._params.neutral: return copy(point) - return self.formulas["dbl"](point, **self._group.curve.parameters)[0] + return self.formulas["dbl"](point, **self._params.curve.parameters)[0] def _scl(self, point: Point) -> Point: if "scl" not in self.formulas: raise NotImplementedError - return self.formulas["scl"](point, **self._group.curve.parameters)[0] + return self.formulas["scl"](point, **self._params.curve.parameters)[0] def _ladd(self, start: Point, to_dbl: Point, to_add: Point) -> Tuple[Point, ...]: if "ladd" not in self.formulas: raise NotImplementedError if self.short_circuit: - if to_dbl == self._group.neutral: + if to_dbl == self._params.neutral: return to_dbl, to_add - if to_add == self._group.neutral: + if to_add == self._params.neutral: return self._dbl(to_dbl), to_dbl - return self.formulas["ladd"](start, to_dbl, to_add, **self._group.curve.parameters) + return self.formulas["ladd"](start, to_dbl, to_add, **self._params.curve.parameters) def _dadd(self, start: Point, one: Point, other: Point) -> Point: if "dadd" not in self.formulas: raise NotImplementedError if self.short_circuit: - if one == self._group.neutral: + if one == self._params.neutral: return copy(other) - if other == self._group.neutral: + if other == self._params.neutral: return copy(one) - return self.formulas["dadd"](start, one, other, **self._group.curve.parameters)[0] + return self.formulas["dadd"](start, one, other, **self._params.curve.parameters)[0] def _neg(self, point: Point) -> Point: if "neg" not in self.formulas: raise NotImplementedError - return self.formulas["neg"](point, **self._group.curve.parameters)[0] + return self.formulas["neg"](point, **self._params.curve.parameters)[0] - def init(self, group: DomainParameters, point: Point): - """Initialize the scalar multiplier with a group and a point.""" + def init(self, params: DomainParameters, point: Point): + """Initialize the scalar multiplier with params and a point.""" coord_model = set(self.formulas.values()).pop().coordinate_model - if group.curve.coordinate_model != coord_model or point.coordinate_model != coord_model: + if params.curve.coordinate_model != coord_model or point.coordinate_model != coord_model: raise ValueError - self._group = group + self._params = params self._point = point self._initialized = True @@ -137,11 +137,11 @@ class LTRMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) if self.complete: q = self._point - r = copy(self._group.neutral) - top = self._group.order.bit_length() - 1 + r = copy(self._params.neutral) + top = self._params.order.bit_length() - 1 else: q = self._dbl(self._point) r = copy(self._point) @@ -178,9 +178,9 @@ class RTLMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) q = self._point - r = copy(self._group.neutral) + r = copy(self._params.neutral) while scalar > 0: if scalar & 1 != 0: r = self._add(r, q) @@ -213,7 +213,7 @@ class CoronMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) q = self._point p0 = copy(q) for i in range(scalar.bit_length() - 2, -1, -1): @@ -247,12 +247,12 @@ class LadderMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) q = self._point if self.complete: - p0 = copy(self._group.neutral) + p0 = copy(self._params.neutral) p1 = self._point - top = self._group.order.bit_length() - 1 + top = self._params.order.bit_length() - 1 else: p0 = copy(q) p1 = self._dbl(q) @@ -286,12 +286,12 @@ class SimpleLadderMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) if self.complete: - top = self._group.order.bit_length() - 1 + top = self._params.order.bit_length() - 1 else: top = scalar.bit_length() - 1 - p0 = copy(self._group.neutral) + p0 = copy(self._params.neutral) p1 = copy(self._point) for i in range(top, -1, -1): if scalar & (1 << i) == 0: @@ -324,13 +324,13 @@ class DifferentialLadderMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) if self.complete: - top = self._group.order.bit_length() - 1 + top = self._params.order.bit_length() - 1 else: top = scalar.bit_length() - 1 q = self._point - p0 = copy(self._group.neutral) + p0 = copy(self._params.neutral) p1 = copy(q) for i in range(top, -1, -1): if scalar & (1 << i) == 0: @@ -355,8 +355,8 @@ class BinaryNAFMultiplier(ScalarMultiplier): neg: NegationFormula, scl: ScalingFormula = None, short_circuit: bool = True): super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, neg=neg, scl=scl) - def init(self, group: DomainParameters, point: Point): - super().init(group, point) + def init(self, params: DomainParameters, point: Point): + super().init(params, point) self._point_neg = self._neg(point) def multiply(self, scalar: int) -> Point: @@ -364,9 +364,9 @@ class BinaryNAFMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) bnaf = naf(scalar) - q = copy(self._group.neutral) + q = copy(self._params.neutral) for val in bnaf: q = self._dbl(q) if val == 1: @@ -395,8 +395,8 @@ class WindowNAFMultiplier(ScalarMultiplier): self.width = width self.precompute_negation = precompute_negation - def init(self, group: DomainParameters, point: Point): - super().init(group, point) + def init(self, params: DomainParameters, point: Point): + super().init(params, point) self._points = {} self._points_neg = {} current_point = point @@ -412,9 +412,9 @@ class WindowNAFMultiplier(ScalarMultiplier): raise ValueError("ScalaMultiplier not initialized.") with ScalarMultiplicationAction(self._point, scalar): if scalar == 0: - return copy(self._group.neutral) + return copy(self._params.neutral) naf = wnaf(scalar, self.width) - q = copy(self._group.neutral) + q = copy(self._params.neutral) for val in naf: q = self._dbl(q) if val > 0: diff --git a/pyecsca/ec/params.py b/pyecsca/ec/params.py index 7c2e504..41d8a78 100644 --- a/pyecsca/ec/params.py +++ b/pyecsca/ec/params.py @@ -8,7 +8,7 @@ from .point import Point @public class DomainParameters(object): - """A (sub)group of an elliptic curve.""" + """Domain parameters which specify a subgroup on an elliptic curve.""" curve: EllipticCurve generator: Point neutral: Point diff --git a/pyecsca/sca/target/__init__.py b/pyecsca/sca/target/__init__.py index e75526a..86317df 100644 --- a/pyecsca/sca/target/__init__.py +++ b/pyecsca/sca/target/__init__.py @@ -2,6 +2,7 @@ from .ISO7816 import * from .base import * +from .serial import * has_chipwhisperer = False has_pyscard = False diff --git a/test/ec/test_curves.py b/test/ec/test_curves.py index 1f6a117..173aaf2 100644 --- a/test/ec/test_curves.py +++ b/test/ec/test_curves.py @@ -17,9 +17,9 @@ class CurvesTests(TestCase): ("other/E-222", "projective") ]) def test_get_params(self, name, coords): - group = get_params(*name.split("/"), coords) + params = get_params(*name.split("/"), coords) try: - assert group.curve.is_on_curve(group.generator) + assert params.curve.is_on_curve(params.generator) except NotImplementedError: pass diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index 2f4308e..6c89521 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -30,17 +30,17 @@ class ScalarMultiplierTests(TestCase): else: assert one.equals(other) - def do_basic_test(self, mult_class, group, base, add, dbl, scale, neg=None, **kwargs): - mult = mult_class(*self.get_formulas(group.curve.coordinate_model, add, dbl, neg, scale), + def do_basic_test(self, mult_class, params, base, add, dbl, scale, neg=None, **kwargs): + mult = mult_class(*self.get_formulas(params.curve.coordinate_model, add, dbl, neg, scale), **kwargs) - mult.init(group, base) + mult.init(params, base) res = mult.multiply(314) other = mult.multiply(157) - mult.init(group, other) + mult.init(params, other) other = mult.multiply(2) self.assertPointEquality(res, other, scale) - mult.init(group, base) - self.assertEqual(InfinityPoint(group.curve.coordinate_model), mult.multiply(0)) + mult.init(params, base) + self.assertEqual(InfinityPoint(params.curve.coordinate_model), mult.multiply(0)) @parameterized.expand([ ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), |
