aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/ec
diff options
context:
space:
mode:
authorJ08nY2025-10-26 16:44:32 +0100
committerJ08nY2025-10-26 16:44:32 +0100
commit674c45bfe5766fb621bdbfa578d403f3f15dd5da (patch)
treeaa7b2900ca9f15f14497df68505857705f083d20 /pyecsca/ec
parent85349f41a19b18380c399e1078ceacae518b50e3 (diff)
downloadpyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.tar.gz
pyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.tar.zst
pyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.zip
Diffstat (limited to 'pyecsca/ec')
-rw-r--r--pyecsca/ec/countermeasures.py91
-rw-r--r--pyecsca/ec/mult/fake.py13
2 files changed, 97 insertions, 7 deletions
diff --git a/pyecsca/ec/countermeasures.py b/pyecsca/ec/countermeasures.py
index da45150..e155663 100644
--- a/pyecsca/ec/countermeasures.py
+++ b/pyecsca/ec/countermeasures.py
@@ -118,7 +118,7 @@ class GroupScalarRandomization(ScalarMultiplierCountermeasure):
:class: frame
&r \xleftarrow{\$} \{0, 1, \ldots, 2^{\text{rand_bits}}\} \\
- &\textbf{return}\ [k + r n]G
+ &\textbf{return}\ [k + r n]P
"""
@@ -167,7 +167,7 @@ class AdditiveSplitting(ScalarMultiplierCountermeasure):
:class: frame
&r \xleftarrow{\$} \{0, 1, \ldots, n\} \\
- &\textbf{return}\ [k - r]G + [r]G
+ &\textbf{return}\ [k - r]P + [r]P
"""
@@ -221,7 +221,7 @@ class MultiplicativeSplitting(ScalarMultiplierCountermeasure):
:class: frame
&r \xleftarrow{\$} \{0, 1, \ldots, 2^{\text{rand_bits}}\} \\
- &S = [r]G \\
+ &S = [r]P \\
&\textbf{return}\ [k r^{-1} \mod n]S
"""
@@ -273,10 +273,10 @@ class EuclideanSplitting(ScalarMultiplierCountermeasure):
:class: frame
&r \xleftarrow{\$} \{0, 1, \ldots, 2^{\log_2{(n)}/2}\} \\
- &S = [r]G \\
+ &S = [r]P \\
&k_1 = k \mod r \\
&k_2 = \lfloor \frac{k}{r} \rfloor \\
- &\textbf{return}\ [k_1]G + [k_2]S
+ &\textbf{return}\ [k_1]P + [k_2]S
"""
@@ -354,7 +354,7 @@ class BrumleyTuveri(ScalarMultiplierCountermeasure):
k + 2n \quad \text{if } \lceil \log_2(k+n) \rceil = \lceil \log_2 n \rceil\\
k + n \quad \text{otherwise}.
\end{cases}\\
- &\textbf{return}\ [\hat{k}]G
+ &\textbf{return}\ [\hat{k}]P
"""
@@ -390,7 +390,19 @@ class BrumleyTuveri(ScalarMultiplierCountermeasure):
@public
class PointBlinding(ScalarMultiplierCountermeasure):
- """Point blinding countermeasure."""
+ r"""
+ Point blinding countermeasure.
+
+ .. math::
+ :class: frame
+
+ &R \xleftarrow{\$} E_{\mathbb{F}_p} \\
+ &S = [k]R \\
+ &T = P + S \\
+ &Q = [k]T \\
+ &\textbf{return}\ Q - S
+
+ """
nmults = 2
requires = {AdditionFormula, NegationFormula}
@@ -432,3 +444,68 @@ class PointBlinding(ScalarMultiplierCountermeasure):
Q = self.mults[1].multiply(int(scalar))
return action.exit(self._add(Q, self._neg(S)))
+
+
+@public
+class MultPointBlinding(ScalarMultiplierCountermeasure):
+ r"""
+ Point blinding countermeasure.
+
+ .. math::
+ :class: frame
+
+ &r \xleftarrow{\$} \{0, 1, \ldots, 2^{\text{rand_bits}}\} \\
+ $R = [r]G$ \\
+ &S = [k]R \\
+ &T = P + S \\
+ &Q = [k]T \\
+ &\textbf{return}\ Q - S
+
+ """
+
+ nmults = 3
+ requires = {AdditionFormula, NegationFormula}
+ rand_bits: int
+ add: Optional[AdditionFormula]
+ neg: Optional[NegationFormula]
+
+ def __init__(
+ self,
+ mult1: "ScalarMultiplier | ScalarMultiplierCountermeasure",
+ mult2: "ScalarMultiplier | ScalarMultiplierCountermeasure",
+ mult3: "ScalarMultiplier | ScalarMultiplierCountermeasure",
+ rng: Callable[[int], Mod] = Mod.random,
+ rand_bits: int = 32,
+ add: Optional[AdditionFormula] = None,
+ neg: Optional[NegationFormula] = None,
+ ):
+ """
+
+ :param mult1: The multiplier to use.
+ :param mult2: The multiplier to use.
+ :param mult3: The multiplier to use.
+ :param rng: The random number generator to use.
+ :param add: Addition formula to use, if None, the formula from the multiplier is used.
+ :param neg: Negation formula to use, if None, the formula from the multiplier is used.
+ """
+ super().__init__(mult1, mult2, mult3, rng=rng)
+ self.rand_bits = rand_bits
+ self.add = add
+ self.neg = neg
+
+ def multiply(self, scalar: int) -> Point:
+ if self.params is None or self.point is None or self.bits is None:
+ raise ValueError("Not initialized.")
+ with ScalarMultiplicationAction(self.point, self.params, scalar) as action:
+ r = self.rng(1 << self.rand_bits)
+ self.mults[0].init(self.params, self.params.generator, self.rand_bits)
+ R = self.mults[0].multiply(int(r))
+
+ self.mults[1].init(self.params, R, self.bits)
+ S = self.mults[1].multiply(int(scalar))
+
+ T = self._add(self.point, R)
+ self.mults[2].init(self.params, T, self.bits)
+ Q = self.mults[2].multiply(int(scalar))
+
+ return action.exit(self._add(Q, self._neg(S)))
diff --git a/pyecsca/ec/mult/fake.py b/pyecsca/ec/mult/fake.py
index f18d695..95bebb5 100644
--- a/pyecsca/ec/mult/fake.py
+++ b/pyecsca/ec/mult/fake.py
@@ -17,6 +17,7 @@ from pyecsca.ec.formula.fake import (
FakeLadderFormula,
FakeNegationFormula,
FakeScalingFormula,
+ FakePoint,
)
from pyecsca.ec.mult import ScalarMultiplier
from pyecsca.ec.params import DomainParameters
@@ -51,6 +52,18 @@ def fake_mult(
return mult
+def fake_params(params: DomainParameters) -> DomainParameters:
+ """
+ Turn the domain parameters into fake domain parameters.
+
+ :param params: The domain parameters to turn into fake domain parameters.
+ :return: The fake domain parameters.
+ """
+ copy = deepcopy(params)
+ copy.generator = FakePoint(params.curve.coordinate_model)
+ return copy
+
+
def turn_fake(mult: ScalarMultiplier) -> ScalarMultiplier:
"""
Turn a multiplier into a fake multiplier.