aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hazmat/primitives/test_x448.py
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2018-11-23 10:44:37 +0800
committerAlex Gaynor <alex.gaynor@gmail.com>2018-11-22 20:44:37 -0600
commit6f88e01af8f5d6db7082d155f3faf88dfb48e864 (patch)
tree42fb14caa9d24a6eca1ae9d07b69a4a502e5c200 /tests/hazmat/primitives/test_x448.py
parent579dfcf48f013dddfd3447e6dc38cfdc0b17145c (diff)
downloadcryptography-6f88e01af8f5d6db7082d155f3faf88dfb48e864.tar.gz
cryptography-6f88e01af8f5d6db7082d155f3faf88dfb48e864.tar.bz2
cryptography-6f88e01af8f5d6db7082d155f3faf88dfb48e864.zip
X448 support (#4580)
* x448 support This work was originally authored by derwolfe * update docs to have a more useful derived key length * error if key is not a valid length in from_public_bytes * one more * switch to using evp_pkey_keygen_gc for x448 keygen * review feedback * switch to using evp_pkey_derive * nit fix
Diffstat (limited to 'tests/hazmat/primitives/test_x448.py')
-rw-r--r--tests/hazmat/primitives/test_x448.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py
new file mode 100644
index 00000000..71b25341
--- /dev/null
+++ b/tests/hazmat/primitives/test_x448.py
@@ -0,0 +1,127 @@
+# 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 os
+
+import pytest
+
+from cryptography.exceptions import _Reasons
+from cryptography.hazmat.backends.interfaces import DHBackend
+from cryptography.hazmat.primitives.asymmetric.x448 import (
+ X448PrivateKey, X448PublicKey
+)
+
+from ...utils import (
+ load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm
+)
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: not backend.x448_supported(),
+ skip_message="Requires OpenSSL without X448 support"
+)
+@pytest.mark.requires_backend_interface(interface=DHBackend)
+def test_x448_unsupported(backend):
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
+ X448PublicKey.from_public_bytes(b"0" * 32)
+
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
+ X448PrivateKey.generate()
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.x448_supported(),
+ skip_message="Requires OpenSSL with X448 support"
+)
+@pytest.mark.requires_backend_interface(interface=DHBackend)
+class TestX448Exchange(object):
+ @pytest.mark.parametrize(
+ "vector",
+ load_vectors_from_file(
+ os.path.join("asymmetric", "X448", "rfc7748.txt"),
+ load_nist_vectors
+ )
+ )
+ def test_rfc7748(self, vector, backend):
+ private = binascii.unhexlify(vector["input_scalar"])
+ public = binascii.unhexlify(vector["input_u"])
+ shared_key = binascii.unhexlify(vector["output_u"])
+ private_key = X448PrivateKey._from_private_bytes(private)
+ public_key = X448PublicKey.from_public_bytes(public)
+ computed_shared_key = private_key.exchange(public_key)
+ assert computed_shared_key == shared_key
+
+ def test_rfc7748_1000_iteration(self, backend):
+ old_private = private = public = binascii.unhexlify(
+ b"05000000000000000000000000000000000000000000000000000000"
+ b"00000000000000000000000000000000000000000000000000000000"
+ )
+ shared_key = binascii.unhexlify(
+ b"aa3b4749d55b9daf1e5b00288826c467274ce3ebbdd5c17b975e09d4"
+ b"af6c67cf10d087202db88286e2b79fceea3ec353ef54faa26e219f38"
+ )
+ private_key = X448PrivateKey._from_private_bytes(private)
+ public_key = X448PublicKey.from_public_bytes(public)
+ for _ in range(1000):
+ computed_shared_key = private_key.exchange(public_key)
+ private_key = X448PrivateKey._from_private_bytes(
+ computed_shared_key
+ )
+ public_key = X448PublicKey.from_public_bytes(old_private)
+ old_private = computed_shared_key
+
+ assert computed_shared_key == shared_key
+
+ # These vectors are also from RFC 7748
+ # https://tools.ietf.org/html/rfc7748#section-6.2
+ @pytest.mark.parametrize(
+ ("private_bytes", "public_bytes"),
+ [
+ (
+ binascii.unhexlify(
+ b"9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28d"
+ b"d9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b"
+ ),
+ binascii.unhexlify(
+ b"9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c"
+ b"22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0"
+ )
+ ),
+ (
+ binascii.unhexlify(
+ b"1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d"
+ b"6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d"
+ ),
+ binascii.unhexlify(
+ b"3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b430"
+ b"27d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609"
+ )
+ )
+ ]
+ )
+ def test_public_bytes(self, private_bytes, public_bytes, backend):
+ private_key = X448PrivateKey._from_private_bytes(private_bytes)
+ assert private_key.public_key().public_bytes() == public_bytes
+ public_key = X448PublicKey.from_public_bytes(public_bytes)
+ assert public_key.public_bytes() == public_bytes
+
+ def test_generate(self, backend):
+ key = X448PrivateKey.generate()
+ assert key
+ assert key.public_key()
+
+ def test_invalid_type_exchange(self, backend):
+ key = X448PrivateKey.generate()
+ with pytest.raises(TypeError):
+ key.exchange(object())
+
+ def test_invalid_length_from_public_bytes(self, backend):
+ with pytest.raises(ValueError):
+ X448PublicKey.from_public_bytes(b"a" * 55)
+
+ with pytest.raises(ValueError):
+ X448PublicKey.from_public_bytes(b"a" * 57)