diff options
| author | J08nY | 2021-01-19 18:07:31 +0100 |
|---|---|---|
| committer | J08nY | 2021-01-19 18:07:31 +0100 |
| commit | 950811a3e6a995e8bd3b2063777aeddd2bee1b0f (patch) | |
| tree | 8c9676e27d973215c96402c815a54075a174feb0 | |
| parent | 616255ba3c8346e58152610941270d864caa89d9 (diff) | |
| download | pyecsca-950811a3e6a995e8bd3b2063777aeddd2bee1b0f.tar.gz pyecsca-950811a3e6a995e8bd3b2063777aeddd2bee1b0f.tar.zst pyecsca-950811a3e6a995e8bd3b2063777aeddd2bee1b0f.zip | |
Introduce explicit field argument to formula calls.
| -rw-r--r-- | pyecsca/ec/formula.py | 26 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 12 | ||||
| -rw-r--r-- | pyecsca/ec/point.py | 14 | ||||
| -rw-r--r-- | pyecsca/ec/signature.py | 2 | ||||
| -rw-r--r-- | test/ec/test_formula.py | 12 | ||||
| -rw-r--r-- | test/ec/test_regress.py | 4 |
6 files changed, 44 insertions, 26 deletions
diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index 38701cb..7a2736a 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -113,7 +113,12 @@ class Formula(ABC): unified: bool """Whether the formula is specifies that it is unified.""" - def __validate_points(self, points, params): + def __validate_params(self, field, params): + for key, value in params.items(): + if not isinstance(value, Mod) or value.n != field: + raise ValueError(f"Wrong param input {key} = {value}.") + + def __validate_points(self, field, points, params): # Validate number of inputs. if len(points) != self.num_inputs: raise ValueError(f"Wrong number of inputs for {self}.") @@ -122,6 +127,8 @@ class Formula(ABC): if point.coordinate_model != self.coordinate_model: raise ValueError(f"Wrong coordinate model of point {point}.") for coord, value in point.coords.items(): + if not isinstance(value, Mod) or value.n != field: + raise ValueError(f"Wrong coordinate input {coord} = {value} of point {i}.") params[coord + str(i + 1)] = value def __validate_assumptions(self, field, params): @@ -147,11 +154,11 @@ class Formula(ABC): raise ValueError( f"This formula couldn't be executed due to an unsupported assumption ({assumption_string}).") - def resolve(expr): - if not expr.args: - return expr + def resolve(expression): + if not expression.args: + return expression args = [] - for arg in expr.args: + for arg in expression.args: if isinstance(arg, Rational): a = arg.numerator() b = arg.denominator() @@ -159,7 +166,7 @@ class Formula(ABC): else: arg = resolve(arg) args.append(arg) - return expr.func(*args) + return expression.func(*args) expr = resolve(expr) poly = Poly(expr, symbols(param), domain=k) @@ -170,17 +177,18 @@ class Formula(ABC): else: raise UnsatisfiedAssumptionError(f"Unsatisfied assumption in the formula ({assumption_string}).") - def __call__(self, *points: Any, **params: Mod) -> Tuple[Any, ...]: + def __call__(self, field: int, *points: Any, **params: Mod) -> Tuple[Any, ...]: """ Execute a formula. + :param field: The field over which the computation is performed. :param points: Points to pass into the formula. :param params: Parameters of the curve. :return: The resulting point(s). """ from .point import Point - self.__validate_points(points, params) - field = int(params[next(iter(params.keys()))].n) # TODO: This is nasty... + self.__validate_params(field, params) + self.__validate_points(field, points, params) self.__validate_assumptions(field, params) # Execute the actual formula. with FormulaAction(self, *points, **params) as action: diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index 74325b5..1650736 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -73,7 +73,7 @@ class ScalarMultiplier(ABC): return copy(other) if other == self._params.curve.neutral: return copy(one) - return self.formulas["add"](one, other, **self._params.curve.parameters)[0] + return self.formulas["add"](self._params.curve.prime, one, other, **self._params.curve.parameters)[0] def _dbl(self, point: Point) -> Point: if "dbl" not in self.formulas: @@ -81,12 +81,12 @@ class ScalarMultiplier(ABC): if self.short_circuit: if point == self._params.curve.neutral: return copy(point) - return self.formulas["dbl"](point, **self._params.curve.parameters)[0] + return self.formulas["dbl"](self._params.curve.prime, 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._params.curve.parameters)[0] + return self.formulas["scl"](self._params.curve.prime, 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: @@ -96,7 +96,7 @@ class ScalarMultiplier(ABC): return to_dbl, to_add if to_add == self._params.curve.neutral: return self._dbl(to_dbl), to_dbl - return self.formulas["ladd"](start, to_dbl, to_add, **self._params.curve.parameters) + return self.formulas["ladd"](self._params.curve.prime, 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: @@ -106,12 +106,12 @@ class ScalarMultiplier(ABC): return copy(other) if other == self._params.curve.neutral: return copy(one) - return self.formulas["dadd"](start, one, other, **self._params.curve.parameters)[0] + return self.formulas["dadd"](self._params.curve.prime, 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._params.curve.parameters)[0] + return self.formulas["neg"](self._params.curve.prime, point, **self._params.curve.parameters)[0] def init(self, params: DomainParameters, point: Point): """ diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py index df9e054..11aee7d 100644 --- a/pyecsca/ec/point.py +++ b/pyecsca/ec/point.py @@ -33,14 +33,24 @@ class Point(object): """A point with coordinates in a coordinate model.""" coordinate_model: CoordinateModel coords: Mapping[str, Mod] + field: int def __init__(self, model: CoordinateModel, **coords: Mod): if not set(model.variables) == set(coords.keys()): raise ValueError self.coordinate_model = model self.coords = coords + field = None + for value in self.coords.values(): + if field is None: + field = value.n + else: + if field != value.n: + raise ValueError(f"Mismatched coordinate field of definition, {field} vs {value.n}.") + self.field = field def __getattribute__(self, name): + # Do the magic such that point.X1 works! if "coords" in super().__getattribute__("__dict__"): coords = super().__getattribute__("coords") if name in coords: @@ -141,8 +151,8 @@ class Point(object): return False if "z" in self.coordinate_model.formulas: formula = self.coordinate_model.formulas["z"] - self_mapped = formula(self) - other_mapped = formula(other) + self_mapped = formula(self.field, self) + other_mapped = formula(self.field, other) return self_mapped == other_mapped else: raise ValueError("No scaling formula available.") diff --git a/pyecsca/ec/signature.py b/pyecsca/ec/signature.py index e61dc1b..a97594b 100644 --- a/pyecsca/ec/signature.py +++ b/pyecsca/ec/signature.py @@ -186,7 +186,7 @@ class Signature(object): p1 = self.mult.multiply(int(u1)) self.mult.init(self.params, self.pubkey) p2 = self.mult.multiply(int(u2)) - p = self.add(p1, p2, **self.params.curve.parameters)[0] + p = self.add(self.params.curve.prime, p1, p2, **self.params.curve.parameters)[0] affine = p.to_affine() v = Mod(int(affine.x), self.params.order) return signature.r == int(v) diff --git a/test/ec/test_formula.py b/test/ec/test_formula.py index 779b140..a7ef691 100644 --- a/test/ec/test_formula.py +++ b/test/ec/test_formula.py @@ -18,9 +18,9 @@ class FormulaTests(TestCase): def test_wrong_call(self): with self.assertRaises(ValueError): - self.add() + self.add(self.secp128r1.curve.prime) with self.assertRaises(ValueError): - self.add(self.secp128r1.generator.to_affine(), self.secp128r1.generator.to_affine()) + self.add(self.secp128r1.curve.prime, self.secp128r1.generator.to_affine(), self.secp128r1.generator.to_affine()) def test_indices(self): self.assertEqual(self.add.input_index, 1) @@ -44,18 +44,18 @@ class FormulaTests(TestCase): self.assertEqual(self.add.num_addsubs, 10) def test_assumptions(self): - res = self.mdbl(self.secp128r1.generator, **self.secp128r1.curve.parameters) + res = self.mdbl(self.secp128r1.curve.prime, self.secp128r1.generator, **self.secp128r1.curve.parameters) self.assertIsNotNone(res) coords = {name: value * 5 for name, value in self.secp128r1.generator.coords.items()} other = Point(self.secp128r1.generator.coordinate_model, **coords) with self.assertRaises(UnsatisfiedAssumptionError): - self.mdbl(other, **self.secp128r1.curve.parameters) + self.mdbl(self.secp128r1.curve.prime, other, **self.secp128r1.curve.parameters) with TemporaryConfig() as cfg: cfg.ec.unsatisfied_formula_assumption_action = "ignore" - pt = self.mdbl(other, **self.secp128r1.curve.parameters) + pt = self.mdbl(self.secp128r1.curve.prime, other, **self.secp128r1.curve.parameters) self.assertIsNotNone(pt) def test_parameters(self): - res = self.jac_dbl(self.jac_secp128r1.generator, **self.jac_secp128r1.curve.parameters) + res = self.jac_dbl(self.secp128r1.curve.prime, self.jac_secp128r1.generator, **self.jac_secp128r1.curve.parameters) self.assertIsNotNone(res) diff --git a/test/ec/test_regress.py b/test/ec/test_regress.py index fe14eb3..ef593fc 100644 --- a/test/ec/test_regress.py +++ b/test/ec/test_regress.py @@ -47,12 +47,12 @@ class RegressionTests(TestCase): curve = EllipticCurve(model, coords, p, neutral, {"a": Mod(8, p), "b": Mod(1, p)}) base = Point(coords, X=Mod(12, p), Z=Mod(1, p)) formula = coords.formulas["dbl-1987-m-2"] - res = formula(base, **curve.parameters)[0] + res = formula(p, base, **curve.parameters)[0] self.assertIsNotNone(res) affine_base = Point(AffineCoordinateModel(model), x=Mod(12, p), y=Mod(2, p)) dbase = curve.affine_double(affine_base).to_model(coords, curve) ladder = coords.formulas["ladd-1987-m-3"] - one, other = ladder(base, dbase, base, **curve.parameters) + one, other = ladder(p, base, dbase, base, **curve.parameters) self.assertIsNotNone(one) self.assertIsNotNone(other) |
