diff --git a/include/boost/crypt2/drbg/detail/hash_drbg.hpp b/include/boost/crypt2/drbg/detail/hash_drbg.hpp index a2b8a00e..285f769b 100644 --- a/include/boost/crypt2/drbg/detail/hash_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hash_drbg.hpp @@ -68,11 +68,11 @@ class hash_drbg compat::uint64_t reseed_counter_ {}; bool initialized_ {}; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hash_df(compat::uint32_t no_of_bits_to_return, compat::span return_container, compat::span provided_data_1, @@ -80,17 +80,17 @@ class hash_drbg compat::span provided_data_3 = compat::span {}, compat::span provided_data_4 = compat::span {}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hashgen(compat::span returned_bits, compat::size_t requested_number_of_bytes) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto no_pr_generate_impl(compat::span return_data, compat::size_t requested_bits, compat::span additional_data = compat::span {}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pr_generate_impl(compat::span return_data, compat::size_t requested_bits, compat::span entropy, compat::span additional_data = compat::span {}) noexcept -> state; @@ -100,43 +100,43 @@ class hash_drbg BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hash_drbg() noexcept; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span entropy, - compat::span nonce = compat::span{}, - compat::span personalization = compat::span{}) noexcept -> state; + compat::span nonce = compat::span{}, + compat::span personalization = compat::span{}) noexcept -> state; template > + concepts::sized_range SizedRange3 = compat::span> BOOST_CRYPT_GPU_ENABLED auto init(SizedRange1&& entropy, - SizedRange2&& nonce = compat::array {}, - SizedRange3&& personalization = compat::array {}) noexcept -> state; + SizedRange2&& nonce = compat::span {}, + SizedRange3&& personalization = compat::span {}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto reseed(compat::span entropy, - compat::span additional_input = compat::span{}) noexcept -> state; + compat::span additional_input = compat::span{}) noexcept -> state; template > + concepts::sized_range SizedRange2 = compat::span> BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, - SizedRange2&& additional_input = compat::array {}) noexcept -> state; + SizedRange2&& additional_input = compat::span {}) noexcept -> state; template + compat::size_t Extent2 = 0U, + compat::size_t Extent3 = 0U> BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto generate(compat::span return_data, compat::size_t requested_bits, compat::span additional_data1 = compat::span {}, [[maybe_unused]] compat::span additional_data2 = compat::span {}) noexcept -> state; template , - concepts::sized_range SizedRange3 = compat::array> + concepts::sized_range SizedRange2 = compat::span, + concepts::sized_range SizedRange3 = compat::span> BOOST_CRYPT_GPU_ENABLED auto generate(SizedRange1&& return_data, compat::size_t requested_bits, - SizedRange2&& additional_data1 = compat::array{}, - [[maybe_unused]] SizedRange3&& additional_data2 = compat::array{}) noexcept -> state; + SizedRange2&& additional_data1 = compat::span{}, + [[maybe_unused]] SizedRange3&& additional_data2 = compat::span{}) noexcept -> state; }; template @@ -241,7 +241,7 @@ hash_drbg::hashg } auto data {value_}; - const auto data_span {compat::span(data)}; + const auto data_span {compat::span(data)}; compat::size_t offset {}; HasherType hasher; while (offset < requested_number_of_bytes) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index ca3ea589..8a7c985a 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -94,7 +94,7 @@ class hmac_drbg SizedRange2&& nonce = compat::span{}, SizedRange3&& personalization = compat::span{}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto reseed(compat::span entropy, compat::span additional_input = compat::span{}) noexcept -> state; @@ -103,7 +103,7 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, SizedRange2&& additional_data = compat::span{}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto generate(compat::span return_data, compat::size_t requested_bits, compat::span additional_data_1 = compat::span{}, compat::span additional_data_2 = compat::span{}) noexcept -> state; diff --git a/include/boost/crypt2/hash/detail/sha3_base.hpp b/include/boost/crypt2/hash/detail/sha3_base.hpp index 44b7f5fa..ccaf14e9 100644 --- a/include/boost/crypt2/hash/detail/sha3_base.hpp +++ b/include/boost/crypt2/hash/detail/sha3_base.hpp @@ -37,11 +37,11 @@ class sha3_base final { BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_message_block() noexcept -> void; - template + template [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span data) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto xof_digest_impl(compat::span data, compat::size_t amount) noexcept -> void; @@ -59,7 +59,7 @@ class sha3_base final { BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init() noexcept -> void; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span data) noexcept -> state; template @@ -74,7 +74,7 @@ class sha3_base final { [[nodiscard("Digest is the function return value")]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR compat::enable_if_t> get_digest() const noexcept; - template + template [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR compat::enable_if_t get_digest(compat::span data) const noexcept; @@ -87,7 +87,7 @@ class sha3_base final { [[nodiscard("Digest is the function return value")]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR compat::enable_if_t> get_digest() noexcept; - template + template [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR compat::enable_if_t get_digest(compat::span data) noexcept; @@ -95,7 +95,7 @@ class sha3_base final { [[nodiscard]] BOOST_CRYPT_GPU_ENABLED compat::enable_if_t get_digest(Range&& data) noexcept; - template + template [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR compat::enable_if_t get_digest(compat::span data, std::size_t amount) noexcept; diff --git a/include/boost/crypt2/mac/hmac.hpp b/include/boost/crypt2/mac/hmac.hpp index bf1c671d..628f896b 100644 --- a/include/boost/crypt2/mac/hmac.hpp +++ b/include/boost/crypt2/mac/hmac.hpp @@ -36,14 +36,14 @@ class hmac bool computed_ {false}; bool corrupted_ {false}; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init_impl(compat::span data) noexcept -> state; public: BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac() noexcept = default; - template + template explicit BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac(const compat::span key) noexcept { init(key); } BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hmac() noexcept; @@ -51,13 +51,13 @@ class hmac BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init_from_keys(const key_type& inner_key, const key_type& outer_key) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span data) noexcept -> state; template BOOST_CRYPT_GPU_ENABLED auto init(SizedRange&& data) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto process_bytes(compat::span data) noexcept -> state; template @@ -67,7 +67,7 @@ class hmac [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest() const noexcept -> compat::expected; - template + template [[nodiscard]] BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto get_digest(compat::span data) const noexcept -> state; diff --git a/test/test_hash_drbg.cpp b/test/test_hash_drbg.cpp index e9d44fea..2dd8c6c7 100644 --- a/test/test_hash_drbg.cpp +++ b/test/test_hash_drbg.cpp @@ -455,6 +455,99 @@ void sha1_error_cases() BOOST_TEST(pr_rng.generate(bad_return_container, 1, entropy, nonce) == boost::crypt::state::uninitialized); } +consteval bool immediate_test() +{ + boost::crypt::sha1_hash_drbg rng; + + constexpr std::array entropy = { + std::byte{0xc3}, std::byte{0xef}, std::byte{0x82}, std::byte{0xce}, + std::byte{0x24}, std::byte{0x1f}, std::byte{0x02}, std::byte{0xe4}, + std::byte{0x29}, std::byte{0x8b}, std::byte{0x11}, std::byte{0x8c}, + std::byte{0xa4}, std::byte{0xf1}, std::byte{0x62}, std::byte{0x25} + }; + + constexpr std::array nonce = { + std::byte{0x15}, std::byte{0xe3}, std::byte{0x2a}, std::byte{0xbb}, + std::byte{0xae}, std::byte{0x6b}, std::byte{0x74}, std::byte{0x33} + }; + + constexpr std::array additional_input_1 = { + std::byte{0x2b}, std::byte{0x79}, std::byte{0x00}, std::byte{0x52}, + std::byte{0xf0}, std::byte{0x9b}, std::byte{0x36}, std::byte{0x4d}, + std::byte{0x4a}, std::byte{0x82}, std::byte{0x67}, std::byte{0xa0}, + std::byte{0xa7}, std::byte{0xde}, std::byte{0x63}, std::byte{0xb8} + }; + + constexpr std::array additional_input_2 = { + std::byte{0x2e}, std::byte{0xe0}, std::byte{0x81}, std::byte{0x9a}, + std::byte{0x67}, std::byte{0x1d}, std::byte{0x07}, std::byte{0xb5}, + std::byte{0x08}, std::byte{0x5c}, std::byte{0xc4}, std::byte{0x6a}, + std::byte{0xa0}, std::byte{0xe6}, std::byte{0x1b}, std::byte{0x56} + }; + + std::span entropy_span {entropy}; + std::span nonce_span {nonce}; + std::span additional_input_1_span {additional_input_1}; + std::span additional_input_2_span {additional_input_2}; + + std::array return_bits {}; + std::span return_bit_span {return_bits}; + + // Test process is: + // 1) Instantiate drbg + // 2) Generate bits, do not compare + // 3) Generate bits, compare + // 4) Destroy drbg + rng.init(entropy_span, nonce_span); + // ** INSTANTIATE: + // V = 062e928dbf6ef8f7b57467a2a956f4754b094b5f5a9515fe0059a35d449b74485eac06f0671eaa6ec313fc52da015f69b18cc670d9e89a + // C = 0fb2fcface8fe5876199565b26d3db365037da40291d67915426959d90c8beba18e3dd1961b48a1ac62b0150cdefa5dc077daf27b4cf3e + + rng.generate(return_bit_span, 640U, additional_input_1_span); + // ** GENERATE (FIRST CALL): + // V = 15e18f888dfede7f170dbdfdd02acfab9b41259f83b27d8f548038fad5643302778fe466a1b0a63b22b39b4c59a4b7f151bec718d08a16 + // C = 0fb2fcface8fe5876199565b26d3db365037da40291d67915426959d90c8beba18e3dd1961b48a1ac62b0150cdefa5dc077daf27b4cf3e + + rng.generate(return_bit_span, 640U, additional_input_2_span); + // ** GENERATE (SECOND CALL): + // V = 25948c835c8ec40678a71458f6feaae1eb78ffdfaccfe520a8a6ce98662cf1bc9073c28d8664f953ae0352e0b5a7ecc5577d08a0babfc3 + // C = 0fb2fcface8fe5876199565b26d3db365037da40291d67915426959d90c8beba18e3dd1961b48a1ac62b0150cdefa5dc077daf27b4cf3e + + + constexpr std::array nist_return = { + std::byte{0x58}, std::byte{0x25}, std::byte{0xfa}, std::byte{0x1d}, + std::byte{0x1d}, std::byte{0xc3}, std::byte{0x3c}, std::byte{0x64}, + std::byte{0xcd}, std::byte{0xc8}, std::byte{0x69}, std::byte{0x06}, + std::byte{0x82}, std::byte{0xef}, std::byte{0xf0}, std::byte{0x60}, + std::byte{0x39}, std::byte{0xe7}, std::byte{0x95}, std::byte{0x08}, + std::byte{0xc3}, std::byte{0xaf}, std::byte{0x48}, std::byte{0xe8}, + std::byte{0x80}, std::byte{0xf8}, std::byte{0x22}, std::byte{0x7d}, + std::byte{0x5f}, std::byte{0x9a}, std::byte{0xaa}, std::byte{0x14}, + std::byte{0xb3}, std::byte{0xbc}, std::byte{0x76}, std::byte{0xba}, + std::byte{0xee}, std::byte{0x47}, std::byte{0x7e}, std::byte{0xbb}, + std::byte{0xb5}, std::byte{0xc4}, std::byte{0x55}, std::byte{0x47}, + std::byte{0x13}, std::byte{0x41}, std::byte{0x79}, std::byte{0x22}, + std::byte{0x32}, std::byte{0x57}, std::byte{0x52}, std::byte{0x5e}, + std::byte{0x8f}, std::byte{0x3a}, std::byte{0xfe}, std::byte{0xfb}, + std::byte{0x78}, std::byte{0xb5}, std::byte{0x9d}, std::byte{0xa0}, + std::byte{0x32}, std::byte{0xf1}, std::byte{0x00}, std::byte{0x6d}, + std::byte{0x74}, std::byte{0xc9}, std::byte{0x83}, std::byte{0x13}, + std::byte{0x75}, std::byte{0xa6}, std::byte{0x77}, std::byte{0xea}, + std::byte{0xb3}, std::byte{0x23}, std::byte{0x9c}, std::byte{0x94}, + std::byte{0xeb}, std::byte{0xe3}, std::byte{0xf7}, std::byte{0xfa} + }; + + for (std::size_t i {}; i < return_bits.size(); ++i) + { + if (!(return_bits[i] == static_cast(nist_return[i]))) + { + return false; + } + } + + return true; +} + int main() { sha_1_basic_correctness(); @@ -465,5 +558,7 @@ int main() sha1_no_reseed_additional_input(); sha1_error_cases(); + static_assert(immediate_test()); + return boost::report_errors(); } diff --git a/test/test_hmac_drbg.cpp b/test/test_hmac_drbg.cpp index 406b150d..c641093d 100644 --- a/test/test_hmac_drbg.cpp +++ b/test/test_hmac_drbg.cpp @@ -4,7 +4,9 @@ #include #include +#include #include +#include #include #include @@ -209,6 +211,65 @@ void error_states() BOOST_TEST(rng.reseed(bad_return) == boost::crypt::state::insufficient_entropy); } +template +consteval bool immediate_test() +{ + boost::crypt::sha1_hmac_drbg rng; + constexpr std::array entropy = { + std::byte{0x49}, std::byte{0x05}, std::byte{0x8e}, std::byte{0x67}, std::byte{0x73}, std::byte{0xed}, std::byte{0x2b}, std::byte{0x7a}, + std::byte{0xb3}, std::byte{0x09}, std::byte{0xc0}, std::byte{0x94}, std::byte{0x9f}, std::byte{0xdf}, std::byte{0x9c}, std::byte{0x9e} + }; + constexpr std::array nonce = { + std::byte{0xa4}, std::byte{0x57}, std::byte{0xcb}, std::byte{0x8e}, std::byte{0xc0}, std::byte{0xe7}, std::byte{0xfd}, std::byte{0x01} + }; + constexpr std::array personalization = { + std::byte{0xdc}, std::byte{0x47}, std::byte{0x76}, std::byte{0x41}, std::byte{0xd8}, std::byte{0x9c}, std::byte{0x7f}, std::byte{0xc4}, std::byte{0xa3}, std::byte{0x0f}, std::byte{0x14}, std::byte{0x30}, std::byte{0x19}, std::byte{0x7d}, std::byte{0xd1}, std::byte{0x59} + }; + + std::span entropy_span {entropy}; + std::span nonce_span {nonce}; + std::span personalization_span {personalization}; + + rng.init(entropy_span, nonce_span, personalization_span); + // ** INSTANTIATE: + // V = 9c530ef5f1e277aab4e1e129091a273f0342d5c9 + // Key = 7006c1c0c03c4ca267b19c50928f35891d8d8807 + + std::array return_bits {}; + std::span return_span {return_bits}; + + rng.generate(return_span, 640U); + // ** GENERATE (FIRST CALL): + // V = 5b1508d16daad5aff52273cd549ce6bd9e259b0d + // Key = b7e28116a16856b9e81bda776d421bb56e8f902f + + rng.generate(return_span, return_bits.size() * 8U); + // ** GENERATE (SECOND CALL): + // V = 71fa823bc53bfd307d6438edd7e5c581fffc27cc + // Key = cfccf80b126cea770b468fb8652abbd5eeea2a5e + + constexpr std::array nist_return = { + std::byte{0x4e}, std::byte{0x89}, std::byte{0x1f}, std::byte{0x4e}, std::byte{0x28}, std::byte{0x11}, std::byte{0x00}, std::byte{0x45}, std::byte{0x3b}, std::byte{0x70}, std::byte{0x78}, + std::byte{0x89}, std::byte{0x29}, std::byte{0xec}, std::byte{0x74}, std::byte{0x3a}, std::byte{0x3c}, std::byte{0x5e}, std::byte{0xdd}, std::byte{0x9b}, std::byte{0x81}, std::byte{0xdc}, + std::byte{0x79}, std::byte{0x8b}, std::byte{0xc9}, std::byte{0x37}, std::byte{0x71}, std::byte{0x36}, std::byte{0x8c}, std::byte{0x39}, std::byte{0xb6}, std::byte{0x12}, std::byte{0x03}, + std::byte{0x7b}, std::byte{0x6f}, std::byte{0x42}, std::byte{0xf6}, std::byte{0x0c}, std::byte{0x5d}, std::byte{0x89}, std::byte{0x24}, std::byte{0xb6}, std::byte{0x46}, std::byte{0x84}, + std::byte{0x81}, std::byte{0x51}, std::byte{0xb0}, std::byte{0xc2}, std::byte{0x95}, std::byte{0xbe}, std::byte{0x49}, std::byte{0x1d}, std::byte{0x4a}, std::byte{0x28}, std::byte{0xd1}, + std::byte{0x92}, std::byte{0x7d}, std::byte{0xee}, std::byte{0xd5}, std::byte{0x23}, std::byte{0xfd}, std::byte{0x04}, std::byte{0xd3}, std::byte{0xd2}, std::byte{0xdd}, std::byte{0xa9}, + std::byte{0x5e}, std::byte{0xd4}, std::byte{0x21}, std::byte{0x66}, std::byte{0x31}, std::byte{0x2e}, std::byte{0x5c}, std::byte{0x33}, std::byte{0x92}, std::byte{0xd2}, std::byte{0x28}, + std::byte{0x93}, std::byte{0xb0}, std::byte{0xdc} + }; + + for (std::size_t i {}; i < return_bits.size(); ++i) + { + if (!(return_bits[i] == static_cast(nist_return[i]))) + { + return false; + } + } + + return true; +} + int main() { sha1_basic_correctness(); @@ -218,5 +279,7 @@ int main() error_states(); error_states(); + static_assert(immediate_test()); + return boost::report_errors(); }