diff options
| author | J08nY | 2025-10-26 16:44:32 +0100 |
|---|---|---|
| committer | J08nY | 2025-10-26 16:44:32 +0100 |
| commit | 674c45bfe5766fb621bdbfa578d403f3f15dd5da (patch) | |
| tree | aa7b2900ca9f15f14497df68505857705f083d20 /pyecsca/ec | |
| parent | 85349f41a19b18380c399e1078ceacae518b50e3 (diff) | |
| download | pyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.tar.gz pyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.tar.zst pyecsca-674c45bfe5766fb621bdbfa578d403f3f15dd5da.zip | |
Diffstat (limited to 'pyecsca/ec')
| -rw-r--r-- | pyecsca/ec/countermeasures.py | 91 | ||||
| -rw-r--r-- | pyecsca/ec/mult/fake.py | 13 |
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. |
