aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Pipfile1
-rw-r--r--pyecsca/ec/mult.py35
-rw-r--r--setup.py1
-rw-r--r--test/ec/test_mult.py32
4 files changed, 55 insertions, 14 deletions
diff --git a/Pipfile b/Pipfile
index fc6d85c..62662d3 100644
--- a/Pipfile
+++ b/Pipfile
@@ -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
diff --git a/setup.py b/setup.py
index 75eebac..a2de0fb 100644
--- a/setup.py
+++ b/setup.py
@@ -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)