diff options
| author | J08nY | 2023-08-27 16:38:00 +0200 |
|---|---|---|
| committer | J08nY | 2023-08-27 16:38:00 +0200 |
| commit | 54e9958c811a57b7adbc052cc86fedaa582c102f (patch) | |
| tree | ec3f5002e12bd1cb4a3e1f3f7bdf27f7d151342b /pyecsca/ec/mult | |
| parent | 19bc2ed369cbcd41c08132edb74d7a1afd843962 (diff) | |
| download | pyecsca-54e9958c811a57b7adbc052cc86fedaa582c102f.tar.gz pyecsca-54e9958c811a57b7adbc052cc86fedaa582c102f.tar.zst pyecsca-54e9958c811a57b7adbc052cc86fedaa582c102f.zip | |
Diffstat (limited to 'pyecsca/ec/mult')
| -rw-r--r-- | pyecsca/ec/mult/base.py | 21 | ||||
| -rw-r--r-- | pyecsca/ec/mult/binary.py | 16 | ||||
| -rw-r--r-- | pyecsca/ec/mult/naf.py | 31 | ||||
| -rw-r--r-- | pyecsca/ec/mult/window.py | 84 |
4 files changed, 103 insertions, 49 deletions
diff --git a/pyecsca/ec/mult/base.py b/pyecsca/ec/mult/base.py index 027320c..a0584d1 100644 --- a/pyecsca/ec/mult/base.py +++ b/pyecsca/ec/mult/base.py @@ -206,3 +206,24 @@ class ScalarMultiplier(ABC): :return: The resulting multiple. """ raise NotImplementedError + + +@public +class AccumulatorMultiplier(ScalarMultiplier, ABC): + """ + A scalar multiplication algorithm mix-in class for a multiplier that accumulates. + + :param accumulation_order: The order of accumulation of points. + """ + accumulation_order: AccumulationOrder + + def __init__(self, *args, accumulation_order: AccumulationOrder = AccumulationOrder.PeqPR, **kwargs): + super().__init__(*args, **kwargs) + self.accumulation_order = accumulation_order + + def _accumulate(self, p: Point, r: Point) -> Point: + if self.accumulation_order is AccumulationOrder.PeqPR: + p = self._add(p, r) + elif self.accumulation_order is AccumulationOrder.PeqRP: + p = self._add(r, p) + return p diff --git a/pyecsca/ec/mult/binary.py b/pyecsca/ec/mult/binary.py index dda3388..6145828 100644 --- a/pyecsca/ec/mult/binary.py +++ b/pyecsca/ec/mult/binary.py @@ -4,7 +4,8 @@ from typing import Optional from public import public -from .base import ScalarMultiplier, ProcessingDirection, AccumulationOrder, ScalarMultiplicationAction +from .base import ScalarMultiplier, ProcessingDirection, AccumulationOrder, ScalarMultiplicationAction, \ + AccumulatorMultiplier from ..formula import ( AdditionFormula, DoublingFormula, @@ -14,7 +15,7 @@ from ..point import Point @public -class DoubleAndAddMultiplier(ScalarMultiplier, ABC): +class DoubleAndAddMultiplier(AccumulatorMultiplier, ScalarMultiplier, ABC): """ Classic double and add scalar multiplication algorithm. @@ -27,7 +28,6 @@ class DoubleAndAddMultiplier(ScalarMultiplier, ABC): optionals = {ScalingFormula} always: bool direction: ProcessingDirection - accumulation_order: AccumulationOrder complete: bool def __init__( @@ -41,10 +41,9 @@ class DoubleAndAddMultiplier(ScalarMultiplier, ABC): complete: bool = True, short_circuit: bool = True, ): - super().__init__(short_circuit=short_circuit, add=add, dbl=dbl, scl=scl) + super().__init__(short_circuit=short_circuit, accumulation_order=accumulation_order, add=add, dbl=dbl, scl=scl) self.always = always self.direction = direction - self.accumulation_order = accumulation_order self.complete = complete def __hash__(self): @@ -58,13 +57,6 @@ class DoubleAndAddMultiplier(ScalarMultiplier, ABC): def __repr__(self): return f"{self.__class__.__name__}({tuple(self.formulas.values())}, short_circuit={self.short_circuit}, accumulation_order={self.accumulation_order}, always={self.always}, complete={self.complete})" - def _accumulate(self, p: Point, r: Point) -> Point: - if self.accumulation_order is AccumulationOrder.PeqPR: - p = self._add(p, r) - elif self.accumulation_order is AccumulationOrder.PeqRP: - p = self._add(r, p) - return p - def _ltr(self, scalar: int) -> Point: if self.complete: q = self._point diff --git a/pyecsca/ec/mult/naf.py b/pyecsca/ec/mult/naf.py index b3409db..1cec8b0 100644 --- a/pyecsca/ec/mult/naf.py +++ b/pyecsca/ec/mult/naf.py @@ -2,7 +2,8 @@ from copy import copy from typing import Optional, List, MutableMapping from public import public -from .base import ScalarMultiplier, ScalarMultiplicationAction, ProcessingDirection, AccumulationOrder, PrecomputationAction +from .base import ScalarMultiplier, ScalarMultiplicationAction, ProcessingDirection, AccumulationOrder, \ + PrecomputationAction, AccumulatorMultiplier from ..formula import ( AdditionFormula, DoublingFormula, @@ -15,13 +16,12 @@ from ..scalar import naf, wnaf @public -class BinaryNAFMultiplier(ScalarMultiplier): +class BinaryNAFMultiplier(AccumulatorMultiplier, ScalarMultiplier): """Binary NAF (Non Adjacent Form) multiplier.""" requires = {AdditionFormula, DoublingFormula, NegationFormula} optionals = {ScalingFormula} direction: ProcessingDirection - accumulation_order: AccumulationOrder _point_neg: Point def __init__( @@ -35,10 +35,9 @@ class BinaryNAFMultiplier(ScalarMultiplier): short_circuit: bool = True, ): super().__init__( - short_circuit=short_circuit, add=add, dbl=dbl, neg=neg, scl=scl + short_circuit=short_circuit, accumulation_order=accumulation_order, add=add, dbl=dbl, neg=neg, scl=scl ) self.direction = direction - self.accumulation_order = accumulation_order def __hash__(self): return id(self) @@ -53,13 +52,6 @@ class BinaryNAFMultiplier(ScalarMultiplier): super().init(params, point) self._point_neg = self._neg(point) - def _accumulate(self, p: Point, r: Point) -> Point: - if self.accumulation_order is AccumulationOrder.PeqPR: - p = self._add(p, r) - elif self.accumulation_order is AccumulationOrder.PeqRP: - p = self._add(r, p) - return p - def _ltr(self, scalar_naf: List[int]) -> Point: q = copy(self._params.curve.neutral) for val in scalar_naf: @@ -100,14 +92,13 @@ class BinaryNAFMultiplier(ScalarMultiplier): @public -class WindowNAFMultiplier(ScalarMultiplier): +class WindowNAFMultiplier(AccumulatorMultiplier, ScalarMultiplier): """Window NAF (Non Adjacent Form) multiplier, left-to-right.""" requires = {AdditionFormula, DoublingFormula, NegationFormula} optionals = {ScalingFormula} _points: MutableMapping[int, Point] _points_neg: MutableMapping[int, Point] - accumulation_order: AccumulationOrder precompute_negation: bool = False width: int @@ -123,10 +114,9 @@ class WindowNAFMultiplier(ScalarMultiplier): short_circuit: bool = True, ): super().__init__( - short_circuit=short_circuit, add=add, dbl=dbl, neg=neg, scl=scl + short_circuit=short_circuit, accumulation_order=accumulation_order, add=add, dbl=dbl, neg=neg, scl=scl ) self.width = width - self.accumulation_order = accumulation_order self.precompute_negation = precompute_negation def __hash__(self): @@ -135,7 +125,7 @@ class WindowNAFMultiplier(ScalarMultiplier): def __eq__(self, other): if not isinstance(other, WindowNAFMultiplier): return False - return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.width == other.width and self.precompute_negation == other.precompute_negation + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.width == other.width and self.precompute_negation == other.precompute_negation and self.accumulation_order == other.accumulation_order def init(self, params: DomainParameters, point: Point): with PrecomputationAction(params, point): @@ -150,13 +140,6 @@ class WindowNAFMultiplier(ScalarMultiplier): self._points_neg[2 * i + 1] = self._neg(current_point) current_point = self._add(current_point, double_point) - def _accumulate(self, p: Point, r: Point) -> Point: - if self.accumulation_order is AccumulationOrder.PeqPR: - p = self._add(p, r) - elif self.accumulation_order is AccumulationOrder.PeqRP: - p = self._add(r, p) - return p - def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") diff --git a/pyecsca/ec/mult/window.py b/pyecsca/ec/mult/window.py index f2c2c70..15126a7 100644 --- a/pyecsca/ec/mult/window.py +++ b/pyecsca/ec/mult/window.py @@ -3,25 +3,90 @@ from typing import Optional, MutableMapping from public import public from ..params import DomainParameters -from .base import ScalarMultiplier, AccumulationOrder, ScalarMultiplicationAction, PrecomputationAction +from .base import ScalarMultiplier, AccumulationOrder, ScalarMultiplicationAction, PrecomputationAction, \ + ProcessingDirection, AccumulatorMultiplier from ..formula import ( AdditionFormula, DoublingFormula, ScalingFormula, ) from ..point import Point -from ..scalar import convert_base +from ..scalar import convert_base, sliding_window_rtl, sliding_window_ltr @public -class FixedWindowLTRMultiplier(ScalarMultiplier): +class SlidingWindowMultiplier(AccumulatorMultiplier, ScalarMultiplier): + """""" + + requires = {AdditionFormula, DoublingFormula} + optionals = {ScalingFormula} + complete: bool + width: int + recoding_direction: ProcessingDirection + _points: MutableMapping[int, Point] + + def __init__( + self, + add: AdditionFormula, + dbl: DoublingFormula, + width: int, + scl: Optional[ScalingFormula] = None, + recoding_direction: ProcessingDirection = ProcessingDirection.LTR, + accumulation_order: AccumulationOrder = AccumulationOrder.PeqPR, + short_circuit: bool = True, + ): + super().__init__( + short_circuit=short_circuit, accumulation_order=accumulation_order, add=add, dbl=dbl, scl=scl + ) + self.width = width + self.recoding_direction = recoding_direction + + def __hash__(self): + return id(self) + + def __eq__(self, other): + if not isinstance(other, SlidingWindowMultiplier): + return False + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.width == other.width and self.recoding_direction == other.recoding_direction and self.accumulation_order == other.accumulation_order + + def init(self, params: DomainParameters, point: Point): + with PrecomputationAction(params, point): + super().init(params, point) + self._points = {} + current_point = point + double_point = self._dbl(point) + for i in range(0, 2 ** (self.width - 1)): + self._points[2 * i + 1] = current_point + current_point = self._add(current_point, double_point) + + def multiply(self, scalar: int) -> Point: + if not self._initialized: + raise ValueError("ScalarMultiplier not initialized.") + with ScalarMultiplicationAction(self._point, scalar) as action: + if scalar == 0: + return action.exit(copy(self._params.curve.neutral)) + if self.recoding_direction is ProcessingDirection.LTR: + scalar_sliding = sliding_window_ltr(scalar, self.width) + elif self.recoding_direction is ProcessingDirection.RTL: + scalar_sliding = sliding_window_rtl(scalar, self.width) + q = copy(self._params.curve.neutral) + for val in scalar_sliding: + q = self._dbl(q) + if val != 0: + q = self._accumulate(q, self._points[val]) + if "scl" in self.formulas: + q = self._scl(q) + return action.exit(q) + + +@public +class FixedWindowLTRMultiplier(AccumulatorMultiplier, ScalarMultiplier): """Like LTRMultiplier, but not binary, but m-ary.""" requires = {AdditionFormula, DoublingFormula} optionals = {ScalingFormula} complete: bool m: int - accumulation_order: AccumulationOrder _points: MutableMapping[int, Point] def __init__( @@ -34,7 +99,7 @@ class FixedWindowLTRMultiplier(ScalarMultiplier): short_circuit: bool = True, ): super().__init__( - short_circuit=short_circuit, add=add, dbl=dbl, scl=scl + short_circuit=short_circuit, accumulation_order=accumulation_order, add=add, dbl=dbl, scl=scl ) if m < 2: raise ValueError("Invalid base.") @@ -47,7 +112,7 @@ class FixedWindowLTRMultiplier(ScalarMultiplier): def __eq__(self, other): if not isinstance(other, FixedWindowLTRMultiplier): return False - return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.m == other.m + return self.formulas == other.formulas and self.short_circuit == other.short_circuit and self.m == other.m and self.accumulation_order == other.accumulation_order def init(self, params: DomainParameters, point: Point): with PrecomputationAction(params, point): @@ -74,13 +139,6 @@ class FixedWindowLTRMultiplier(ScalarMultiplier): q = self._accumulate(q, r) return q - def _accumulate(self, p: Point, r: Point) -> Point: - if self.accumulation_order is AccumulationOrder.PeqPR: - p = self._add(p, r) - elif self.accumulation_order is AccumulationOrder.PeqRP: - p = self._add(r, p) - return p - def multiply(self, scalar: int) -> Point: if not self._initialized: raise ValueError("ScalarMultiplier not initialized.") |
