diff options
| -rw-r--r-- | docs/references.rst | 1 | ||||
| -rw-r--r-- | pyecsca/ec/countermeasures.py | 42 | ||||
| -rw-r--r-- | test/ec/test_countermeasures.py | 21 |
3 files changed, 63 insertions, 1 deletions
diff --git a/docs/references.rst b/docs/references.rst index 555431f..590bde4 100644 --- a/docs/references.rst +++ b/docs/references.rst @@ -12,6 +12,7 @@ .. [ZVP] Zero-value point attacks on elliptic curve cryptosystem, https://doi.org/10.1007/10958513_17 .. [EPA] Exceptional procedure attack on elliptic curve cryptosystems, https://doi.org/10.1007/3-540-36288-6_17 .. [FFD] A formula for disaster: a unified approach to elliptic curve special-point-based attacks, https://eprint.iacr.org/2021/1595.pdf +.. [BT11] Remote Timing Attacks Are Still Practical, https://eprint.iacr.org/2011/232.pdf .. [MT1991] Mazur, B., & Tate, J. (1991). The `p`-adic sigma function. Duke Mathematical Journal, 62 (3), 663-688. .. [CO2002] Jean-Sébastien Coron. Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems, https://link.springer.com/chapter/10.1007/3-540-48059-5_25 .. [DJB02] D.J. Bernstein: Pippenger's Exponentiation Algorithm, https://cr.yp.to/papers/pippenger.pdf diff --git a/pyecsca/ec/countermeasures.py b/pyecsca/ec/countermeasures.py index 9fd743a..217e12d 100644 --- a/pyecsca/ec/countermeasures.py +++ b/pyecsca/ec/countermeasures.py @@ -42,6 +42,9 @@ class ScalarMultiplierCountermeasure(ABC): .. note:: The countermeasure may compute multiple scalar multiplications internally. Thus, it may call the init method of the scalar multiplier multiple times. + + :param scalar: The scalar to multiply with. + :return: The result of the multiplication. """ raise NotImplementedError @@ -222,3 +225,42 @@ class EuclideanSplitting(ScalarMultiplierCountermeasure): self.params.curve.prime, S, T, **self.params.curve.parameters )[0] return action.exit(res) + + +@public +class BrumleyTuveri(ScalarMultiplierCountermeasure): + r""" + A countermeasure that fixes the bit-length of the scalar by adding some multiple + of the order to it. + + Originally proposed in [BT11]_. + + .. math:: + :class: frame + + &\hat{k}= \begin{cases} + 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 + + """ + + def init(self, params: DomainParameters, point: Point): + self.params = params + self.point = point + self.mult.init( + self.params, + self.point, + bits=params.full_order.bit_length() + 1, + ) + + def multiply(self, scalar: int) -> Point: + if self.params is None or self.point is None: + raise ValueError("Not initialized.") + with ScalarMultiplicationAction(self.point, self.params, scalar) as action: + n = self.params.full_order + scalar += n + if scalar.bit_length() <= n.bit_length(): + scalar += n + return action.exit(self.mult.multiply(scalar)) diff --git a/test/ec/test_countermeasures.py b/test/ec/test_countermeasures.py index 8a572e8..3cd5461 100644 --- a/test/ec/test_countermeasures.py +++ b/test/ec/test_countermeasures.py @@ -7,7 +7,7 @@ from pyecsca.ec.countermeasures import ( GroupScalarRandomization, AdditiveSplitting, MultiplicativeSplitting, - EuclideanSplitting, + EuclideanSplitting, BrumleyTuveri, ) from pyecsca.ec.mult import * @@ -219,3 +219,22 @@ def test_euclidean_splitting(mults, secp128r1, num): esplit.init(secp128r1, secp128r1.generator) masked = esplit.multiply(num) assert raw.equals(masked) + + +@pytest.mark.parametrize( + "num", + [ + 3253857902090173296443513219124437746, + 1234567893141592653589793238464338327, + ], +) +def test_brumley_tuveri(mults, secp128r1, num): + mult = copy(mults[0]) + mult.init(secp128r1, secp128r1.generator) + raw = mult.multiply(num) + + for mult in mults: + bt = BrumleyTuveri(mult) + bt.init(secp128r1, secp128r1.generator) + masked = bt.multiply(num) + assert raw.equals(masked) |
