diff options
| author | Andrej Bátora | 2023-12-14 22:40:05 +0100 |
|---|---|---|
| committer | GitHub | 2023-12-14 22:40:05 +0100 |
| commit | 2b7bda7b57f0f66102cf92526ceee78f11ea29d4 (patch) | |
| tree | 92df965a2bc4afb5ea3d38ce69703cc4c39ae7d4 /test | |
| parent | c69aebde34d3bdf8a1ff789b3aa172040b59f1d7 (diff) | |
| parent | cee7e6b3196739b9ceaf12da3a11d5f5486b16bb (diff) | |
| download | pyecsca-2b7bda7b57f0f66102cf92526ceee78f11ea29d4.tar.gz pyecsca-2b7bda7b57f0f66102cf92526ceee78f11ea29d4.tar.zst pyecsca-2b7bda7b57f0f66102cf92526ceee78f11ea29d4.zip | |
Merge branch 'J08nY:master' into CPA_correlations_tracking
Diffstat (limited to 'test')
| -rw-r--r-- | test/ec/test_configuration.py | 2 | ||||
| -rw-r--r-- | test/ec/test_formula.py | 426 | ||||
| -rw-r--r-- | test/ec/test_mult.py | 343 | ||||
| -rw-r--r-- | test/ec/test_scalar.py | 26 | ||||
| -rw-r--r-- | test/sca/test_rpa.py | 90 | ||||
| -rw-r--r-- | test/sca/test_structural.py | 315 |
6 files changed, 735 insertions, 467 deletions
diff --git a/test/ec/test_configuration.py b/test/ec/test_configuration.py index 54cc53a..15c9471 100644 --- a/test/ec/test_configuration.py +++ b/test/ec/test_configuration.py @@ -33,7 +33,7 @@ def test_weierstrass_projective(base_independents): coords = model.coordinates["projective"] configs = list(all_configurations(model=model, coords=coords, **base_independents)) assert len(set(map(lambda cfg: cfg.scalarmult, configs))) == len(configs) - assert len(configs) == 11360 + assert len(configs) == 12640 def test_mult_class(base_independents): diff --git a/test/ec/test_formula.py b/test/ec/test_formula.py index bb3d123..3f8d45c 100644 --- a/test/ec/test_formula.py +++ b/test/ec/test_formula.py @@ -1,13 +1,39 @@ import pickle +from operator import itemgetter +from typing import Tuple import pytest from sympy import FF, symbols - +from importlib_resources import files, as_file +import test.data.formulas +from pyecsca.ec.formula.expand import expand_formula_list +from pyecsca.ec.formula.fliparoo import generate_fliparood_formulas +from pyecsca.ec.formula.graph import rename_ivs +from pyecsca.ec.formula.metrics import ( + formula_similarity, + formula_similarity_abs, + formula_similarity_fuzz, +) +from pyecsca.ec.formula.partitions import ( + reduce_all_adds, + expand_all_muls, + expand_all_nopower2_muls, + generate_partitioned_formulas, +) +from pyecsca.ec.formula.switch_sign import generate_switched_formulas from pyecsca.ec.mod import SymbolicMod, Mod from pyecsca.misc.cfg import TemporaryConfig from pyecsca.ec.error import UnsatisfiedAssumptionError -from pyecsca.ec.params import get_params +from pyecsca.ec.params import get_params, DomainParameters from pyecsca.ec.point import Point +from pyecsca.ec.model import ShortWeierstrassModel, MontgomeryModel, TwistedEdwardsModel +from pyecsca.ec.formula.efd import ( + AdditionEFDFormula, + DoublingEFDFormula, + LadderEFDFormula, + EFDFormula, +) +from pyecsca.ec.formula import AdditionFormula, DoublingFormula, LadderFormula @pytest.fixture() @@ -62,39 +88,27 @@ def test_num_ops(add): def test_assumptions(secp128r1, mdbl): - res = mdbl( - secp128r1.curve.prime, - secp128r1.generator, - **secp128r1.curve.parameters - ) + res = mdbl(secp128r1.curve.prime, secp128r1.generator, **secp128r1.curve.parameters) assert res is not None - coords = { - name: value * 5 for name, value in secp128r1.generator.coords.items() - } + coords = {name: value * 5 for name, value in secp128r1.generator.coords.items()} other = Point(secp128r1.generator.coordinate_model, **coords) with pytest.raises(UnsatisfiedAssumptionError): - mdbl( - secp128r1.curve.prime, other, **secp128r1.curve.parameters - ) + mdbl(secp128r1.curve.prime, other, **secp128r1.curve.parameters) with TemporaryConfig() as cfg: cfg.ec.unsatisfied_formula_assumption_action = "ignore" - pt = mdbl( - secp128r1.curve.prime, other, **secp128r1.curve.parameters - ) + pt = mdbl(secp128r1.curve.prime, other, **secp128r1.curve.parameters) assert pt is not None def test_parameters(): jac_secp128r1 = get_params("secg", "secp128r1", "jacobian") - jac_dbl = jac_secp128r1.curve.coordinate_model.formulas[ - "dbl-1998-hnm" - ] + jac_dbl = jac_secp128r1.curve.coordinate_model.formulas["dbl-1998-hnm"] res = jac_dbl( jac_secp128r1.curve.prime, jac_secp128r1.generator, - **jac_secp128r1.curve.parameters + **jac_secp128r1.curve.parameters, ) assert res is not None @@ -111,9 +125,7 @@ def test_symbolic(secp128r1, dbl): coords, **{key: SymbolicMod(symbols(key), p) for key in coords.variables} ) symbolic_double = dbl(p, symbolic_point, **sympy_params)[0] - generator_double = dbl( - p, secp128r1.generator, **secp128r1.curve.parameters - )[0] + generator_double = dbl(p, secp128r1.generator, **secp128r1.curve.parameters)[0] for outer_var in coords.variables: symbolic_val = getattr(symbolic_double, outer_var).x generator_val = getattr(generator_double, outer_var).x @@ -126,3 +138,371 @@ def test_symbolic(secp128r1, dbl): def test_pickle(add, dbl): assert add == pickle.loads(pickle.dumps(add)) + + +def test_formula_similarity(secp128r1): + add_bl = secp128r1.curve.coordinate_model.formulas["add-2007-bl"] + add_rcb = secp128r1.curve.coordinate_model.formulas["add-2015-rcb"] + out = formula_similarity(add_bl, add_rcb) + assert out["output"] == 0 + assert out["ivs"] < 0.5 + out_abs = formula_similarity_abs(add_bl, add_rcb) + assert out_abs["output"] == 0 + assert out_abs["ivs"] < 0.5 + out_fuzz = formula_similarity_fuzz(add_bl, add_rcb, secp128r1.curve, samples=100) + assert out_fuzz["output"] == 0 + assert out_fuzz["ivs"] < 0.5 + out_same = formula_similarity(add_bl, add_bl) + assert out_same["output"] == 1 + assert out_same["ivs"] == 1 + + +LIBRARY_FORMULAS = [ + [ + "add-bc-r1rv76-jac", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp128r1"), + AdditionEFDFormula, + ], + [ + "add-bc-r1rv76-mod", + ShortWeierstrassModel, + "modified", + ("secg", "secp128r1"), + AdditionEFDFormula, + ], + [ + "dbl-bc-r1rv76-jac", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp128r1"), + DoublingEFDFormula, + ], + [ + "dbl-bc-r1rv76-mod", + ShortWeierstrassModel, + "modified", + ("secg", "secp128r1"), + DoublingEFDFormula, + ], + [ + "dbl-bc-r1rv76-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + DoublingEFDFormula, + ], + [ + "ladd-bc-r1rv76-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "dbl-boringssl-p224", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp224r1"), + DoublingEFDFormula, + ], + [ + "add-boringssl-p224", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp224r1"), + AdditionEFDFormula, + ], + [ + "add-libressl-v382", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp128r1"), + AdditionEFDFormula, + ], + [ + "dbl-libressl-v382", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp128r1"), + DoublingEFDFormula, + ], + [ + "dbl-secp256k1-v040", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp256k1"), + DoublingEFDFormula, + ], + [ + "add-openssl-z256", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "add-openssl-z256a", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "ladd-openssl-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "ladd-hacl-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "dbl-hacl-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + DoublingEFDFormula, + ], + [ + "dbl-sunec-v21", + ShortWeierstrassModel, + "projective-3", + ("secg", "secp256r1"), + DoublingEFDFormula, + ], + [ + "add-sunec-v21", + ShortWeierstrassModel, + "projective-3", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "add-sunec-v21-ed25519", + TwistedEdwardsModel, + "extended", + ("other", "Ed25519"), + AdditionEFDFormula, + ], + [ + "dbl-sunec-v21-ed25519", + TwistedEdwardsModel, + "extended", + ("other", "Ed25519"), + DoublingEFDFormula, + ], + [ + "ladd-rfc7748", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "add-bearssl-v06", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "dbl-bearssl-v06", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp256r1"), + DoublingEFDFormula, + ], + [ + "add-libgcrypt-v1102", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "dbl-libgcrypt-v1102", + ShortWeierstrassModel, + "jacobian", + ("secg", "secp256r1"), + DoublingEFDFormula, + ], + [ + "ladd-go-1214", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "add-gecc-322", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp256r1"), + AdditionEFDFormula, + ], + [ + "dbl-gecc-321", + ShortWeierstrassModel, + "jacobian-3", + ("secg", "secp256r1"), + DoublingEFDFormula, + ], + [ + "ladd-boringssl-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], + [ + "dbl-ipp-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + DoublingEFDFormula, + ], + [ + "ladd-botan-x25519", + MontgomeryModel, + "xz", + ("other", "Curve25519"), + LadderEFDFormula, + ], +] + + +@pytest.fixture(params=LIBRARY_FORMULAS, ids=list(map(itemgetter(0), LIBRARY_FORMULAS))) +def library_formula_params(request) -> Tuple[EFDFormula, DomainParameters]: + name, model, coords_name, param_spec, formula_type = request.param + model = model() + coordinate_model = model.coordinates[coords_name] + with as_file(files(test.data.formulas).joinpath(name)) as meta_path, as_file( + files(test.data.formulas).joinpath(name + ".op3") + ) as op3_path: + formula = formula_type(meta_path, op3_path, name, coordinate_model) + params = get_params(*param_spec, coords_name) + return formula, params + + +def test_formula_graph(library_formula_params): + formula, params = library_formula_params + do_test_formula(rename_ivs(formula), params) + + +def test_switch_sign(library_formula_params): + formula, params = library_formula_params + for switch_formula in generate_switched_formulas(formula): + do_test_formula(switch_formula, params) + + +def test_fliparood_formula(library_formula_params): + formula, params = library_formula_params + for fliparood in generate_fliparood_formulas(formula): + do_test_formula(fliparood, params) + + +def test_partition_formula_single(library_formula_params): + formula, params = library_formula_params + try: + next(iter(generate_partitioned_formulas(formula))) + except StopIteration: + pass + + +@pytest.mark.slow +def test_partition_formula(library_formula_params): + formula, params = library_formula_params + for partitioned in generate_partitioned_formulas(formula): + do_test_formula(partitioned, params) + + +def test_reductions(library_formula_params): + formula, params = library_formula_params + do_test_formula(reduce_all_adds(formula), params) + + +def test_expansions(library_formula_params): + formula, params = library_formula_params + do_test_formula(expand_all_muls(formula), params) + do_test_formula(expand_all_nopower2_muls(formula), params) + + +def do_test_formula(formula, params): + coordinate_model = formula.coordinate_model + scale = coordinate_model.formulas.get("z", None) + if scale is None: + scale = coordinate_model.formulas.get("scale", None) + + formula_type = formula.__class__ + for _ in range(10): + Paff = params.curve.affine_random() + P2aff = params.curve.affine_double(Paff) + Qaff = params.curve.affine_random() + Q2aff = params.curve.affine_double(Qaff) + Raff = params.curve.affine_add(Paff, Qaff) + R2aff = params.curve.affine_double(Raff) + QRaff = params.curve.affine_add(Qaff, Raff) + P = Paff.to_model(coordinate_model, params.curve) + P2 = P2aff.to_model(coordinate_model, params.curve) + Q = Qaff.to_model(coordinate_model, params.curve) + Q2 = Q2aff.to_model(coordinate_model, params.curve) + R = Raff.to_model(coordinate_model, params.curve) + R2 = R2aff.to_model(coordinate_model, params.curve) # noqa + QR = QRaff.to_model(coordinate_model, params.curve) + inputs = (P, Q, R)[: formula.num_inputs] + res = formula(params.curve.prime, *inputs, **params.curve.parameters) + if issubclass(formula_type, AdditionFormula): + try: + assert res[0].to_affine() == Raff + except NotImplementedError: + assert ( + scale(params.curve.prime, res[0], **params.curve.parameters)[0] == R + ) + elif issubclass(formula_type, DoublingFormula): + try: + assert res[0].to_affine() == P2aff + except NotImplementedError: + assert ( + scale(params.curve.prime, res[0], **params.curve.parameters)[0] + == P2 + ) + elif issubclass(formula_type, LadderFormula): + try: + assert res[0].to_affine() == Q2aff + assert res[1].to_affine() == QRaff + except NotImplementedError: + # print(scale(params.curve.prime, res[0], **params.curve.parameters)[0]) + # print(scale(params.curve.prime, res[1], **params.curve.parameters)[0]) + # print(P) + # print(Q) + # print(R) + # print(P2) + # print(Q2) + # print(R2) + # print(QR) + # print("------------------------------------") + assert ( + scale(params.curve.prime, res[1], **params.curve.parameters)[0] + == QR + ) + assert ( + scale(params.curve.prime, res[0], **params.curve.parameters)[0] + == Q2 + ) + + +def test_formula_correctness(library_formula_params): + formula, params = library_formula_params + do_test_formula(formula, params) + + +def test_formula_expand(add): + res = expand_formula_list([add]) + assert len(res) > 1 diff --git a/test/ec/test_mult.py b/test/ec/test_mult.py index 20e1c95..d5e3146 100644 --- a/test/ec/test_mult.py +++ b/test/ec/test_mult.py @@ -20,6 +20,7 @@ from pyecsca.ec.mult import ( SlidingWindowMultiplier, BGMWMultiplier, CombMultiplier, + WindowBoothMultiplier, ) from pyecsca.ec.mult.fixed import FullPrecompMultiplier from pyecsca.ec.point import InfinityPoint, Point @@ -36,12 +37,9 @@ def assert_pt_equality(one: Point, other: Point, scale): assert one.equals(other) -def do_basic_test( - mult_class, params, base, add, dbl, scale, neg=None, **kwargs -): +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 + *get_formulas(params.curve.coordinate_model, add, dbl, neg, scale), **kwargs ) mult.init(params, base) res = mult.multiply(314) @@ -59,26 +57,28 @@ def do_basic_test( return res -@pytest.mark.parametrize("add,dbl,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), - ("add-2015-rcb", "dbl-2015-rcb", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", None), - ]) +@pytest.mark.parametrize( + "add,dbl,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), + ("add-2015-rcb", "dbl-2015-rcb", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", None), + ], +) def test_rtl(secp128r1, add, dbl, scale): do_basic_test(RTLMultiplier, secp128r1, secp128r1.generator, add, dbl, scale) -@pytest.mark.parametrize("add,dbl,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), - ("add-2015-rcb", "dbl-2015-rcb", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", None), - ]) +@pytest.mark.parametrize( + "add,dbl,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), + ("add-2015-rcb", "dbl-2015-rcb", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", None), + ], +) def test_ltr(secp128r1, add, dbl, scale): - a = do_basic_test( - LTRMultiplier, secp128r1, secp128r1.generator, 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 ) @@ -100,22 +100,35 @@ def test_ltr(secp128r1, add, dbl, scale): assert_pt_equality(c, d, scale) -@pytest.mark.parametrize("add,dbl,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), - ("add-2015-rcb", "dbl-2015-rcb", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", None), - ]) +@pytest.mark.parametrize( + "add,dbl,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), + ("add-2015-rcb", "dbl-2015-rcb", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", None), + ], +) def test_doubleandadd(secp128r1, add, dbl, scale): a = do_basic_test( DoubleAndAddMultiplier, secp128r1, secp128r1.generator, add, dbl, scale ) b = do_basic_test( - DoubleAndAddMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, direction=ProcessingDirection.RTL + DoubleAndAddMultiplier, + secp128r1, + secp128r1.generator, + add, + dbl, + scale, + direction=ProcessingDirection.RTL, ) c = do_basic_test( - DoubleAndAddMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, - accumulation_order=AccumulationOrder.PeqPR + DoubleAndAddMultiplier, + secp128r1, + secp128r1.generator, + add, + dbl, + scale, + accumulation_order=AccumulationOrder.PeqPR, ) d = do_basic_test( DoubleAndAddMultiplier, @@ -132,13 +145,14 @@ def test_doubleandadd(secp128r1, add, dbl, scale): assert_pt_equality(c, d, scale) -@pytest.mark.parametrize("add,dbl,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), - ("add-2015-rcb", "dbl-2015-rcb", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", None), - ] - ) +@pytest.mark.parametrize( + "add,dbl,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), + ("add-2015-rcb", "dbl-2015-rcb", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", None), + ], +) def test_coron(secp128r1, add, dbl, scale): do_basic_test(CoronMultiplier, secp128r1, secp128r1.generator, add, dbl, scale) @@ -164,27 +178,31 @@ def test_ladder(curve25519): assert_pt_equality(a, b, True) -@pytest.mark.parametrize("add,dbl,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), - ("add-2015-rcb", "dbl-2015-rcb", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", None), - ]) +@pytest.mark.parametrize( + "add,dbl,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "z"), + ("add-2015-rcb", "dbl-2015-rcb", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", None), + ], +) def test_simple_ladder(secp128r1, add, dbl, scale): do_basic_test( SimpleLadderMultiplier, secp128r1, secp128r1.generator, add, dbl, scale ) -@pytest.mark.parametrize("num,complete", - [ - (15, True), - (15, False), - (2355498743, True), - (2355498743, False), - (325385790209017329644351321912443757746, True), - (325385790209017329644351321912443757746, False), - ]) +@pytest.mark.parametrize( + "num,complete", + [ + (15, True), + (15, False), + (2355498743, True), + (2355498743, False), + (325385790209017329644351321912443757746, True), + (325385790209017329644351321912443757746, False), + ], +) def test_ladder_differential(curve25519, num, complete): ladder = LadderMultiplier( curve25519.curve.coordinate_model.formulas["ladd-1987-m"], @@ -206,27 +224,31 @@ def test_ladder_differential(curve25519, num, complete): assert InfinityPoint(curve25519.curve.coordinate_model) == differential.multiply(0) -@pytest.mark.parametrize("add,dbl,neg,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", "z"), - ("add-2015-rcb", "dbl-2015-rcb", "neg", None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", None), - ]) +@pytest.mark.parametrize( + "add,dbl,neg,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", "z"), + ("add-2015-rcb", "dbl-2015-rcb", "neg", None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", None), + ], +) def test_binary_naf(secp128r1, add, dbl, neg, scale): do_basic_test( BinaryNAFMultiplier, secp128r1, secp128r1.generator, add, dbl, scale, neg ) -@pytest.mark.parametrize("add,dbl,neg,width,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 3, "z"), - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 3, None), - ("add-2015-rcb", "dbl-2015-rcb", "neg", 3, None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, "z"), - ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, None), - ("add-2015-rcb", "dbl-2015-rcb", "neg", 5, None), - ]) +@pytest.mark.parametrize( + "add,dbl,neg,width,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 3, "z"), + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 3, None), + ("add-2015-rcb", "dbl-2015-rcb", "neg", 3, None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, "z"), + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, None), + ("add-2015-rcb", "dbl-2015-rcb", "neg", 5, None), + ], +) def test_window_naf(secp128r1, add, dbl, neg, width, scale): formulas = get_formulas(secp128r1.curve.coordinate_model, add, dbl, neg, scale) mult = WindowNAFMultiplier(*formulas[:3], width, *formulas[3:]) @@ -247,12 +269,14 @@ def test_window_naf(secp128r1, add, dbl, neg, width, scale): assert_pt_equality(res_precompute, res, scale) -@pytest.mark.parametrize("add,dbl,width,scale", - [ - ("add-1998-cmo-2", "dbl-1998-cmo-2", 5, "z"), - ("add-2015-rcb", "dbl-2015-rcb", 5, None), - ("add-1998-cmo-2", "dbl-1998-cmo-2", 5, None), - ]) +@pytest.mark.parametrize( + "add,dbl,width,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", 5, "z"), + ("add-2015-rcb", "dbl-2015-rcb", 5, None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", 5, None), + ], +) def test_fixed_window(secp128r1, add, dbl, width, scale): formulas = get_formulas(secp128r1.curve.coordinate_model, add, dbl, scale) mult = FixedWindowLTRMultiplier(*formulas[:2], width, *formulas[2:]) @@ -266,6 +290,27 @@ def test_fixed_window(secp128r1, add, dbl, width, scale): assert InfinityPoint(secp128r1.curve.coordinate_model) == mult.multiply(0) +@pytest.mark.parametrize( + "add,dbl,neg,width,scale", + [ + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, "z"), + ("add-2015-rcb", "dbl-2015-rcb", "neg", 5, None), + ("add-1998-cmo-2", "dbl-1998-cmo-2", "neg", 5, None), + ], +) +def test_booth_window(secp128r1, add, dbl, neg, width, scale): + formulas = get_formulas(secp128r1.curve.coordinate_model, add, dbl, neg, scale) + mult = WindowBoothMultiplier(*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) + + @pytest.fixture(params=["add-1998-cmo-2", "add-2015-rcb"]) def add(secp128r1, request): return secp128r1.curve.coordinate_model.formulas[request.param] @@ -276,53 +321,137 @@ def dbl(secp128r1, request): return secp128r1.curve.coordinate_model.formulas[request.param] -@pytest.mark.parametrize("num", [10, 2355498743, 325385790209017329644351321912443757746]) +@pytest.mark.parametrize( + "num", [10, 2355498743, 325385790209017329644351321912443757746] +) def test_basic_multipliers(secp128r1, num, add, dbl): neg = secp128r1.curve.coordinate_model.formulas["neg"] scale = secp128r1.curve.coordinate_model.formulas["z"] - ltr_options = {"always": (True, False), - "complete": (True, False), - "accumulation_order": tuple(AccumulationOrder)} - ltrs = [LTRMultiplier(add, dbl, scale, **dict(zip(ltr_options.keys(), combination))) for combination in product(*ltr_options.values())] + ltr_options = { + "always": (True, False), + "complete": (True, False), + "accumulation_order": tuple(AccumulationOrder), + } + ltrs = [ + LTRMultiplier(add, dbl, scale, **dict(zip(ltr_options.keys(), combination))) + for combination in product(*ltr_options.values()) + ] rtl_options = ltr_options - rtls = [RTLMultiplier(add, dbl, scale, **dict(zip(rtl_options.keys(), combination))) for combination in product(*rtl_options.values())] - bnaf_options = {"direction": tuple(ProcessingDirection), - "accumulation_order": tuple(AccumulationOrder)} - bnafs = [BinaryNAFMultiplier(add, dbl, neg, scale, **dict(zip(bnaf_options.keys(), combination))) for combination in product(*bnaf_options.values())] - wnaf_options = {"precompute_negation": (True, False), - "width": (3, 5), - "accumulation_order": tuple(AccumulationOrder)} - wnafs = [WindowNAFMultiplier(add, dbl, neg, scl=scale, **dict(zip(wnaf_options.keys(), combination))) for combination in product(*wnaf_options.values())] + rtls = [ + RTLMultiplier(add, dbl, scale, **dict(zip(rtl_options.keys(), combination))) + for combination in product(*rtl_options.values()) + ] + bnaf_options = { + "direction": tuple(ProcessingDirection), + "accumulation_order": tuple(AccumulationOrder), + } + bnafs = [ + BinaryNAFMultiplier( + add, dbl, neg, scale, **dict(zip(bnaf_options.keys(), combination)) + ) + for combination in product(*bnaf_options.values()) + ] + wnaf_options = { + "precompute_negation": (True, False), + "width": (3, 5), + "accumulation_order": tuple(AccumulationOrder), + } + wnafs = [ + WindowNAFMultiplier( + add, dbl, neg, scl=scale, **dict(zip(wnaf_options.keys(), combination)) + ) + for combination in product(*wnaf_options.values()) + ] + booth_options = { + "precompute_negation": (True, False), + "width": (3, 5), + "accumulation_order": tuple(AccumulationOrder), + } + booths = [ + WindowBoothMultiplier( + add, dbl, neg, scl=scale, **dict(zip(booth_options.keys(), combination)) + ) + for combination in product(*booth_options.values()) + ] ladder_options = {"complete": (True, False)} - ladders = [SimpleLadderMultiplier(add, dbl, scale, **dict(zip(ladder_options.keys(), combination))) for combination in product(*ladder_options.values())] - fixed_options = {"m": (5, 8), - "accumulation_order": tuple(AccumulationOrder)} - fixeds = [FixedWindowLTRMultiplier(add, dbl, scl=scale, **dict(zip(fixed_options.keys(), combination))) for combination in product(*fixed_options.values())] - sliding_options = {"width": (3, 5), - "recoding_direction": tuple(ProcessingDirection), - "accumulation_order": tuple(AccumulationOrder)} - slides = [SlidingWindowMultiplier(add, dbl, scl=scale, **dict(zip(sliding_options.keys(), combination))) for combination in product(*sliding_options.values())] - precomp_options = {"always": (True, False), - "complete": (True, False), - "direction": tuple(ProcessingDirection), - "accumulation_order": tuple(AccumulationOrder)} - precomps = [FullPrecompMultiplier(add, dbl, scl=scale, **dict(zip(precomp_options.keys(), combination))) for combination in product(*precomp_options.values())] - bgmw_options = {"width": (3, 5), - "direction": tuple(ProcessingDirection), - "accumulation_order": tuple(AccumulationOrder)} - bgmws = [BGMWMultiplier(add, dbl, scl=scale, **dict(zip(bgmw_options.keys(), combination))) for combination in product(*bgmw_options.values())] - comb_options = {"width": (2, 3, 5), - "accumulation_order": tuple(AccumulationOrder)} - combs = [CombMultiplier(add, dbl, scl=scale, **dict(zip(comb_options.keys(), combination))) for combination in product(*comb_options.values())] + ladders = [ + SimpleLadderMultiplier( + add, dbl, scale, **dict(zip(ladder_options.keys(), combination)) + ) + for combination in product(*ladder_options.values()) + ] + fixed_options = {"m": (5, 8), "accumulation_order": tuple(AccumulationOrder)} + fixeds = [ + FixedWindowLTRMultiplier( + add, dbl, scl=scale, **dict(zip(fixed_options.keys(), combination)) + ) + for combination in product(*fixed_options.values()) + ] + sliding_options = { + "width": (3, 5), + "recoding_direction": tuple(ProcessingDirection), + "accumulation_order": tuple(AccumulationOrder), + } + slides = [ + SlidingWindowMultiplier( + add, dbl, scl=scale, **dict(zip(sliding_options.keys(), combination)) + ) + for combination in product(*sliding_options.values()) + ] + precomp_options = { + "always": (True, False), + "complete": (True, False), + "direction": tuple(ProcessingDirection), + "accumulation_order": tuple(AccumulationOrder), + } + precomps = [ + FullPrecompMultiplier( + add, dbl, scl=scale, **dict(zip(precomp_options.keys(), combination)) + ) + for combination in product(*precomp_options.values()) + ] + bgmw_options = { + "width": (3, 5), + "direction": tuple(ProcessingDirection), + "accumulation_order": tuple(AccumulationOrder), + } + bgmws = [ + BGMWMultiplier( + add, dbl, scl=scale, **dict(zip(bgmw_options.keys(), combination)) + ) + for combination in product(*bgmw_options.values()) + ] + comb_options = {"width": (2, 3, 5), "accumulation_order": tuple(AccumulationOrder)} + combs = [ + CombMultiplier( + add, dbl, scl=scale, **dict(zip(comb_options.keys(), combination)) + ) + for combination in product(*comb_options.values()) + ] - mults: Sequence[ScalarMultiplier] = ltrs + rtls + bnafs + wnafs + [CoronMultiplier(add, dbl, scale)] + ladders + fixeds + slides + precomps + bgmws + combs + mults: Sequence[ScalarMultiplier] = ( + ltrs + + rtls + + bnafs + + wnafs + + booths + + [CoronMultiplier(add, dbl, scale)] + + ladders + + fixeds + + slides + + precomps + + bgmws + + combs + ) results = [] for mult in mults: mult.init(secp128r1, secp128r1.generator) res = mult.multiply(num) if results: - assert res == results[-1], f"Points not equal {res} != {results[-1]} for mult = {mult}" + assert ( + res == results[-1] + ), f"Points not equal {res} != {results[-1]} for mult = {mult}" results.append(res) diff --git a/test/ec/test_scalar.py b/test/ec/test_scalar.py index 493690a..9c6cb60 100644 --- a/test/ec/test_scalar.py +++ b/test/ec/test_scalar.py @@ -1,4 +1,13 @@ -from pyecsca.ec.scalar import convert_base, sliding_window_ltr, sliding_window_rtl, wnaf, naf +from pyecsca.ec.scalar import ( + convert_base, + sliding_window_ltr, + sliding_window_rtl, + wnaf, + naf, + booth, + booth_word, + booth_window, +) def test_convert(): @@ -14,3 +23,18 @@ def test_sliding_window(): def test_nafs(): i = 0b1100110101001101011011 assert naf(i) == wnaf(i, 2) + + +def test_booth(): + assert booth(0b101) == [-1, 1, -1, 1] + for i in range(2**6): + bw = booth_word(i, 5) + # verified with BoringSSL recoding impl. (ec_GFp_nistp_recode_scalar_bits) + if i <= 31: + assert bw == (i + 1) // 2 + else: + assert bw == -((64 - i) // 2) + s = 0x12345678123456781234567812345678123456781234567812345678 + bw = booth_window(s, 5, 224) + # verified with BoringSSL ec_GFp_nistp224_point_mul + assert bw == [1, 4, 13, 3, -10, 15, 0, 9, 3, 9, -10, -12, -8, 2, 9, -6, 5, 13, -2, 1, -14, 7, -15, 11, 8, -16, 5, -14, -12, 11, -6, -4, 1, 4, 13, 3, -10, 15, 0, 9, 3, 9, -10, -12, -8] diff --git a/test/sca/test_rpa.py b/test/sca/test_rpa.py index f09a1a1..39c281d 100644 --- a/test/sca/test_rpa.py +++ b/test/sca/test_rpa.py @@ -12,12 +12,24 @@ from pyecsca.ec.mult import ( RTLMultiplier, BinaryNAFMultiplier, WindowNAFMultiplier, - SimpleLadderMultiplier, AccumulationOrder, ProcessingDirection, SlidingWindowMultiplier, FixedWindowLTRMultiplier, - FullPrecompMultiplier, BGMWMultiplier, CombMultiplier, + SimpleLadderMultiplier, + AccumulationOrder, + ProcessingDirection, + SlidingWindowMultiplier, + FixedWindowLTRMultiplier, + FullPrecompMultiplier, + BGMWMultiplier, + CombMultiplier, + WindowBoothMultiplier, ) from pyecsca.ec.params import DomainParameters from pyecsca.ec.point import Point -from pyecsca.sca.re.rpa import MultipleContext, rpa_point_0y, rpa_point_x0, rpa_distinguish +from pyecsca.sca.re.rpa import ( + MultipleContext, + rpa_point_0y, + rpa_point_x0, + rpa_distinguish, +) @pytest.fixture() @@ -47,18 +59,18 @@ def neg(coords): @pytest.fixture() def rpa_params(model, coords): - p = 0x85d265945a4f5681 - a = Mod(0x7fc57b4110698bc0, p) - b = Mod(0x37113ea591b04527, p) - gx = Mod(0x80d2d78fddb97597, p) - gy = Mod(0x5586d818b7910930, p) + p = 0x85D265945A4F5681 + a = Mod(0x7FC57B4110698BC0, p) + b = Mod(0x37113EA591B04527, p) + gx = Mod(0x80D2D78FDDB97597, p) + gy = Mod(0x5586D818B7910930, p) # (0x4880bcf620852a54, 0) RPA point # (0, 0x6bed3155c9ada064) RPA point infty = Point(coords, X=Mod(0, p), Y=Mod(1, p), Z=Mod(0, p)) g = Point(coords, X=gx, Y=gy, Z=Mod(1, p)) curve = EllipticCurve(model, coords, p, infty, dict(a=a, b=b)) - return DomainParameters(curve, g, 0x85d265932d90785c, 1) + return DomainParameters(curve, g, 0x85D265932D90785C, 1) def test_x0_point(rpa_params): @@ -80,25 +92,63 @@ def test_distinguish(secp128r1, add, dbl, neg): RTLMultiplier(add, dbl, None, False, AccumulationOrder.PeqPR, True), RTLMultiplier(add, dbl, None, True, AccumulationOrder.PeqPR, False), SimpleLadderMultiplier(add, dbl, None, True, True), - BinaryNAFMultiplier(add, dbl, neg, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True), - WindowNAFMultiplier(add, dbl, neg, 3, None, AccumulationOrder.PeqPR, True, True), - WindowNAFMultiplier(add, dbl, neg, 4, None, AccumulationOrder.PeqPR, True, True), + BinaryNAFMultiplier( + add, dbl, neg, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True + ), + WindowNAFMultiplier( + add, dbl, neg, 3, None, AccumulationOrder.PeqPR, True, True + ), + WindowNAFMultiplier( + add, dbl, neg, 4, None, AccumulationOrder.PeqPR, True, True + ), + WindowBoothMultiplier( + add, dbl, neg, 4, None, AccumulationOrder.PeqPR, True, True + ), # WindowNAFMultiplier(add, dbl, neg, 4, None, AccumulationOrder.PeqPR, False, True), - SlidingWindowMultiplier(add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True), - SlidingWindowMultiplier(add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True), + SlidingWindowMultiplier( + add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True + ), + SlidingWindowMultiplier( + add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True + ), FixedWindowLTRMultiplier(add, dbl, 4, None, AccumulationOrder.PeqPR, True), FixedWindowLTRMultiplier(add, dbl, 5, None, AccumulationOrder.PeqPR, True), - FullPrecompMultiplier(add, dbl, None, True, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True, True), - FullPrecompMultiplier(add, dbl, None, False, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True, True), + FullPrecompMultiplier( + add, + dbl, + None, + True, + ProcessingDirection.LTR, + AccumulationOrder.PeqPR, + True, + True, + ), + FullPrecompMultiplier( + add, + dbl, + None, + False, + ProcessingDirection.LTR, + AccumulationOrder.PeqPR, + True, + True, + ), # FullPrecompMultiplier(add, dbl, None, False, ProcessingDirection.RTL, AccumulationOrder.PeqPR, True, True), - BGMWMultiplier(add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True), - BGMWMultiplier(add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True), + BGMWMultiplier( + add, dbl, 3, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True + ), + BGMWMultiplier( + add, dbl, 5, None, ProcessingDirection.LTR, AccumulationOrder.PeqPR, True + ), CombMultiplier(add, dbl, 3, None, AccumulationOrder.PeqPR, True), - CombMultiplier(add, dbl, 5, None, AccumulationOrder.PeqPR, True) + CombMultiplier(add, dbl, 5, None, AccumulationOrder.PeqPR, True), ] for real_mult in multipliers: + def simulated_oracle(scalar, affine_point): - point = affine_point.to_model(secp128r1.curve.coordinate_model, secp128r1.curve) + point = affine_point.to_model( + secp128r1.curve.coordinate_model, secp128r1.curve + ) with local(MultipleContext()) as ctx: real_mult.init(secp128r1, point) real_mult.multiply(scalar) diff --git a/test/sca/test_structural.py b/test/sca/test_structural.py deleted file mode 100644 index 970e4fc..0000000 --- a/test/sca/test_structural.py +++ /dev/null @@ -1,315 +0,0 @@ -import pytest -from importlib_resources import files, as_file -import test.data.formulas -from pyecsca.ec.formula import ( - AdditionEFDFormula, - LadderEFDFormula, - DoublingEFDFormula, - AdditionFormula, - DoublingFormula, - LadderFormula, -) -from pyecsca.ec.model import ShortWeierstrassModel, MontgomeryModel, TwistedEdwardsModel -from pyecsca.ec.params import get_params -from pyecsca.sca.re.structural import formula_similarity - - -def test_formula_similarity(secp128r1): - add_bl = secp128r1.curve.coordinate_model.formulas["add-2007-bl"] - add_rcb = secp128r1.curve.coordinate_model.formulas["add-2015-rcb"] - out = formula_similarity(add_bl, add_rcb) - assert out["output"] == 0 - assert out["ivs"] < 0.5 - out_same = formula_similarity(add_bl, add_bl) - assert out_same["output"] == 1 - assert out_same["ivs"] == 1 - - -@pytest.mark.parametrize( - "name,model,coords,param_spec,formula_type", - [ - [ - "add-bc-r1rv76-jac", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp128r1"), - AdditionEFDFormula, - ], - [ - "add-bc-r1rv76-mod", - ShortWeierstrassModel, - "modified", - ("secg", "secp128r1"), - AdditionEFDFormula, - ], - [ - "dbl-bc-r1rv76-jac", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp128r1"), - DoublingEFDFormula, - ], - [ - "dbl-bc-r1rv76-mod", - ShortWeierstrassModel, - "modified", - ("secg", "secp128r1"), - DoublingEFDFormula, - ], - [ - "dbl-bc-r1rv76-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - DoublingEFDFormula, - ], - [ - "ladd-bc-r1rv76-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "dbl-boringssl-p224", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp224r1"), - DoublingEFDFormula, - ], - [ - "add-boringssl-p224", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp224r1"), - AdditionEFDFormula, - ], - [ - "add-libressl-v382", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp128r1"), - AdditionEFDFormula, - ], - [ - "dbl-libressl-v382", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp128r1"), - DoublingEFDFormula, - ], - [ - "dbl-secp256k1-v040", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp256k1"), - DoublingEFDFormula, - ], - [ - "add-openssl-z256", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "add-openssl-z256a", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "ladd-openssl-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "ladd-hacl-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "dbl-hacl-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - DoublingEFDFormula, - ], - [ - "dbl-sunec-v21", - ShortWeierstrassModel, - "projective-3", - ("secg", "secp256r1"), - DoublingEFDFormula, - ], - [ - "add-sunec-v21", - ShortWeierstrassModel, - "projective-3", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "add-sunec-v21-ed25519", - TwistedEdwardsModel, - "extended", - ("other", "Ed25519"), - AdditionEFDFormula, - ], - [ - "dbl-sunec-v21-ed25519", - TwistedEdwardsModel, - "extended", - ("other", "Ed25519"), - DoublingEFDFormula, - ], - [ - "ladd-rfc7748", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "add-bearssl-v06", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "dbl-bearssl-v06", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp256r1"), - DoublingEFDFormula, - ], - [ - "add-libgcrypt-v1102", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "dbl-libgcrypt-v1102", - ShortWeierstrassModel, - "jacobian", - ("secg", "secp256r1"), - DoublingEFDFormula, - ], - [ - "ladd-go-1214", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "add-gecc-322", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp256r1"), - AdditionEFDFormula, - ], - [ - "dbl-gecc-321", - ShortWeierstrassModel, - "jacobian-3", - ("secg", "secp256r1"), - DoublingEFDFormula, - ], - [ - "ladd-boringssl-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - [ - "dbl-ipp-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - DoublingEFDFormula, - ], - [ - "ladd-botan-x25519", - MontgomeryModel, - "xz", - ("other", "Curve25519"), - LadderEFDFormula, - ], - ], -) -def test_formula_correctness(name, model, coords, param_spec, formula_type): - model = model() - coordinate_model = model.coordinates[coords] - with as_file(files(test.data.formulas).joinpath(name)) as meta_path, as_file( - files(test.data.formulas).joinpath(name + ".op3") - ) as op3_path: - formula = formula_type(meta_path, op3_path, name, coordinate_model) - params = get_params(*param_spec, coords) - scale = coordinate_model.formulas.get("z", None) - if scale is None: - scale = coordinate_model.formulas.get("scale", None) - for _ in range(10): - Paff = params.curve.affine_random() - P2aff = params.curve.affine_double(Paff) - Qaff = params.curve.affine_random() - Q2aff = params.curve.affine_double(Qaff) - Raff = params.curve.affine_add(Paff, Qaff) - R2aff = params.curve.affine_double(Raff) - QRaff = params.curve.affine_add(Qaff, Raff) - P = Paff.to_model(coordinate_model, params.curve) - P2 = P2aff.to_model(coordinate_model, params.curve) - Q = Qaff.to_model(coordinate_model, params.curve) - Q2 = Q2aff.to_model(coordinate_model, params.curve) - R = Raff.to_model(coordinate_model, params.curve) - R2 = R2aff.to_model(coordinate_model, params.curve) # noqa - QR = QRaff.to_model(coordinate_model, params.curve) - inputs = (P, Q, R)[: formula.num_inputs] - res = formula(params.curve.prime, *inputs, **params.curve.parameters) - if issubclass(formula_type, AdditionFormula): - try: - assert res[0].to_affine() == Raff - except NotImplementedError: - assert ( - scale(params.curve.prime, res[0], **params.curve.parameters)[0] == R - ) - elif issubclass(formula_type, DoublingFormula): - try: - assert res[0].to_affine() == P2aff - except NotImplementedError: - assert ( - scale(params.curve.prime, res[0], **params.curve.parameters)[0] - == P2 - ) - elif issubclass(formula_type, LadderFormula): - try: - assert res[0].to_affine() == Q2aff - assert res[1].to_affine() == QRaff - except NotImplementedError: - # print(scale(params.curve.prime, res[0], **params.curve.parameters)[0]) - # print(scale(params.curve.prime, res[1], **params.curve.parameters)[0]) - # print(P) - # print(Q) - # print(R) - # print(P2) - # print(Q2) - # print(R2) - # print(QR) - # print("------------------------------------") - assert ( - scale(params.curve.prime, res[1], **params.curve.parameters)[0] - == QR - ) - assert ( - scale(params.curve.prime, res[0], **params.curve.parameters)[0] - == Q2 - ) |
