diff options
| author | J08nY | 2023-08-08 16:21:07 +0200 |
|---|---|---|
| committer | J08nY | 2023-08-08 16:21:07 +0200 |
| commit | 077bf996ef042244c9259d3b32e13f07c2f3f3ae (patch) | |
| tree | 506f27332fa172eff52b920449a3c6ddd7a10021 /test/ec/test_mult.py | |
| parent | 109fec027766630166083c497ea0f0e8052965a4 (diff) | |
| download | pyecsca-077bf996ef042244c9259d3b32e13f07c2f3f3ae.tar.gz pyecsca-077bf996ef042244c9259d3b32e13f07c2f3f3ae.tar.zst pyecsca-077bf996ef042244c9259d3b32e13f07c2f3f3ae.zip | |
Diffstat (limited to 'test/ec/test_mult.py')
| -rw-r--r-- | test/ec/test_mult.py | 567 |
1 files changed, 282 insertions, 285 deletions
diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index 5200520..91ef6dd 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -1,5 +1,6 @@ from unittest import TestCase +import pytest from parameterized import parameterized from pyecsca.ec.params import get_params @@ -13,320 +14,316 @@ from pyecsca.ec.mult import ( DifferentialLadderMultiplier, CoronMultiplier, ) -from pyecsca.ec.point import InfinityPoint +from pyecsca.ec.point import InfinityPoint, Point from .utils import cartesian -class ScalarMultiplierTests(TestCase): - def setUp(self): - self.secp128r1 = get_params("secg", "secp128r1", "projective") - self.base = self.secp128r1.generator - self.coords = self.secp128r1.curve.coordinate_model +def get_formulas(coords, *names): + return [coords.formulas[name] for name in names if name is not None] - self.curve25519 = get_params("other", "Curve25519", "xz") - self.base25519 = self.curve25519.generator - self.coords25519 = self.curve25519.curve.coordinate_model - def get_formulas(self, coords, *names): - return [coords.formulas[name] for name in names if name is not None] +def assert_pt_equality(one: Point, other: Point, scale): + if scale: + assert one == other + else: + assert one.equals(other) - def assertPointEquality(self, one, other, scale): - if scale: - self.assertEqual(one, other) - else: - assert one.equals(other) - def do_basic_test( - self, mult_class, params, base, add, dbl, scale, neg=None, **kwargs - ): - mult = mult_class( - *self.get_formulas(params.curve.coordinate_model, add, dbl, neg, scale), - **kwargs - ) - mult.init(params, base) - res = mult.multiply(314) - other = mult.multiply(157) - mult.init(params, other) - other = mult.multiply(2) - self.assertPointEquality(res, other, scale) - mult.init(params, base) - self.assertEqual(InfinityPoint(params.curve.coordinate_model), mult.multiply(0)) - return res +def do_basic_test( + mult_class, params, base, add, dbl, scale, neg=None, **kwargs +): + mult = mult_class( + *get_formulas(params.curve.coordinate_model, add, dbl, neg, scale), + **kwargs + ) + mult.init(params, base) + res = mult.multiply(314) + other = mult.multiply(157) + mult.init(params, other) + other = mult.multiply(2) + assert_pt_equality(res, other, scale) + mult.init(params, base) + assert InfinityPoint(params.curve.coordinate_model) == mult.multiply(0) + return res + + +@pytest.mark.parametrize("name,add,dbl,scale", + [ + ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), + ("complete", "add-2016-rcb", "dbl-2016-rcb", None), + ("none", "add-1998-cmo", "dbl-1998-cmo", None), + ]) +def test_rtl(secp128r1, name, add, dbl, scale): + do_basic_test(RTLMultiplier, secp128r1, secp128r1.generator, add, dbl, scale) - @parameterized.expand( - [ - ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), - ("complete", "add-2016-rcb", "dbl-2016-rcb", None), - ("none", "add-1998-cmo", "dbl-1998-cmo", None), - ] + +@pytest.mark.parametrize("name,add,dbl,scale", + [ + ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), + ("complete", "add-2016-rcb", "dbl-2016-rcb", None), + ("none", "add-1998-cmo", "dbl-1998-cmo", None), + ]) +def test_ltr(secp128r1, name, add, dbl, scale): + a = do_basic_test( + LTRMultiplier, secp128r1, secp128r1.generator, add, dbl, scale + ) + b = do_basic_test( + LTRMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, always=True + ) + c = do_basic_test( + LTRMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, complete=False ) - def test_rtl(self, name, add, dbl, scale): - self.do_basic_test(RTLMultiplier, self.secp128r1, self.base, add, dbl, scale) + d = do_basic_test( + LTRMultiplier, + secp128r1, + secp128r1.generator, + add, + dbl, + scale, + always=True, + complete=False, + ) + assert_pt_equality(a, b, scale) + assert_pt_equality(b, c, scale) + assert_pt_equality(c, d, scale) + + +@pytest.mark.parametrize("name,add,dbl,scale", + [ + ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), + ("complete", "add-2016-rcb", "dbl-2016-rcb", None), + ("none", "add-1998-cmo", "dbl-1998-cmo", None), + ] + ) +def test_coron(secp128r1, name, add, dbl, scale): + do_basic_test(CoronMultiplier, secp128r1, secp128r1.generator, add, dbl, scale) - @parameterized.expand( - [ - ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), - ("complete", "add-2016-rcb", "dbl-2016-rcb", None), - ("none", "add-1998-cmo", "dbl-1998-cmo", None), - ] + +def test_ladder(curve25519): + a = do_basic_test( + LadderMultiplier, + curve25519, + curve25519.generator, + "ladd-1987-m", + "dbl-1987-m", + "scale", ) - def test_ltr(self, name, add, dbl, scale): - a = self.do_basic_test( - LTRMultiplier, self.secp128r1, self.base, add, dbl, scale - ) - b = self.do_basic_test( - LTRMultiplier, self.secp128r1, self.base, add, dbl, scale, always=True - ) - c = self.do_basic_test( - LTRMultiplier, self.secp128r1, self.base, add, dbl, scale, complete=False - ) - d = self.do_basic_test( - LTRMultiplier, - self.secp128r1, - self.base, - add, - dbl, - scale, - always=True, - complete=False, - ) - self.assertPointEquality(a, b, scale) - self.assertPointEquality(b, c, scale) - self.assertPointEquality(c, d, scale) + b = do_basic_test( + LadderMultiplier, + curve25519, + curve25519.generator, + "ladd-1987-m", + "dbl-1987-m", + "scale", + complete=False, + ) + assert_pt_equality(a, b, True) + - @parameterized.expand( - [ - ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), - ("complete", "add-2016-rcb", "dbl-2016-rcb", None), - ("none", "add-1998-cmo", "dbl-1998-cmo", None), - ] +@pytest.mark.parametrize("name,add,dbl,scale", + [ + ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), + ("complete", "add-2016-rcb", "dbl-2016-rcb", None), + ("none", "add-1998-cmo", "dbl-1998-cmo", None), + ]) +def test_simple_ladder(secp128r1, name, add, dbl, scale): + do_basic_test( + SimpleLadderMultiplier, secp128r1, secp128r1.generator, add, dbl, scale ) - def test_coron(self, name, add, dbl, scale): - self.do_basic_test(CoronMultiplier, self.secp128r1, self.base, add, dbl, scale) - def test_ladder(self): - a = self.do_basic_test( - LadderMultiplier, - self.curve25519, - self.base25519, - "ladd-1987-m", - "dbl-1987-m", - "scale", - ) - b = self.do_basic_test( - LadderMultiplier, - self.curve25519, - self.base25519, - "ladd-1987-m", - "dbl-1987-m", - "scale", - complete=False, - ) - self.assertPointEquality(a, b, True) - @parameterized.expand( - [ - ("scaled", "add-1998-cmo", "dbl-1998-cmo", "z"), - ("complete", "add-2016-rcb", "dbl-2016-rcb", None), - ("none", "add-1998-cmo", "dbl-1998-cmo", None), - ] +@pytest.mark.parametrize("name,num,complete", + [ + ("15", 15, True), + ("15", 15, False), + ("2355498743", 2355498743, True), + ("2355498743", 2355498743, False), + ( + "325385790209017329644351321912443757746", + 325385790209017329644351321912443757746, + True, + ), + ( + "325385790209017329644351321912443757746", + 325385790209017329644351321912443757746, + False, + ), + ]) +def test_ladder_differential(curve25519, name, num, complete): + ladder = LadderMultiplier( + curve25519.curve.coordinate_model.formulas["ladd-1987-m"], + curve25519.curve.coordinate_model.formulas["dbl-1987-m"], + curve25519.curve.coordinate_model.formulas["scale"], + complete=complete, ) - def test_simple_ladder(self, name, add, dbl, scale): - self.do_basic_test( - SimpleLadderMultiplier, self.secp128r1, self.base, add, dbl, scale - ) + differential = DifferentialLadderMultiplier( + curve25519.curve.coordinate_model.formulas["dadd-1987-m"], + curve25519.curve.coordinate_model.formulas["dbl-1987-m"], + curve25519.curve.coordinate_model.formulas["scale"], + complete=complete, + ) + ladder.init(curve25519, curve25519.generator) + res_ladder = ladder.multiply(num) + differential.init(curve25519, curve25519.generator) + res_differential = differential.multiply(num) + assert res_ladder == res_differential + assert InfinityPoint(curve25519.curve.coordinate_model) == differential.multiply(0) + - @parameterized.expand( - [ - ("15", 15, True), - ("15", 15, False), - ("2355498743", 2355498743, True), - ("2355498743", 2355498743, False), - ( - "325385790209017329644351321912443757746", - 325385790209017329644351321912443757746, - True, - ), - ( - "325385790209017329644351321912443757746", - 325385790209017329644351321912443757746, - False, - ), - ] +@pytest.mark.parametrize("name,add,dbl,neg,scale", + [ + ("scaled", "add-1998-cmo", "dbl-1998-cmo", "neg", "z"), + ("complete", "add-2016-rcb", "dbl-2016-rcb", "neg", None), + ("none", "add-1998-cmo", "dbl-1998-cmo", "neg", None), + ]) +def test_binary_naf(secp128r1, name, add, dbl, neg, scale): + do_basic_test( + BinaryNAFMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, neg ) - def test_ladder_differential(self, name, num, complete): - ladder = LadderMultiplier( - self.coords25519.formulas["ladd-1987-m"], - self.coords25519.formulas["dbl-1987-m"], - self.coords25519.formulas["scale"], - complete=complete, - ) - differential = DifferentialLadderMultiplier( - self.coords25519.formulas["dadd-1987-m"], - self.coords25519.formulas["dbl-1987-m"], - self.coords25519.formulas["scale"], - complete=complete, - ) - ladder.init(self.curve25519, self.base25519) - res_ladder = ladder.multiply(num) - differential.init(self.curve25519, self.base25519) - res_differential = differential.multiply(num) - self.assertEqual(res_ladder, res_differential) - self.assertEqual(InfinityPoint(self.coords25519), differential.multiply(0)) - @parameterized.expand( - [ - ("scaled", "add-1998-cmo", "dbl-1998-cmo", "neg", "z"), - ("complete", "add-2016-rcb", "dbl-2016-rcb", "neg", None), - ("none", "add-1998-cmo", "dbl-1998-cmo", "neg", None), - ] + +@pytest.mark.parametrize("name,add,dbl,neg,width,scale", + [ + ("scaled3", "add-1998-cmo", "dbl-1998-cmo", "neg", 3, "z"), + ("none3", "add-1998-cmo", "dbl-1998-cmo", "neg", 3, None), + ("complete3", "add-2016-rcb", "dbl-2016-rcb", "neg", 3, None), + ("scaled5", "add-1998-cmo", "dbl-1998-cmo", "neg", 5, "z"), + ("none5", "add-1998-cmo", "dbl-1998-cmo", "neg", 5, None), + ("complete5", "add-2016-rcb", "dbl-2016-rcb", "neg", 5, None), + ]) +def test_window_naf(secp128r1, name, add, dbl, neg, width, scale): + formulas = get_formulas(secp128r1.curve.coordinate_model, add, dbl, neg, scale) + mult = WindowNAFMultiplier(*formulas[:3], width, *formulas[3:]) + mult.init(secp128r1, secp128r1.generator) + res = mult.multiply(157 * 789) + other = mult.multiply(157) + mult.init(secp128r1, other) + other = mult.multiply(789) + assert_pt_equality(res, other, scale) + mult.init(secp128r1, secp128r1.generator) + assert InfinityPoint(secp128r1.curve.coordinate_model) == mult.multiply(0) + + mult = WindowNAFMultiplier( + *formulas[:3], width, *formulas[3:], precompute_negation=True ) - def test_binary_naf(self, name, add, dbl, neg, scale): - self.do_basic_test( - BinaryNAFMultiplier, self.secp128r1, self.base, add, dbl, scale, neg - ) + mult.init(secp128r1, secp128r1.generator) + res_precompute = mult.multiply(157 * 789) + assert_pt_equality(res_precompute, res, scale) + - @parameterized.expand( - [ - ("scaled3", "add-1998-cmo", "dbl-1998-cmo", "neg", 3, "z"), - ("none3", "add-1998-cmo", "dbl-1998-cmo", "neg", 3, None), - ("complete3", "add-2016-rcb", "dbl-2016-rcb", "neg", 3, None), - ("scaled5", "add-1998-cmo", "dbl-1998-cmo", "neg", 5, "z"), - ("none5", "add-1998-cmo", "dbl-1998-cmo", "neg", 5, None), - ("complete5", "add-2016-rcb", "dbl-2016-rcb", "neg", 5, None), - ] +@pytest.mark.parametrize("name,num,add,dbl", + cartesian( + [ + ("10", 10), + ("2355498743", 2355498743), + ( + "325385790209017329644351321912443757746", + 325385790209017329644351321912443757746, + ), + ], + [("add-1998-cmo", "dbl-1998-cmo"), ("add-2016-rcb", "dbl-2016-rcb")], + ) + ) +def test_basic_multipliers(secp128r1, name, num, add, dbl): + ltr = LTRMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["z"], + ) + with pytest.raises(ValueError): + ltr.multiply(1) + ltr.init(secp128r1, secp128r1.generator) + res_ltr = ltr.multiply(num) + rtl = RTLMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas["dbl-1998-cmo"], + secp128r1.curve.coordinate_model.formulas["z"], ) - def test_window_naf(self, name, add, dbl, neg, width, scale): - formulas = self.get_formulas(self.coords, add, dbl, neg, scale) - mult = WindowNAFMultiplier(*formulas[:3], width, *formulas[3:]) - mult.init(self.secp128r1, self.base) - res = mult.multiply(157 * 789) - other = mult.multiply(157) - mult.init(self.secp128r1, other) - other = mult.multiply(789) - self.assertPointEquality(res, other, scale) - mult.init(self.secp128r1, self.base) - self.assertEqual(InfinityPoint(self.coords), mult.multiply(0)) + with pytest.raises(ValueError): + rtl.multiply(1) + rtl.init(secp128r1, secp128r1.generator) + res_rtl = rtl.multiply(num) + assert res_ltr == res_rtl - mult = WindowNAFMultiplier( - *formulas[:3], width, *formulas[3:], precompute_negation=True - ) - mult.init(self.secp128r1, self.base) - res_precompute = mult.multiply(157 * 789) - self.assertPointEquality(res_precompute, res, scale) + ltr_always = LTRMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["z"], + always=True, + ) + rtl_always = RTLMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["z"], + always=True, + ) + ltr_always.init(secp128r1, secp128r1.generator) + rtl_always.init(secp128r1, secp128r1.generator) + res_ltr_always = ltr_always.multiply(num) + res_rtl_always = rtl_always.multiply(num) + assert res_ltr == res_ltr_always + assert res_rtl == res_rtl_always - @parameterized.expand( - cartesian( - [ - ("10", 10), - ("2355498743", 2355498743), - ( - "325385790209017329644351321912443757746", - 325385790209017329644351321912443757746, - ), - ], - [("add-1998-cmo", "dbl-1998-cmo"), ("add-2016-rcb", "dbl-2016-rcb")], - ) + bnaf = BinaryNAFMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["neg"], + secp128r1.curve.coordinate_model.formulas["z"], ) - def test_basic_multipliers(self, name, num, add, dbl): - ltr = LTRMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - ltr.multiply(1) - ltr.init(self.secp128r1, self.base) - res_ltr = ltr.multiply(num) - rtl = RTLMultiplier( - self.coords.formulas[add], - self.coords.formulas["dbl-1998-cmo"], - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - rtl.multiply(1) - rtl.init(self.secp128r1, self.base) - res_rtl = rtl.multiply(num) - self.assertEqual(res_ltr, res_rtl) + with pytest.raises(ValueError): + bnaf.multiply(1) + bnaf.init(secp128r1, secp128r1.generator) + res_bnaf = bnaf.multiply(num) + assert res_bnaf == res_ltr - ltr_always = LTRMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["z"], - always=True, - ) - rtl_always = RTLMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["z"], - always=True, - ) - ltr_always.init(self.secp128r1, self.base) - rtl_always.init(self.secp128r1, self.base) - res_ltr_always = ltr_always.multiply(num) - res_rtl_always = rtl_always.multiply(num) - self.assertEqual(res_ltr, res_ltr_always) - self.assertEqual(res_rtl, res_rtl_always) + wnaf = WindowNAFMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["neg"], + 3, + secp128r1.curve.coordinate_model.formulas["z"], + ) + with pytest.raises(ValueError): + wnaf.multiply(1) + wnaf.init(secp128r1, secp128r1.generator) + res_wnaf = wnaf.multiply(num) + assert res_wnaf == res_ltr - bnaf = BinaryNAFMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["neg"], - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - bnaf.multiply(1) - bnaf.init(self.secp128r1, self.base) - res_bnaf = bnaf.multiply(num) - self.assertEqual(res_bnaf, res_ltr) + ladder = SimpleLadderMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["z"], + ) + with pytest.raises(ValueError): + ladder.multiply(1) + ladder.init(secp128r1, secp128r1.generator) + res_ladder = ladder.multiply(num) + assert res_ladder == res_ltr - wnaf = WindowNAFMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["neg"], - 3, - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - wnaf.multiply(1) - wnaf.init(self.secp128r1, self.base) - res_wnaf = wnaf.multiply(num) - self.assertEqual(res_wnaf, res_ltr) + coron = CoronMultiplier( + secp128r1.curve.coordinate_model.formulas[add], + secp128r1.curve.coordinate_model.formulas[dbl], + secp128r1.curve.coordinate_model.formulas["z"], + ) + with pytest.raises(ValueError): + coron.multiply(1) + coron.init(secp128r1, secp128r1.generator) + res_coron = coron.multiply(num) + assert res_coron == res_ltr - ladder = SimpleLadderMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - ladder.multiply(1) - ladder.init(self.secp128r1, self.base) - res_ladder = ladder.multiply(num) - self.assertEqual(res_ladder, res_ltr) - coron = CoronMultiplier( - self.coords.formulas[add], - self.coords.formulas[dbl], - self.coords.formulas["z"], - ) - with self.assertRaises(ValueError): - coron.multiply(1) - coron.init(self.secp128r1, self.base) - res_coron = coron.multiply(num) - self.assertEqual(res_coron, res_ltr) +def test_init_fail(curve25519, secp128r1): + mult = DifferentialLadderMultiplier( + curve25519.curve.coordinate_model.formulas["dadd-1987-m"], + curve25519.curve.coordinate_model.formulas["dbl-1987-m"], + curve25519.curve.coordinate_model.formulas["scale"], + ) + with pytest.raises(ValueError): + mult.init(secp128r1, secp128r1.generator) - def test_init_fail(self): - mult = DifferentialLadderMultiplier( - self.coords25519.formulas["dadd-1987-m"], - self.coords25519.formulas["dbl-1987-m"], - self.coords25519.formulas["scale"], + with pytest.raises(ValueError): + LadderMultiplier( + curve25519.curve.coordinate_model.formulas["ladd-1987-m"], + scl=curve25519.curve.coordinate_model.formulas["scale"], + complete=False, ) - with self.assertRaises(ValueError): - mult.init(self.secp128r1, self.base) - - with self.assertRaises(ValueError): - LadderMultiplier( - self.coords25519.formulas["ladd-1987-m"], - scl=self.coords25519.formulas["scale"], - complete=False, - ) |
