diff options
| author | J08nY | 2023-09-28 17:31:33 +0200 |
|---|---|---|
| committer | J08nY | 2023-09-28 17:31:33 +0200 |
| commit | f2a0476c778dd5f752bf522f28563ec7a01f186e (patch) | |
| tree | ce1566ffa0478131236cb603774f88222173f98b /test/test_impl.py | |
| parent | edae0ca0627926772045c105ae4551c18f872653 (diff) | |
| download | pyecsca-codegen-f2a0476c778dd5f752bf522f28563ec7a01f186e.tar.gz pyecsca-codegen-f2a0476c778dd5f752bf522f28563ec7a01f186e.tar.zst pyecsca-codegen-f2a0476c778dd5f752bf522f28563ec7a01f186e.zip | |
Move to pytest.
Diffstat (limited to 'test/test_impl.py')
| -rw-r--r-- | test/test_impl.py | 494 |
1 files changed, 277 insertions, 217 deletions
diff --git a/test/test_impl.py b/test/test_impl.py index b054567..6c58315 100644 --- a/test/test_impl.py +++ b/test/test_impl.py @@ -1,137 +1,165 @@ from copy import copy from os.path import join -from unittest import TestCase +import pytest -from click.testing import CliRunner -from pyecsca.ec.params import get_params from pyecsca.ec.key_agreement import ECDH_SHA1 -from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier, CoronMultiplier, BinaryNAFMultiplier +from pyecsca.ec.mult import ( + LTRMultiplier, + RTLMultiplier, + CoronMultiplier, + BinaryNAFMultiplier, +) from pyecsca.ec.signature import ECDSA_SHA1, SignatureResult from pyecsca.codegen.builder import build_impl from pyecsca.codegen.client import HostTarget -class ImplTests(TestCase): +def do_basic_test( + callback, + runner, + params, + mult_class, + formulas, + mult_name, + ecdsa, + ecdh, + **mult_kwargs, +): + other_args = [ + ("--mul", "KARATSUBA", "--sqr", "KARATSUBA"), + ("--mul", "TOOM_COOK", "--sqr", "TOOM_COOK"), + ("--red", "BARRETT"), + ("--red", "MONTGOMERY"), + ] + for additional in other_args: + with runner.isolated_filesystem() as tmpdir: + runner.invoke( + build_impl, + [ + "--platform", + "HOST", + *additional, + "--ecdsa" if ecdsa else "--no-ecdsa", + "--ecdh" if ecdh else "--no-ecdh", + params.curve.model.shortname, + params.curve.coordinate_model.name, + *formulas, + f"{mult_name}({','.join(f'{key}={value}' for key, value in mult_kwargs.items())})", + ".", + ], + ) + target = HostTarget( + params.curve.model, + params.curve.coordinate_model, + binary=join(tmpdir, "pyecsca-codegen-HOST.elf"), + ) + target.connect() + target.set_params(params) + formula_instances = [ + params.curve.coordinate_model.formulas[formula] for formula in formulas + ] + mult = mult_class(*formula_instances, **mult_kwargs) + mult.init(params, params.generator) + callback(target, mult, params) + target.disconnect() - def setUp(self): - self.secp128r1 = get_params("secg", "secp128r1", "projective") - self.base = self.secp128r1.generator - self.coords = self.secp128r1.curve.coordinate_model - self.curve25519 = get_params("other", "Curve25519", "xz") - self.base25519 = self.curve25519.generator - self.coords25519 = self.curve25519.curve.coordinate_model +def test_init(cli_runner, secp128r1): + def callback(target, mult, params): + target.init_prng(bytes([0x12, 0x34, 0x56, 0x78])) - def do_basic_test(self, callback, runner, params, mult_class, formulas, mult_name, - ecdsa, ecdh, **mult_kwargs): - other_args = [ - ("--mul", "KARATSUBA", "--sqr", "KARATSUBA"), - ("--mul", "TOOM_COOK", "--sqr", "TOOM_COOK"), - ("--red", "BARRETT"), - ("--red", "MONTGOMERY") - ] - for additional in other_args: - with runner.isolated_filesystem() as tmpdir: - runner.invoke(build_impl, - ["--platform", "HOST", - *additional, - "--ecdsa" if ecdsa else "--no-ecdsa", - "--ecdh" if ecdh else "--no-ecdh", - params.curve.model.shortname, params.curve.coordinate_model.name, - *formulas, - f"{mult_name}({','.join(f'{key}={value}' for key, value in mult_kwargs.items())})", - "."]) - target = HostTarget(params.curve.model, params.curve.coordinate_model, - binary=join(tmpdir, "pyecsca-codegen-HOST.elf")) - target.connect() - target.set_params(params) - formula_instances = [params.curve.coordinate_model.formulas[formula] for formula - in formulas] - mult = mult_class(*formula_instances, **mult_kwargs) - mult.init(params, params.generator) - callback(target, mult, params) - target.disconnect() + do_basic_test( + callback, + cli_runner, + secp128r1, + LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], + "ltr", + False, + False, + ) -class PRNGTests(ImplTests): +def test_setup(cli_runner, secp128r1): + def callback(target, mult, params): + priv = 57 + pub = mult.multiply(priv).to_affine() + target.set_privkey(priv) + target.set_pubkey(pub) - def test_init(self): - runner = CliRunner() + do_basic_test( + callback, + cli_runner, + secp128r1, + LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], + "ltr", + False, + False, + ) - def callback(target, mult, params): - target.init_prng(bytes([0x12, 0x34, 0x56, 0x78])) - self.do_basic_test(callback, runner, self.secp128r1, LTRMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False, complete=False) +def test_debug(cli_runner, secp128r1): + def callback(target, mult, params): + model, coords = target.debug() + assert model == params.curve.model.shortname + assert coords == params.curve.coordinate_model.name + do_basic_test( + callback, + cli_runner, + secp128r1, + LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], + "ltr", + False, + False, + ) -class SetupTests(ImplTests): - def test_setup(self): - runner = CliRunner() - - def callback(target, mult, params): - priv = 57 - pub = mult.multiply(priv).to_affine() - target.set_privkey(priv) - target.set_pubkey(pub) - - self.do_basic_test(callback, runner, self.secp128r1, LTRMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False, complete=False) - - def test_debug(self): - runner = CliRunner() - - def callback(target, mult, params): - model, coords = target.debug() - self.assertEqual(model, params.curve.model.shortname) - self.assertEqual(coords, params.curve.coordinate_model.name) - - self.do_basic_test(callback, runner, self.secp128r1, LTRMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False, complete=False) - - -class KeyGenerationTests(ImplTests): - - def do_keygen_test(self, runner, params, mult_class, formulas, mult_name, **mult_kwargs): - def callback(target, mult, params): - for _ in range(10): - priv, pub = target.generate() - self.assertTrue(params.curve.is_on_curve(pub)) - expected = mult.multiply(priv).to_affine() - self.assertEqual(pub, expected) - - self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, False, False, - **mult_kwargs) - - def test_ltr(self): - runner = CliRunner() - self.do_keygen_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False) - self.do_keygen_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True) - self.do_keygen_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", always=True, complete=False) - self.do_keygen_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", always=True, complete=True) - - def test_rtl(self): - runner = CliRunner() - self.do_keygen_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=False) - self.do_keygen_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=True) - - def test_coron(self): - runner = CliRunner() - self.do_keygen_test(runner, self.secp128r1, CoronMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "coron") +@pytest.mark.parametrize( + "mult_class,mult_name,formulas,mult_kwargs", + [ + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": False}), + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": True}), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": False, "always": True}, + ), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": True, "always": True}, + ), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": False}), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": True}), + (CoronMultiplier, "coron", ["add-1998-cmo", "dbl-1998-cmo"], {}), + (BinaryNAFMultiplier, "bnaf", ["add-1998-cmo", "dbl-1998-cmo", "neg"], {}), + ], +) +def test_keygen(mult_class, mult_name, mult_kwargs, formulas, cli_runner, secp128r1): + def callback(target, mult, params): + for _ in range(10): + priv, pub = target.generate() + assert params.curve.is_on_curve(pub) + expected = mult.multiply(priv).to_affine() + assert pub == expected - def test_bnaf(self): - runner = CliRunner() - self.do_keygen_test(runner, self.secp128r1, BinaryNAFMultiplier, - ["add-1998-cmo", "dbl-1998-cmo", "neg"], "bnaf") + do_basic_test( + callback, + cli_runner, + secp128r1, + mult_class, + formulas, + mult_name, + False, + False, + **mult_kwargs, + ) # def test_ladder(self): # runner = CliRunner() @@ -139,120 +167,152 @@ class KeyGenerationTests(ImplTests): # # TODO: what about coords where generator is not affine? -class ScalarMultiplicationTests(ImplTests): +@pytest.mark.parametrize( + "mult_class,mult_name,formulas,mult_kwargs", + [ + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": False}), + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": True}), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": False, "always": True}, + ), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": True, "always": True}, + ), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": False}), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": True}), + (CoronMultiplier, "coron", ["add-1998-cmo", "dbl-1998-cmo"], {}), + (BinaryNAFMultiplier, "bnaf", ["add-1998-cmo", "dbl-1998-cmo", "neg"], {}), + ], +) +def test_scalarmult( + mult_class, mult_name, mult_kwargs, formulas, cli_runner, secp128r1 +): + values = [15, 2355498743, 3253857901321912443757746] - def do_mult_test(self, runner, params, mult_class, formulas, mult_name, **mult_kwargs): - values = [15, 2355498743, 3253857901321912443757746] + def callback(target, mult, params): + for value in values: + result = target.scalar_mult(value, params.generator) + expected = mult.multiply(value) + assert result == expected - def callback(target, mult, params): - for value in values: - result = target.scalar_mult(value, params.generator) - expected = mult.multiply(value) - self.assertEqual(result, expected) + do_basic_test( + callback, + cli_runner, + secp128r1, + mult_class, + formulas, + mult_name, + False, + False, + **mult_kwargs, + ) - self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, False, False, - **mult_kwargs) - def test_ltr(self): - runner = CliRunner() - self.do_mult_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False) - self.do_mult_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True) - self.do_mult_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False, always=True) - self.do_mult_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True, always=True) +@pytest.mark.parametrize( + "mult_class,mult_name,formulas,mult_kwargs", + [ + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": False}), + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": True}), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": False, "always": True}, + ), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": True, "always": True}, + ), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": False}), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": True}), + (CoronMultiplier, "coron", ["add-1998-cmo", "dbl-1998-cmo"], {}), + (BinaryNAFMultiplier, "bnaf", ["add-1998-cmo", "dbl-1998-cmo", "neg"], {}), + ], +) +def test_ecdh(mult_class, mult_name, mult_kwargs, formulas, cli_runner, secp128r1): + other_privs = [15, 2355498743, 3253857901321912443757746] - def test_rtl(self): - runner = CliRunner() - self.do_mult_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=False) - self.do_mult_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=True) - - def test_coron(self): - runner = CliRunner() - self.do_mult_test(runner, self.secp128r1, CoronMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "coron") - - def test_bnaf(self): - runner = CliRunner() - self.do_mult_test(runner, self.secp128r1, BinaryNAFMultiplier, - ["add-1998-cmo", "dbl-1998-cmo", "neg"], "bnaf") - - -class ECDHTests(ImplTests): - def do_ecdh_test(self, runner, params, mult_class, formulas, mult_name, **mult_kwargs): - other_privs = [15, 2355498743, 3253857901321912443757746] - - def callback(target, mult, params): - for other_priv in other_privs: - priv, pub = target.generate() - other_pub = mult.multiply(other_priv) - ecdh = ECDH_SHA1(copy(mult), params, other_pub, priv) - result = target.ecdh(other_pub) - expected = ecdh.perform() - self.assertEqual(result, expected) - - self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, False, True, - **mult_kwargs) - - def test_ltr(self): - runner = CliRunner() - self.do_ecdh_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False) - self.do_ecdh_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True) - self.do_ecdh_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False, always=True) - self.do_ecdh_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True, always=True) - - def test_rtl(self): - runner = CliRunner() - self.do_ecdh_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=False) - self.do_ecdh_test(runner, self.secp128r1, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "rtl", always=True) - - def test_coron(self): - runner = CliRunner() - self.do_ecdh_test(runner, self.secp128r1, CoronMultiplier, - ["add-1998-cmo", "dbl-1998-cmo"], "coron") - - def test_bnaf(self): - runner = CliRunner() - self.do_ecdh_test(runner, self.secp128r1, BinaryNAFMultiplier, - ["add-1998-cmo", "dbl-1998-cmo", "neg"], "bnaf") + def callback(target, mult, params): + for other_priv in other_privs: + priv, pub = target.generate() + other_pub = mult.multiply(other_priv) + ecdh = ECDH_SHA1(copy(mult), params, other_pub, priv) + result = target.ecdh(other_pub) + expected = ecdh.perform() + assert result == expected + do_basic_test( + callback, + cli_runner, + secp128r1, + mult_class, + formulas, + mult_name, + False, + True, + **mult_kwargs, + ) -class ECDSATests(ImplTests): - def do_ecdsa_test(self, runner, params, mult_class, formulas, mult_name, **mult_kwargs): - data = b"something" - def callback(target, mult, params): - priv, pub = target.generate() - ecdsa = ECDSA_SHA1(copy(mult), params, mult.formulas["add"], - pub.to_model(params.curve.coordinate_model, params.curve), priv) +@pytest.mark.parametrize( + "mult_class,mult_name,formulas,mult_kwargs", + [ + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": False}), + (LTRMultiplier, "ltr", ["add-1998-cmo", "dbl-1998-cmo"], {"complete": True}), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": False, "always": True}, + ), + ( + LTRMultiplier, + "ltr", + ["add-1998-cmo", "dbl-1998-cmo"], + {"complete": True, "always": True}, + ), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": False}), + (RTLMultiplier, "rtl", ["add-1998-cmo", "dbl-1998-cmo"], {"always": True}), + (CoronMultiplier, "coron", ["add-1998-cmo", "dbl-1998-cmo"], {}), + (BinaryNAFMultiplier, "bnaf", ["add-1998-cmo", "dbl-1998-cmo", "neg"], {}), + ], +) +def test_ecdsa(mult_class, mult_name, mult_kwargs, formulas, cli_runner, secp128r1): + data = b"something" - signature_data = target.ecdsa_sign(data) - result = SignatureResult.from_DER(signature_data) - self.assertTrue(ecdsa.verify_data(result, data)) + def callback(target, mult, params): + priv, pub = target.generate() + ecdsa = ECDSA_SHA1( + copy(mult), + params, + mult.formulas["add"], + pub.to_model(params.curve.coordinate_model, params.curve), + priv, + ) - expected = ecdsa.sign_data(data).to_DER() - self.assertTrue(target.ecdsa_verify(data, expected)) + signature_data = target.ecdsa_sign(data) + result = SignatureResult.from_DER(signature_data) + assert ecdsa.verify_data(result, data) - self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, True, - False, **mult_kwargs) + expected = ecdsa.sign_data(data).to_DER() + assert target.ecdsa_verify(data, expected) - def test_ltr(self): - runner = CliRunner() - self.do_ecdsa_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False) - self.do_ecdsa_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True) - self.do_ecdsa_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=False, always=True) - self.do_ecdsa_test(runner, self.secp128r1, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], - "ltr", complete=True, always=True)
\ No newline at end of file + do_basic_test( + callback, + cli_runner, + secp128r1, + mult_class, + formulas, + mult_name, + True, + False, + **mult_kwargs, + ) |
