diff options
| -rw-r--r-- | Pipfile | 1 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 35 | ||||
| -rw-r--r-- | setup.py | 1 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 32 |
4 files changed, 55 insertions, 14 deletions
@@ -17,6 +17,7 @@ atpublic = "*" matplotlib = "*" cython = "*" fastdtw = {path = "./../fastdtw"} +parameterized = "*" [requires] python_version = "3.7" diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index a623fd0..c0fe994 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -1,10 +1,11 @@ from copy import copy -from typing import Mapping, Tuple, Optional, List +from typing import Mapping, Tuple, Optional, MutableMapping from pyecsca.ec.naf import naf, wnaf from .context import Context from .curve import EllipticCurve -from .formula import Formula, AdditionFormula, DoublingFormula, ScalingFormula, LadderFormula +from .formula import (Formula, AdditionFormula, DoublingFormula, ScalingFormula, LadderFormula, + NegationFormula) from .point import Point @@ -53,8 +54,9 @@ class ScalarMultiplier(object): **self.curve.parameters) def _neg(self, point: Point) -> Point: - # TODO - raise NotImplementedError + if "neg" not in self.formulas: + raise NotImplementedError + return self.context.execute(self.formulas["neg"], point, **self.curve.parameters)[0] def init(self, point: Point): self._point = point @@ -143,9 +145,8 @@ class BinaryNAFMultiplier(ScalarMultiplier): _point_neg: Point def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, - scl: ScalingFormula = None, - ctx: Context = None): - super().__init__(curve, ctx, add=add, dbl=dbl, scl=scl) + neg: NegationFormula, scl: ScalingFormula = None, ctx: Context = None): + super().__init__(curve, ctx, add=add, dbl=dbl, neg=neg, scl=scl) def init(self, point: Point): super().init(point) @@ -161,22 +162,28 @@ class BinaryNAFMultiplier(ScalarMultiplier): q = self._add(q, self._point) if val == -1: q = self._add(q, self._point_neg) + if "scl" in self.formulas: + q = self._scl(q) return q class WindowNAFMultiplier(ScalarMultiplier): - _points: List[Point] + _points: MutableMapping[int, Point] _width: int - def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, width: int, - scl: ScalingFormula = None, - ctx: Context = None): - super().__init__(curve, ctx, add=add, dbl=dbl, scl=scl) + def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, + neg: NegationFormula, width: int, scl: ScalingFormula = None, ctx: Context = None): + super().__init__(curve, ctx, add=add, dbl=dbl, neg=neg, scl=scl) self._width = width def init(self, point: Point): self._point = point - # TODO: precompute {1, 3, 5, upto 2^(w-1)-1} + self._points = {} + current_point = point + double_point = self._dbl(point) + for i in range(1, (self._width + 1) // 2 + 1): + self._points[2 ** i - 1] = current_point + current_point = self._add(current_point, double_point) def multiply(self, scalar: int, point: Optional[Point] = None): self._init_multiply(point) @@ -189,4 +196,6 @@ class WindowNAFMultiplier(ScalarMultiplier): elif val < 0: neg = self._neg(self._points[-val]) q = self._add(q, neg) + if "scl" in self.formulas: + q = self._scl(q) return q @@ -31,6 +31,7 @@ setup( ], tests_require=[ "nose2", + "parameterized", "green" ] ) diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index 1a2bc7e..258a525 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -3,7 +3,7 @@ from unittest import TestCase from pyecsca.ec.curve import EllipticCurve from pyecsca.ec.mod import Mod from pyecsca.ec.model import ShortWeierstrassModel, MontgomeryModel -from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier, LadderMultiplier +from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier, LadderMultiplier, BinaryNAFMultiplier, WindowNAFMultiplier from pyecsca.ec.point import Point @@ -54,6 +54,24 @@ class ScalarMultiplierTests(TestCase): other = mult.multiply(5, other) self.assertEqual(res, other) + def test_binary_naf_simple(self): + mult = BinaryNAFMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["neg"], self.coords.formulas["z"]) + res = mult.multiply(10, self.base) + other = mult.multiply(5, self.base) + other = mult.multiply(2, other) + self.assertEqual(res, other) + + def test_window_naf_simple(self): + mult = WindowNAFMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["neg"], 3, self.coords.formulas["z"]) + res = mult.multiply(10, self.base) + other = mult.multiply(5, self.base) + other = mult.multiply(2, other) + self.assertEqual(res, other) + def test_basic_multipliers(self): ltr = LTRMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], self.coords.formulas["dbl-1998-cmo"], self.coords.formulas["z"]) @@ -73,3 +91,15 @@ class ScalarMultiplierTests(TestCase): res_rtl_always = rtl_always.multiply(10, self.base) self.assertEqual(res_ltr, res_ltr_always) self.assertEqual(res_rtl, res_rtl_always) + + bnaf = BinaryNAFMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["neg"], self.coords.formulas["z"]) + res_bnaf = bnaf.multiply(10, self.base) + self.assertEqual(res_bnaf, res_ltr) + + wnaf = WindowNAFMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["neg"], 3, self.coords.formulas["z"]) + res_wnaf = wnaf.multiply(10, self.base) + self.assertEqual(res_wnaf, res_ltr) |
