diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/test_impl.py | 2 | ||||
| -rw-r--r-- | test/test_simulator.py | 194 |
2 files changed, 195 insertions, 1 deletions
diff --git a/test/test_impl.py b/test/test_impl.py index ea92f8a..b054567 100644 --- a/test/test_impl.py +++ b/test/test_impl.py @@ -255,4 +255,4 @@ class ECDSATests(ImplTests): 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) + "ltr", complete=True, always=True)
\ No newline at end of file diff --git a/test/test_simulator.py b/test/test_simulator.py new file mode 100644 index 0000000..d741cf4 --- /dev/null +++ b/test/test_simulator.py @@ -0,0 +1,194 @@ +from copy import copy +from os.path import join +from unittest import TestCase + +from click.testing import CliRunner +from pyecsca.ec.key_agreement import ECDH_SHA1 +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 SimulatorTarget + +from pyecsca.ec.curve import EllipticCurve +from pyecsca.ec.mod import Mod +from pyecsca.ec.model import ShortWeierstrassModel +from pyecsca.ec.params import DomainParameters +from pyecsca.ec.point import InfinityPoint, Point +import gc + + +class SimulatorTest(TestCase): + + def setUp(self): + model = ShortWeierstrassModel() + coords = model.coordinates["projective"] + p = 0xd7d1247f + a = Mod(0xa4a44016, p) + b = Mod(0x73f76716, p) + n = 0xd7d2a475 + h = 1 + gx, gy, gz = Mod(0x54eed6d7, p), Mod(0x6f1e55ac, p), Mod(1, p) + generator = Point(coords, X=gx, Y=gy, Z=gz) + neutral = InfinityPoint(coords) + + curve = EllipticCurve(model, coords, p, neutral, {"a": a, "b": b}) + self.curve32 = DomainParameters(curve, generator, n, h) + self.base = self.curve32.generator + self.coords = self.curve32.curve.coordinate_model + + def do_basic_test(self, callback, runner, params, mult_class, formulas, mult_name, + ecdsa, ecdh): + with runner.isolated_filesystem() as tmpdir: + runner.invoke(build_impl, + ["--platform", "STM32F3", + "--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}()", + "."]) + target = SimulatorTarget(params.curve.model, params.curve.coordinate_model) + target.connect(binary=join(tmpdir, "pyecsca-codegen-CW308_STM32F3.elf")) + target.set_params(params) + formula_instances = [params.curve.coordinate_model.formulas[formula] for formula + in formulas] + mult = mult_class(*formula_instances) + mult.init(params, params.generator) + callback(target, mult, params) + target.disconnect() + del target + gc.collect() + + +class PRNGTests(SimulatorTest): + + def test_init(self): + runner = CliRunner() + + def callback(target, mult, params): + target.init_prng(bytes([0x12, 0x34, 0x56, 0x78])) + + self.do_basic_test(callback, runner, self.curve32, LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False) + + +class SetupTests(SimulatorTest): + + 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.curve32, LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, 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.curve32, LTRMultiplier, + ["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False) + + +class KeyGenerationTests(SimulatorTest): + + def do_keygen_test(self, runner, params, mult_class, formulas, mult_name): + def callback(target, mult, params): + 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) + + def test_ltr(self): + runner = CliRunner() + self.do_keygen_test(runner, self.curve32, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "ltr") + + def test_rtl(self): + runner = CliRunner() + self.do_keygen_test(runner, self.curve32, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "rtl") + + +class ScalarMultiplicationTests(SimulatorTest): + + def do_mult_test(self, runner, params, mult_class, formulas, mult_name): + values = [2355498743] + + def callback(target, mult, params): + for value in values: + result = target.scalar_mult(value, params.generator) + expected = mult.multiply(value) + self.assertEqual(result, expected) + + self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, False, False) + + def test_ltr(self): + runner = CliRunner() + self.do_mult_test(runner, self.curve32, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "ltr") + + def test_rtl(self): + runner = CliRunner() + self.do_mult_test(runner, self.curve32, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "rtl") + + +class ECDHTests(SimulatorTest): + def do_ecdh_test(self, runner, params, mult_class, formulas, mult_name): + other_privs = [2355498743] + + 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) + + def test_ltr(self): + runner = CliRunner() + self.do_ecdh_test(runner, self.curve32, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "ltr") + + def test_rtl(self): + runner = CliRunner() + self.do_ecdh_test(runner, self.curve32, RTLMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], + "rtl") + + +class ECDSATests(SimulatorTest): + def do_ecdsa_test(self, runner, params, mult_class, formulas, mult_name): + 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) + + signature_data = target.ecdsa_sign(data) + result = SignatureResult.from_DER(bytes(signature_data)) + self.assertTrue(ecdsa.verify_data(result, data)) + + expected = ecdsa.sign_data(data).to_DER() + self.assertTrue(target.ecdsa_verify(data, expected)) + + self.do_basic_test(callback, runner, params, mult_class, formulas, mult_name, True, False) + + def test_ltr(self): + runner = CliRunner() + self.do_ecdsa_test(runner, self.curve32, LTRMultiplier, ["add-1998-cmo", "dbl-1998-cmo"], "ltr")
\ No newline at end of file |
