| # This file is dual licensed under the terms of the Apache License, Version |
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository |
| # for complete details. |
| |
| from __future__ import absolute_import, division, print_function |
| |
| import binascii |
| |
| import pytest |
| |
| from cryptography.exceptions import UnsupportedAlgorithm |
| from cryptography.hazmat.backends.interfaces import EllipticCurveBackend |
| from cryptography.hazmat.primitives import serialization |
| from cryptography.hazmat.primitives.asymmetric import ec |
| |
| from ..hazmat.primitives.test_ec import _skip_exchange_algorithm_unsupported |
| |
| |
| _CURVES = { |
| "secp224r1": ec.SECP224R1(), |
| "secp256r1": ec.SECP256R1(), |
| "secp384r1": ec.SECP384R1(), |
| "secp521r1": ec.SECP521R1(), |
| "secp256k1": ec.SECP256K1(), |
| "brainpoolP224r1": None, |
| "brainpoolP256r1": ec.BrainpoolP256R1(), |
| "brainpoolP320r1": None, |
| "brainpoolP384r1": ec.BrainpoolP384R1(), |
| "brainpoolP512r1": ec.BrainpoolP512R1(), |
| "brainpoolP224t1": None, |
| "brainpoolP256t1": None, |
| "brainpoolP320t1": None, |
| "brainpoolP384t1": None, |
| "brainpoolP512t1": None, |
| } |
| |
| |
| @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) |
| @pytest.mark.wycheproof_tests( |
| "ecdh_test.json", |
| "ecdh_brainpoolP224r1_test.json", |
| "ecdh_brainpoolP256r1_test.json", |
| "ecdh_brainpoolP320r1_test.json", |
| "ecdh_brainpoolP384r1_test.json", |
| "ecdh_brainpoolP512r1_test.json", |
| "ecdh_secp224r1_test.json", |
| "ecdh_secp256k1_test.json", |
| "ecdh_secp256r1_test.json", |
| "ecdh_secp384r1_test.json", |
| "ecdh_secp521r1_test.json", |
| ) |
| def test_ecdh(backend, wycheproof): |
| curve = _CURVES[wycheproof.testgroup["curve"]] |
| if curve is None: |
| pytest.skip( |
| "Unsupported curve ({})".format(wycheproof.testgroup["curve"]) |
| ) |
| _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) |
| |
| private_key = ec.derive_private_key( |
| int(wycheproof.testcase["private"], 16), curve, backend |
| ) |
| |
| try: |
| public_key = serialization.load_der_public_key( |
| binascii.unhexlify(wycheproof.testcase["public"]), backend |
| ) |
| except NotImplementedError: |
| assert wycheproof.has_flag("UnnamedCurve") |
| return |
| except ValueError: |
| assert wycheproof.invalid or wycheproof.acceptable |
| return |
| except UnsupportedAlgorithm: |
| return |
| |
| if wycheproof.valid or wycheproof.acceptable: |
| computed_shared = private_key.exchange(ec.ECDH(), public_key) |
| expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) |
| assert computed_shared == expected_shared |
| else: |
| with pytest.raises(ValueError): |
| private_key.exchange(ec.ECDH(), public_key) |
| |
| |
| @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) |
| @pytest.mark.wycheproof_tests( |
| "ecdh_secp224r1_ecpoint_test.json", |
| "ecdh_secp256r1_ecpoint_test.json", |
| "ecdh_secp384r1_ecpoint_test.json", |
| "ecdh_secp521r1_ecpoint_test.json", |
| ) |
| def test_ecdh_ecpoint(backend, wycheproof): |
| curve = _CURVES[wycheproof.testgroup["curve"]] |
| _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) |
| |
| private_key = ec.derive_private_key( |
| int(wycheproof.testcase["private"], 16), curve, backend |
| ) |
| |
| if wycheproof.invalid: |
| with pytest.raises(ValueError): |
| ec.EllipticCurvePublicKey.from_encoded_point( |
| curve, binascii.unhexlify(wycheproof.testcase["public"]) |
| ) |
| return |
| |
| assert wycheproof.valid or wycheproof.acceptable |
| public_key = ec.EllipticCurvePublicKey.from_encoded_point( |
| curve, binascii.unhexlify(wycheproof.testcase["public"]) |
| ) |
| computed_shared = private_key.exchange(ec.ECDH(), public_key) |
| expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) |
| assert computed_shared == expected_shared |