diff options
| author | J08nY | 2025-03-19 15:07:06 +0100 |
|---|---|---|
| committer | J08nY | 2025-03-19 15:07:06 +0100 |
| commit | b3d4e400a81950a87aa866726f9d2d5d97a1f92e (patch) | |
| tree | 8bb0bdac65affa6b6b757f48a47f02f9cfd72ffe | |
| parent | f50335f62ff4ebd4ea855597357f1d7a6df8eef8 (diff) | |
| download | pyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.tar.gz pyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.tar.zst pyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.zip | |
| -rw-r--r-- | pyecsca/ec/mult/comb.py | 19 | ||||
| -rw-r--r-- | pyecsca/sca/re/tree.py | 8 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 6 |
3 files changed, 29 insertions, 4 deletions
diff --git a/pyecsca/ec/mult/comb.py b/pyecsca/ec/mult/comb.py index 3e064d2..2488edf 100644 --- a/pyecsca/ec/mult/comb.py +++ b/pyecsca/ec/mult/comb.py @@ -1,5 +1,6 @@ """Provides Comb-like scalar multipliers, such as BGMW or Lim-Lee.""" +import random from copy import copy from math import ceil from typing import MutableMapping, Optional @@ -136,6 +137,7 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) Algorithm 3.44 from [GECC]_ :param width: Window width (number of comb teeth). + :param always: Whether the double and add always method is used. :param accumulation_order: The order of accumulation of points. """ @@ -143,6 +145,8 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) optionals = {ScalingFormula} width: int """Window width.""" + always: bool + """Whether to always accumulate.""" _points: MutableMapping[int, Point] def __init__( @@ -151,6 +155,7 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) dbl: DoublingFormula, width: int, scl: Optional[ScalingFormula] = None, + always: bool = False, accumulation_order: AccumulationOrder = AccumulationOrder.PeqPR, short_circuit: bool = True, ): @@ -162,10 +167,11 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) scl=scl, ) self.width = width + self.always = always def __hash__(self): return hash( - (CombMultiplier, super().__hash__(), self.width, self.accumulation_order) + (CombMultiplier, super().__hash__(), self.width, self.accumulation_order, self.always) ) def __eq__(self, other): @@ -176,10 +182,11 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) and self.short_circuit == other.short_circuit and self.width == other.width and self.accumulation_order == other.accumulation_order + and self.always == other.always ) def __repr__(self): - return f"{self.__class__.__name__}({', '.join(map(str, self.formulas.values()))}, short_circuit={self.short_circuit}, width={self.width}, accumulation_order={self.accumulation_order.name})" + return f"{self.__class__.__name__}({', '.join(map(str, self.formulas.values()))}, short_circuit={self.short_circuit}, width={self.width}, accumulation_order={self.accumulation_order.name}, always={self.always})" def init(self, params: DomainParameters, point: Point, bits: Optional[int] = None): with PrecomputationAction(params, point) as action: @@ -223,7 +230,13 @@ class CombMultiplier(AccumulatorMultiplier, PrecompMultiplier, ScalarMultiplier) word |= bit << j if word: q = self._accumulate(q, self._points[word]) - # TODO always + elif self.always: + j = random.randrange(0, 2 ** self.width) + # dummy + if j == 0: + self._accumulate(q, self._point) + else: + self._accumulate(q, self._points[j]) if "scl" in self.formulas: q = self._scl(q) diff --git a/pyecsca/sca/re/tree.py b/pyecsca/sca/re/tree.py index 6307c0f..15664ac 100644 --- a/pyecsca/sca/re/tree.py +++ b/pyecsca/sca/re/tree.py @@ -361,12 +361,20 @@ class SplitCriterion: """ def __call__(self, split: pd.Series) -> float: + """ + Compute the score of a split. + + :param split: The split to score. + :return: The score, can be any (consistent) scale. + """ raise NotImplementedError def is_better(self, score: float, current_best: float) -> bool: + """Whether the score is better than the current best.""" raise NotImplementedError def is_optimal(self, score: float, n_cfgs: int, n_codomain: int) -> bool: + """Whether the score is optimal and no further splits need to be examined.""" raise NotImplementedError diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index e915585..07ddcdf 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -461,7 +461,11 @@ def test_basic_multipliers(secp128r1, num, add, dbl): ) for combination in product(*bgmw_options.values()) ] - comb_options = {"width": (2, 3, 4, 5), "accumulation_order": tuple(AccumulationOrder)} + comb_options = { + "width": (2, 3, 4, 5), + "accumulation_order": tuple(AccumulationOrder), + "always": (True, False), + } combs = [ CombMultiplier( add, dbl, scl=scale, **dict(zip(comb_options.keys(), combination)) |
