diff options
Diffstat (limited to 'tests/primitives')
-rw-r--r-- | tests/primitives/test_hash_vectors.py | 111 | ||||
-rw-r--r-- | tests/primitives/test_hashes.py | 78 | ||||
-rw-r--r-- | tests/primitives/test_utils.py | 36 | ||||
-rw-r--r-- | tests/primitives/utils.py | 78 |
4 files changed, 302 insertions, 1 deletions
diff --git a/tests/primitives/test_hash_vectors.py b/tests/primitives/test_hash_vectors.py new file mode 100644 index 00000000..51c4b85d --- /dev/null +++ b/tests/primitives/test_hash_vectors.py @@ -0,0 +1,111 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import os + +from cryptography.primitives import hashes + +from .utils import generate_hash_test, generate_long_string_hash_test +from ..utils import load_hash_vectors_from_file + + +class TestSHA1(object): + test_SHA1 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("NIST", "SHABYTE"), + [ + "SHA1LongMsg.rsp", + "SHA1ShortMsg.rsp", + ], + hashes.SHA1, + only_if=lambda api: api.supports_hash(hashes.SHA1), + skip_message="Does not support SHA1", + ) + + +class TestSHA224(object): + test_SHA224 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("NIST", "SHABYTE"), + [ + "SHA224LongMsg.rsp", + "SHA224ShortMsg.rsp", + ], + hashes.SHA224, + only_if=lambda api: api.supports_hash(hashes.SHA224), + skip_message="Does not support SHA224", + ) + + +class TestSHA256(object): + test_SHA256 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("NIST", "SHABYTE"), + [ + "SHA256LongMsg.rsp", + "SHA256ShortMsg.rsp", + ], + hashes.SHA256, + only_if=lambda api: api.supports_hash(hashes.SHA256), + skip_message="Does not support SHA256", + ) + + +class TestSHA384(object): + test_SHA384 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("NIST", "SHABYTE"), + [ + "SHA384LongMsg.rsp", + "SHA384ShortMsg.rsp", + ], + hashes.SHA384, + only_if=lambda api: api.supports_hash(hashes.SHA384), + skip_message="Does not support SHA384", + ) + + +class TestSHA512(object): + test_SHA512 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("NIST", "SHABYTE"), + [ + "SHA512LongMsg.rsp", + "SHA512ShortMsg.rsp", + ], + hashes.SHA512, + only_if=lambda api: api.supports_hash(hashes.SHA512), + skip_message="Does not support SHA512", + ) + + +class TestRIPEMD160(object): + test_RIPEMD160 = generate_hash_test( + load_hash_vectors_from_file, + os.path.join("ISO", "ripemd160"), + [ + "ripevectors.txt", + ], + hashes.RIPEMD160, + only_if=lambda api: api.supports_hash(hashes.RIPEMD160), + skip_message="Does not support RIPEMD160", + ) + + test_RIPEMD160_long_string = generate_long_string_hash_test( + hashes.RIPEMD160, + "52783243c1697bdbe16d37f97f68f08325dc1528", + only_if=lambda api: api.supports_hash(hashes.RIPEMD160), + skip_message="Does not support RIPEMD160", + ) diff --git a/tests/primitives/test_hashes.py b/tests/primitives/test_hashes.py new file mode 100644 index 00000000..bfb45037 --- /dev/null +++ b/tests/primitives/test_hashes.py @@ -0,0 +1,78 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography.primitives import hashes + +from .utils import generate_base_hash_test + + +class TestSHA1(object): + test_SHA1 = generate_base_hash_test( + hashes.SHA1, + digest_size=20, + block_size=64, + only_if=lambda api: api.supports_hash(hashes.SHA1), + skip_message="Does not support SHA1", + ) + + +class TestSHA224(object): + test_SHA224 = generate_base_hash_test( + hashes.SHA224, + digest_size=28, + block_size=64, + only_if=lambda api: api.supports_hash(hashes.SHA224), + skip_message="Does not support SHA224", + ) + + +class TestSHA256(object): + test_SHA256 = generate_base_hash_test( + hashes.SHA256, + digest_size=32, + block_size=64, + only_if=lambda api: api.supports_hash(hashes.SHA256), + skip_message="Does not support SHA256", + ) + + +class TestSHA384(object): + test_SHA384 = generate_base_hash_test( + hashes.SHA384, + digest_size=48, + block_size=128, + only_if=lambda api: api.supports_hash(hashes.SHA384), + skip_message="Does not support SHA384", + ) + + +class TestSHA512(object): + test_SHA512 = generate_base_hash_test( + hashes.SHA512, + digest_size=64, + block_size=128, + only_if=lambda api: api.supports_hash(hashes.SHA512), + skip_message="Does not support SHA512", + ) + + +class TestRIPEMD160(object): + test_RIPEMD160 = generate_base_hash_test( + hashes.RIPEMD160, + digest_size=20, + block_size=64, + only_if=lambda api: api.supports_hash(hashes.RIPEMD160), + skip_message="Does not support RIPEMD160", + ) diff --git a/tests/primitives/test_utils.py b/tests/primitives/test_utils.py index 4666ece7..9888309e 100644 --- a/tests/primitives/test_utils.py +++ b/tests/primitives/test_utils.py @@ -1,6 +1,7 @@ import pytest -from .utils import encrypt_test +from .utils import (base_hash_test, encrypt_test, hash_test, + long_string_hash_test) class TestEncryptTest(object): @@ -12,3 +13,36 @@ class TestEncryptTest(object): skip_message="message!" ) assert exc_info.value.args[0] == "message!" + + +class TestHashTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + hash_test( + None, None, None, + only_if=lambda api: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" + + +class TestBaseHashTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + base_hash_test( + None, None, None, None, + only_if=lambda api: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" + + +class TestLongHashTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + long_string_hash_test( + None, None, None, + only_if=lambda api: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" diff --git a/tests/primitives/utils.py b/tests/primitives/utils.py index 3cf08c28..8b32700b 100644 --- a/tests/primitives/utils.py +++ b/tests/primitives/utils.py @@ -40,3 +40,81 @@ def encrypt_test(api, cipher_factory, mode_factory, params, only_if, actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() assert actual_ciphertext == binascii.unhexlify(ciphertext) + + +def generate_hash_test(param_loader, path, file_names, hash_cls, + only_if=lambda api: True, skip_message=None): + def test_hash(self): + for api in _ALL_APIS: + for file_name in file_names: + for params in param_loader(os.path.join(path, file_name)): + yield ( + hash_test, + api, + hash_cls, + params, + only_if, + skip_message + ) + return test_hash + + +def hash_test(api, hash_cls, params, only_if, skip_message): + if not only_if(api): + pytest.skip(skip_message) + msg = params[0] + md = params[1] + m = hash_cls(api=api) + m.update(binascii.unhexlify(msg)) + assert m.hexdigest() == md.replace(" ", "").lower() + + +def generate_base_hash_test(hash_cls, digest_size, block_size, + only_if=lambda api: True, skip_message=None): + def test_base_hash(self): + for api in _ALL_APIS: + yield ( + base_hash_test, + api, + hash_cls, + digest_size, + block_size, + only_if, + skip_message, + ) + return test_base_hash + + +def base_hash_test(api, hash_cls, digest_size, block_size, only_if, + skip_message): + if not only_if(api): + pytest.skip(skip_message) + m = hash_cls(api=api) + assert m.digest_size == digest_size + assert m.block_size == block_size + m_copy = m.copy() + assert m != m_copy + assert m._ctx != m_copy._ctx + + +def generate_long_string_hash_test(hash_factory, md, only_if=lambda api: True, + skip_message=None): + def test_long_string_hash(self): + for api in _ALL_APIS: + yield( + long_string_hash_test, + api, + hash_factory, + md, + only_if, + skip_message + ) + return test_long_string_hash + + +def long_string_hash_test(api, hash_factory, md, only_if, skip_message): + if not only_if(api): + pytest.skip(skip_message) + m = hash_factory(api) + m.update(b"a" * 1000000) + assert m.hexdigest() == md.lower() |