1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7import binascii 8 9import pytest 10 11from cryptography.exceptions import UnsupportedAlgorithm 12from cryptography.hazmat.backends.interfaces import EllipticCurveBackend 13from cryptography.hazmat.primitives import serialization 14from cryptography.hazmat.primitives.asymmetric import ec 15 16from ..hazmat.primitives.test_ec import _skip_exchange_algorithm_unsupported 17 18 19_CURVES = { 20 "secp224r1": ec.SECP224R1(), 21 "secp256r1": ec.SECP256R1(), 22 "secp384r1": ec.SECP384R1(), 23 "secp521r1": ec.SECP521R1(), 24 "secp224k1": None, 25 "secp256k1": ec.SECP256K1(), 26 "brainpoolP224r1": None, 27 "brainpoolP256r1": ec.BrainpoolP256R1(), 28 "brainpoolP320r1": None, 29 "brainpoolP384r1": ec.BrainpoolP384R1(), 30 "brainpoolP512r1": ec.BrainpoolP512R1(), 31 "brainpoolP224t1": None, 32 "brainpoolP256t1": None, 33 "brainpoolP320t1": None, 34 "brainpoolP384t1": None, 35 "brainpoolP512t1": None, 36} 37 38 39@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 40@pytest.mark.wycheproof_tests( 41 "ecdh_test.json", 42 "ecdh_brainpoolP224r1_test.json", 43 "ecdh_brainpoolP256r1_test.json", 44 "ecdh_brainpoolP320r1_test.json", 45 "ecdh_brainpoolP384r1_test.json", 46 "ecdh_brainpoolP512r1_test.json", 47 "ecdh_secp224r1_test.json", 48 "ecdh_secp256k1_test.json", 49 "ecdh_secp256r1_test.json", 50 "ecdh_secp384r1_test.json", 51 "ecdh_secp521r1_test.json", 52) 53def test_ecdh(backend, wycheproof): 54 curve = _CURVES[wycheproof.testgroup["curve"]] 55 if curve is None: 56 pytest.skip( 57 "Unsupported curve ({})".format(wycheproof.testgroup["curve"]) 58 ) 59 _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) 60 61 private_key = ec.derive_private_key( 62 int(wycheproof.testcase["private"], 16), curve, backend 63 ) 64 65 try: 66 public_key = serialization.load_der_public_key( 67 binascii.unhexlify(wycheproof.testcase["public"]), backend 68 ) 69 except NotImplementedError: 70 assert wycheproof.has_flag("UnnamedCurve") 71 return 72 except ValueError: 73 assert wycheproof.invalid or wycheproof.acceptable 74 return 75 except UnsupportedAlgorithm: 76 return 77 78 if wycheproof.valid or wycheproof.acceptable: 79 computed_shared = private_key.exchange(ec.ECDH(), public_key) 80 expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) 81 assert computed_shared == expected_shared 82 else: 83 with pytest.raises(ValueError): 84 private_key.exchange(ec.ECDH(), public_key) 85 86 87@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 88@pytest.mark.wycheproof_tests( 89 "ecdh_secp224r1_ecpoint_test.json", 90 "ecdh_secp256r1_ecpoint_test.json", 91 "ecdh_secp384r1_ecpoint_test.json", 92 "ecdh_secp521r1_ecpoint_test.json", 93) 94def test_ecdh_ecpoint(backend, wycheproof): 95 curve = _CURVES[wycheproof.testgroup["curve"]] 96 _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) 97 98 private_key = ec.derive_private_key( 99 int(wycheproof.testcase["private"], 16), curve, backend 100 ) 101 102 if wycheproof.invalid: 103 with pytest.raises(ValueError): 104 ec.EllipticCurvePublicKey.from_encoded_point( 105 curve, binascii.unhexlify(wycheproof.testcase["public"]) 106 ) 107 return 108 109 assert wycheproof.valid or wycheproof.acceptable 110 public_key = ec.EllipticCurvePublicKey.from_encoded_point( 111 curve, binascii.unhexlify(wycheproof.testcase["public"]) 112 ) 113 computed_shared = private_key.exchange(ec.ECDH(), public_key) 114 expected_shared = binascii.unhexlify(wycheproof.testcase["shared"]) 115 assert computed_shared == expected_shared 116