diff options
| author | J08nY | 2018-12-15 16:43:44 +0100 |
|---|---|---|
| committer | J08nY | 2019-03-21 11:00:14 +0100 |
| commit | bec2c56a86ce1d0b2285aaed50726fbdba42d620 (patch) | |
| tree | 65e4266481ed851a0f41367ecc8ba399de8f4240 | |
| parent | ba8212dbc9cee4c098838534c096486ad5bf759a (diff) | |
| download | pyecsca-bec2c56a86ce1d0b2285aaed50726fbdba42d620.tar.gz pyecsca-bec2c56a86ce1d0b2285aaed50726fbdba42d620.tar.zst pyecsca-bec2c56a86ce1d0b2285aaed50726fbdba42d620.zip | |
| -rw-r--r-- | pyecsca/ec/context.py | 16 | ||||
| -rw-r--r-- | pyecsca/ec/formula.py | 28 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 35 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 37 |
4 files changed, 93 insertions, 23 deletions
diff --git a/pyecsca/ec/context.py b/pyecsca/ec/context.py index b4667cf..e691184 100644 --- a/pyecsca/ec/context.py +++ b/pyecsca/ec/context.py @@ -13,7 +13,9 @@ class Context(object): self.intermediates = [] self.actions = [] - def execute(self, formula: Formula, *points: Point, **params: Mod) -> Point: + def execute(self, formula: Formula, *points: Point, **params: Mod) -> Tuple[Point, ...]: + if len(points) != formula.num_inputs: + raise ValueError self.actions.append((formula, tuple(points))) coords = {} for i, point in enumerate(points): @@ -29,7 +31,11 @@ class Context(object): previous_locals = set(locals.keys()) for key in diff: self.intermediates.append((key, locals[key])) - resulting = {variable: locals[variable + "3"] - for variable in formula.coordinate_model.variables - if variable + "3" in locals} - return Point(formula.coordinate_model, **resulting) + result = [] + for i in range(formula.num_outputs): + ind = str(i + 3) + resulting = {variable: locals[variable + ind] + for variable in formula.coordinate_model.variables + if variable + ind in locals} + result.append(Point(formula.coordinate_model, **resulting)) + return tuple(result) diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index 877f4d5..80139b7 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -10,6 +10,8 @@ class Formula(object): parameters: List[str] assumptions: List[Expression] code: List[Module] + _inputs: int + _outputs: int def __init__(self, path: str, name: str, coordinate_model: Any): self.name = name @@ -39,29 +41,43 @@ class Formula(object): for line in f.readlines(): self.code.append(parse(line.decode("ascii").replace("^", "**"), path, mode="exec")) + @property + def num_inputs(self): + return self._inputs + + @property + def num_outputs(self): + return self._outputs + def __repr__(self): return self.__class__.__name__ + "({} for {})".format(self.name, self.coordinate_model) class AdditionFormula(Formula): - pass + _inputs = 2 + _outputs = 1 class DoublingFormula(Formula): - pass + _inputs = 1 + _outputs = 1 class TriplingFormula(Formula): - pass + _inputs = 1 + _outputs = 1 class ScalingFormula(Formula): - pass + _inputs = 1 + _outputs = 1 class DifferentialAdditionFormula(Formula): - pass + _inputs = 3 + _outputs = 1 class LadderFormula(Formula): - pass + _inputs = 3 + _outputs = 2 diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index 4dd0f5b..a32a54b 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -1,9 +1,9 @@ from copy import copy -from typing import Mapping +from typing import Mapping, Tuple from .context import Context from .curve import EllipticCurve -from .formula import Formula, AdditionFormula, DoublingFormula, ScalingFormula +from .formula import Formula, AdditionFormula, DoublingFormula, ScalingFormula, LadderFormula from .point import Point @@ -30,19 +30,25 @@ class ScalarMultiplier(object): return copy(other) if other == self.curve.neutral: return copy(one) - return self.context.execute(self.formulas["add"], one, other, **self.curve.parameters) + return self.context.execute(self.formulas["add"], one, other, **self.curve.parameters)[0] def _dbl(self, point: Point) -> Point: if "dbl" not in self.formulas: raise NotImplementedError if point == self.curve.neutral: return copy(point) - return self.context.execute(self.formulas["dbl"], point, **self.curve.parameters) + return self.context.execute(self.formulas["dbl"], point, **self.curve.parameters)[0] def _scl(self, point: Point) -> Point: if "scl" not in self.formulas: raise NotImplementedError - return self.context.execute(self.formulas["scl"], point, **self.curve.parameters) + return self.context.execute(self.formulas["scl"], point, **self.curve.parameters)[0] + + def _ladd(self, start: Point, to_dbl: Point, to_add: Point) -> Tuple[Point, Point]: + if "ladd" not in self.formulas: + raise NotImplementedError + return self.context.execute(self.formulas["ladd"], start, to_dbl, to_add, + **self.curve.parameters) def multiply(self, scalar: int, point: Point) -> Point: raise NotImplementedError @@ -91,3 +97,22 @@ class RTLMultiplier(ScalarMultiplier): if "scl" in self.formulas: r = self._scl(r) return r + + +class LadderMultiplier(ScalarMultiplier): + + def __init__(self, curve: EllipticCurve, ladd: LadderFormula, scl: ScalingFormula = None, + ctx: Context = None): + super().__init__(curve, ctx, ladd=ladd, scl=scl) + + def multiply(self, scalar: int, point: Point) -> Point: + p0 = copy(point) + p1 = self._ladd(self.curve.neutral, point, point)[1] + for i in range(scalar.bit_length(), -1, -1): + if scalar & i != 0: + p0, p1 = self._ladd(point, p1, p0) + else: + p0, p1 = self._ladd(point, p0, p1) + if "scl" in self.formulas: + p0 = self._scl(p0) + return p0 diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index ec26335..38c7367 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -2,8 +2,8 @@ from unittest import TestCase from pyecsca.ec.curve import EllipticCurve from pyecsca.ec.mod import Mod -from pyecsca.ec.model import ShortWeierstrassModel -from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier +from pyecsca.ec.model import ShortWeierstrassModel, MontgomeryModel +from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier, LadderMultiplier from pyecsca.ec.point import Point @@ -12,24 +12,47 @@ class ScalarMultiplierTests(TestCase): def setUp(self): self.p = 0xfffffffdffffffffffffffffffffffff self.coords = ShortWeierstrassModel.coordinates["projective"] + self.base = Point(self.coords, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.p), + Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.p), + Z=Mod(1, self.p)) self.secp128r1 = EllipticCurve(ShortWeierstrassModel, self.coords, dict(a=0xfffffffdfffffffffffffffffffffffc, b=0xe87579c11079f43dd824993c2cee5ed3), Point(self.coords, X=Mod(0, self.p), Y=Mod(1, self.p), Z=Mod(0, self.p))) - self.base = Point(self.coords, X=Mod(0x161ff7528b899b2d0c28607ca52c5b86, self.p), - Y=Mod(0xcf5ac8395bafeb13c02da292dded7a83, self.p), - Z=Mod(1, self.p)) + + self.coords25519 = MontgomeryModel.coordinates["xz"] + self.p25519 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed + self.base25519 = Point(self.coords25519, X=Mod(9, self.p25519), + Z=Mod(1, self.p25519)) + self.curve25519 = EllipticCurve(MontgomeryModel, self.coords25519, + dict(a=486662, b=1), + Point(self.coords25519, + X=Mod(0, self.p25519), Z=Mod(1, self.p25519))) def test_rtl_simple(self): mult = RTLMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], self.coords.formulas["dbl-1998-cmo"], self.coords.formulas["z"]) - mult.multiply(10, self.base) + res = mult.multiply(10, self.base) + other = mult.multiply(5, self.base) + other = mult.multiply(2, other) + self.assertEqual(res, other) def test_ltr_simple(self): mult = LTRMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], self.coords.formulas["dbl-1998-cmo"], self.coords.formulas["z"]) - mult.multiply(10, self.base) + res = mult.multiply(10, self.base) + other = mult.multiply(5, self.base) + other = mult.multiply(2, other) + self.assertEqual(res, other) + + def test_ladder_simple(self): + mult = LadderMultiplier(self.curve25519, self.coords25519.formulas["ladd-1987-m"], + self.coords25519.formulas["scale"]) + res = mult.multiply(15, self.base25519) + other = mult.multiply(3, self.base25519) + other = mult.multiply(5, other) + self.assertEqual(res, other) def test_basic_multipliers(self): ltr = LTRMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], |
