• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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