diff options
| author | J08nY | 2018-12-19 17:00:30 +0100 |
|---|---|---|
| committer | J08nY | 2019-03-21 11:00:14 +0100 |
| commit | 0f844cc1e15564dd1b53d7bfbe175302730c9758 (patch) | |
| tree | 6ea77c92bd82022eeafa2c405bf83c5ba571358d | |
| parent | fe1d8873331109342348d7ab58c3415c65aec57c (diff) | |
| download | pyecsca-0f844cc1e15564dd1b53d7bfbe175302730c9758.tar.gz pyecsca-0f844cc1e15564dd1b53d7bfbe175302730c9758.tar.zst pyecsca-0f844cc1e15564dd1b53d7bfbe175302730c9758.zip | |
| -rw-r--r-- | docs/conf.py | 3 | ||||
| -rw-r--r-- | pyecsca/ec/curve.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/formula.py | 2 | ||||
| -rw-r--r-- | pyecsca/ec/model.py | 3 | ||||
| -rw-r--r-- | pyecsca/ec/mult.py | 48 | ||||
| -rw-r--r-- | pyecsca/ec/point.py | 1 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 25 |
7 files changed, 77 insertions, 7 deletions
diff --git a/docs/conf.py b/docs/conf.py index 3e081ad..42b9090 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -194,7 +194,4 @@ epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True
\ No newline at end of file diff --git a/pyecsca/ec/curve.py b/pyecsca/ec/curve.py index 20dd3e0..ea18233 100644 --- a/pyecsca/ec/curve.py +++ b/pyecsca/ec/curve.py @@ -15,6 +15,7 @@ class EllipticCurve(object): def __init__(self, model: CurveModel, coordinate_model: CoordinateModel, parameters: Mapping[str, int], neutral: Point): + # TODO: Add base_point arg, order arg, cofactor arg. if coordinate_model not in model.coordinates.values(): raise ValueError if set(model.parameter_names).symmetric_difference(parameters.keys()): @@ -27,6 +28,7 @@ class EllipticCurve(object): self.neutral = neutral def is_on_curve(self, point: Point) -> bool: + #TODO pass def is_neutral(self, point: Point) -> bool: diff --git a/pyecsca/ec/formula.py b/pyecsca/ec/formula.py index e155282..fd58a31 100644 --- a/pyecsca/ec/formula.py +++ b/pyecsca/ec/formula.py @@ -14,6 +14,8 @@ class Formula(object): _inputs: int _outputs: int + # TODO: Separate into EFDFormula? + def __init__(self, path: str, name: str, coordinate_model: Any): self.name = name self.coordinate_model = coordinate_model diff --git a/pyecsca/ec/model.py b/pyecsca/ec/model.py index 40c19e9..cc474f5 100644 --- a/pyecsca/ec/model.py +++ b/pyecsca/ec/model.py @@ -20,6 +20,9 @@ class CurveModel(object): to_weierstrass: List[Module] from_weierstrass: List[Module] + #TODO: move the base_formulas into methods, operatin on affine points? + # Also to_weierstrass anf from_weierstrass. + class EFDCurveModel(CurveModel): _efd_name: str diff --git a/pyecsca/ec/mult.py b/pyecsca/ec/mult.py index d7c5bc6..aba2739 100644 --- a/pyecsca/ec/mult.py +++ b/pyecsca/ec/mult.py @@ -77,6 +77,11 @@ class ScalarMultiplier(object): @public class LTRMultiplier(ScalarMultiplier): + """ + Classic double and add scalar multiplication algorithm, that scans the scalar left-to-right (msb to lsb) + + The `always` parameter determines whether the double and add always method is used. + """ always: bool def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, @@ -101,6 +106,11 @@ class LTRMultiplier(ScalarMultiplier): @public class RTLMultiplier(ScalarMultiplier): + """ + Classic double and add scalar multiplication algorithm, that scans the scalar right-to-left (lsb to msb) + + The `always` parameter determines whether the double and add always method is used. + """ always: bool def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, @@ -124,8 +134,37 @@ class RTLMultiplier(ScalarMultiplier): return r +class CoronMultiplier(ScalarMultiplier): + """ + Coron's double and add resistant against SPA, from: + + Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems + + https://link.springer.com/content/pdf/10.1007/3-540-48059-5_25.pdf + """ + + 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) + + def multiply(self, scalar: int, point: Optional[Point] = None): + q = self._init_multiply(point) + p0 = copy(q) + for i in range(scalar.bit_length() - 2, -1, -1): + p0 = self._dbl(p0) + p1 = self._add(p0, q) + if scalar & (1 << i) != 0: + p0 = p1 + if "scl" in self.formulas: + p0 = self._scl(p0) + return p0 + + @public class LadderMultiplier(ScalarMultiplier): + """ + Montgomery ladder multiplier, using a three input, two output ladder formula. + """ def __init__(self, curve: EllipticCurve, ladd: LadderFormula, scl: ScalingFormula = None, ctx: Context = None): @@ -147,6 +186,9 @@ class LadderMultiplier(ScalarMultiplier): @public class SimpleLadderMultiplier(ScalarMultiplier): + """ + Montgomery ladder multiplier, using addition and doubling formulas. + """ def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, scl: ScalingFormula = None, ctx: Context = None): @@ -170,6 +212,9 @@ class SimpleLadderMultiplier(ScalarMultiplier): @public class BinaryNAFMultiplier(ScalarMultiplier): + """ + Binary NAF (Non Adjacent Form) multiplier, left-to-right. + """ _point_neg: Point def __init__(self, curve: EllipticCurve, add: AdditionFormula, dbl: DoublingFormula, @@ -197,6 +242,9 @@ class BinaryNAFMultiplier(ScalarMultiplier): @public class WindowNAFMultiplier(ScalarMultiplier): + """ + Window NAF (Non Adjacent Form) multiplier, left-to-right. + """ _points: MutableMapping[int, Point] _width: int diff --git a/pyecsca/ec/point.py b/pyecsca/ec/point.py index 265a0ea..05f2503 100644 --- a/pyecsca/ec/point.py +++ b/pyecsca/ec/point.py @@ -15,6 +15,7 @@ class Point(object): self.coords = coords def __eq__(self, other): + # TODO: Somehow compare projective points. Via a map to an affinepoint? if type(other) is not Point: return False return self.coordinate_model == other.coordinate_model and self.coords == other.coords diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index cda9f76..100e53d 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -3,7 +3,8 @@ 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, BinaryNAFMultiplier, WindowNAFMultiplier, SimpleLadderMultiplier +from pyecsca.ec.mult import (LTRMultiplier, RTLMultiplier, LadderMultiplier, BinaryNAFMultiplier, + WindowNAFMultiplier, SimpleLadderMultiplier, CoronMultiplier) from pyecsca.ec.point import Point @@ -46,6 +47,14 @@ class ScalarMultiplierTests(TestCase): other = mult.multiply(2, other) self.assertEqual(res, other) + def test_coron(self): + mult = CoronMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], 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_ladder(self): mult = LadderMultiplier(self.curve25519, self.coords25519.formulas["ladd-1987-m"], self.coords25519.formulas["scale"]) @@ -56,7 +65,8 @@ class ScalarMultiplierTests(TestCase): def test_simple_ladder(self): mult = SimpleLadderMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], - self.coords.formulas["dbl-1998-cmo"], self.coords.formulas["z"]) + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["z"]) res = mult.multiply(10, self.base) other = mult.multiply(5, self.base) other = mult.multiply(2, other) @@ -113,6 +123,13 @@ class ScalarMultiplierTests(TestCase): self.assertEqual(res_wnaf, res_ltr) ladder = SimpleLadderMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], - self.coords.formulas["dbl-1998-cmo"], self.coords.formulas["z"]) + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["z"]) res_ladder = ladder.multiply(10, self.base) - self.assertEqual(res_ladder, res_ltr)
\ No newline at end of file + self.assertEqual(res_ladder, res_ltr) + + coron = CoronMultiplier(self.secp128r1, self.coords.formulas["add-1998-cmo"], + self.coords.formulas["dbl-1998-cmo"], + self.coords.formulas["z"]) + res_coron = coron.multiply(10, self.base) + self.assertEqual(res_coron, res_ltr) |
