aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2025-03-19 15:07:06 +0100
committerJ08nY2025-03-19 15:07:06 +0100
commitb3d4e400a81950a87aa866726f9d2d5d97a1f92e (patch)
tree8bb0bdac65affa6b6b757f48a47f02f9cfd72ffe
parentf50335f62ff4ebd4ea855597357f1d7a6df8eef8 (diff)
downloadpyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.tar.gz
pyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.tar.zst
pyecsca-b3d4e400a81950a87aa866726f9d2d5d97a1f92e.zip
-rw-r--r--pyecsca/ec/mult/comb.py19
-rw-r--r--pyecsca/sca/re/tree.py8
-rw-r--r--test/ec/test_mult.py6
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))