diff --git a/libs/hash/CMakeLists.txt b/libs/hash/CMakeLists.txt index d8ca9033f7..0b9d9ec9c7 100644 --- a/libs/hash/CMakeLists.txt +++ b/libs/hash/CMakeLists.txt @@ -92,6 +92,10 @@ if(CRYPTO3_HASH_SHA3) add_definitions(-D${CMAKE_UPPER_WORKSPACE_NAME}_HAS_SHA3) endif() +if(CRYPTO3_HASH_SHAKE) + add_definitions(-D${CMAKE_UPPER_WORKSPACE_NAME}_HAS_SHAKE) +endif() + if(CRYPTO3_HASH_TIGER) add_definitions(-D${CMAKE_UPPER_WORKSPACE_NAME}_HAS_TIGER) endif() diff --git a/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_functions.hpp b/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_functions.hpp index b7e503f469..e243ca0c08 100644 --- a/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_functions.hpp +++ b/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_functions.hpp @@ -54,9 +54,8 @@ namespace nil { namespace detail { template::value_type>::value>::type> + typename = typename std::enable_if< + std::is_same::value>::type> class expand_message_xmd { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1 static_assert(Hash::block_bits % 8 == 0, "r_in_bytes is not a multiple of 8"); @@ -136,6 +135,70 @@ namespace nil { return uniform_bytes; } }; + + template::value>::type> + class expand_message_xof { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.2 + static_assert(Hash::block_bits % 8 == 0, "r_in_bytes is not a multiple of 8"); + static_assert(Hash::digest_bits % 8 == 0, "b_in_bytes is not a multiple of 8"); + static_assert(Hash::digest_bits >= 2 * k, "k-bit collision resistance is not fulfilled"); + static_assert(len_in_bytes < 0x10000, "len_in_bytes should be less than 0x10000"); + static_assert(Hash::digest_bits == len_in_bytes * 8, "len_in_bytes should be equal to XOF digest length"); + + constexpr static std::size_t b_in_bytes = Hash::digest_bits / 8; + constexpr static std::array l_i_b_str = { + static_cast(len_in_bytes >> 8u), static_cast(len_in_bytes % 0x100)}; + constexpr static std::size_t ell = static_cast(len_in_bytes / b_in_bytes) + + static_cast(len_in_bytes % b_in_bytes != 0); + + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1 + static_assert(ell <= 255, "ell should be less than 256"); + + public: + typedef std::array result_type; + typedef accumulator_set internal_accumulator_type; + + static inline void init_accumulator(internal_accumulator_type &acc) { + + } + + template + static inline void update(internal_accumulator_type &acc, const InputRange &range) { + BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept)); + + hash(range, acc); + } + + template + static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) { + BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept)); + + hash(first, last, acc); + } + + template + static inline typename std::enable_if< + std::is_same::value_type>::value, + result_type>::type + process(internal_accumulator_type &b0_acc, const DstRange &dst) { + + auto dst_size = std::distance(std::cbegin(dst), std::cend(dst)); + assert(dst_size >= 16 && dst_size <= 255); + + hash(l_i_b_str, b0_acc); + hash(dst, b0_acc); + hash(std::array {static_cast(dst_size)}, b0_acc); + typename Hash::digest_type b0 = ::nil::crypto3::accumulators::extract::hash(b0_acc); + + result_type uniform_bytes; + std::copy(b0.begin(), b0.end(), uniform_bytes.begin()); + return uniform_bytes; + } + }; } // namespace detail } // namespace hashes } // namespace crypto3 diff --git a/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_suites.hpp b/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_suites.hpp index 65665f7f96..062c9d0103 100644 --- a/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_suites.hpp +++ b/libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_suites.hpp @@ -31,6 +31,8 @@ #include #include +#include +#include namespace nil { namespace crypto3 { @@ -74,8 +76,136 @@ namespace nil { /// L = ceil((ceil(log2(p)) + k) / 8) constexpr static std::size_t L = 64; }; + + template<> + struct h2f_suite, 128> { + typedef typename algebra::curves::bls12_381::base_field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef shake<128, 1024> hash_type; + + // BLS12381G1_XOF:SHAKE128_SSWU_RO_ + constexpr static std::array suite_id = { + 0x42, 0x4c, 0x53, 0x31, 0x32, 0x33, 0x38, 0x31, 0x47, 0x31, 0x5f, 0x58, 0x4f, 0x46, 0x3a, 0x53, + 0x48, 0x41, 0x4b, 0x45, 0x31, 0x32, 0x38, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 64; + }; + + template<> + struct h2f_suite, + shake<128, 2048>, 128> { + typedef typename algebra::curves::bls12_381::g2_type<>::field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef shake<128, 2048> hash_type; + + // BLS12381G2_XOF:SHAKE128_SSWU_RO_ + constexpr static std::array suite_id = { + 0x42, 0x4c, 0x53, 0x31, 0x32, 0x33, 0x38, 0x31, 0x47, 0x32, 0x5f, 0x58, 0x4f, 0x46, 0x3a, 0x53, + 0x48, 0x41, 0x4b, 0x45, 0x31, 0x32, 0x38, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 64; + }; + + template<> + struct h2f_suite, 128> { + typedef typename algebra::curves::bls12_381::base_field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef shake<256, 1024> hash_type; + + // BLS12381G1_XOF:SHAKE256_SSWU_RO_ + constexpr static std::array suite_id = { + 0x42, 0x4c, 0x53, 0x31, 0x32, 0x33, 0x38, 0x31, 0x47, 0x31, 0x5f, 0x58, 0x4f, 0x46, 0x3a, 0x53, + 0x48, 0x41, 0x4b, 0x45, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 64; + }; + + template<> + struct h2f_suite, + shake<256, 2048>, 128> { + typedef typename algebra::curves::bls12_381::g2_type<>::field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef shake<256, 2048> hash_type; + + // BLS12381G2_XOF:SHAKE256_SSWU_RO_ + constexpr static std::array suite_id = { + 0x42, 0x4c, 0x53, 0x31, 0x32, 0x33, 0x38, 0x31, 0x47, 0x32, 0x5f, 0x58, 0x4f, 0x46, 0x3a, 0x53, + 0x48, 0x41, 0x4b, 0x45, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 64; + }; + + template<> + struct h2f_suite, 128> { + typedef typename algebra::curves::pallas::base_field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef keccak_1600<256> hash_type; + + // PALLAS_XMD:KECCAK-256_SSWU_RO_ + constexpr static std::array suite_id = { + 0x50, 0x41, 0x4c, 0x4c, 0x41, 0x53, 0x5f, 0x58, 0x4d, 0x44, 0x3a, 0x4b, 0x45, 0x43, 0x43, + 0x41, 0x4b, 0x2d, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 48; + }; + + template<> + struct h2f_suite, 128> { + typedef typename algebra::curves::mnt4_298::base_field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef keccak_1600<256> hash_type; + + // MNT4298_XMD:KECCAK-256_SSWU_RO_ + constexpr static std::array suite_id = { + 0x4d, 0x4e, 0x54, 0x34, 0x32, 0x39, 0x38, 0x5f, 0x58, 0x4d, 0x44, 0x3a, 0x4b, 0x45, 0x43, 0x43, + 0x41, 0x4b, 0x2d, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 54; + }; + + template<> + struct h2f_suite, 128> { + typedef typename algebra::curves::mnt6_298::base_field_type field_type; + typedef typename field_type::value_type field_value_type; + typedef typename field_type::modular_type modular_type; + typedef keccak_1600<256> hash_type; + + // MNT6298_XMD:KECCAK-256_SSWU_RO_ + constexpr static std::array suite_id = { + 0x4d, 0x4e, 0x54, 0x36, 0x32, 0x39, 0x38, 0x5f, 0x58, 0x4d, 0x44, 0x3a, 0x4b, 0x45, 0x43, 0x43, + 0x41, 0x4b, 0x2d, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x53, 0x57, 0x55, 0x5f, 0x52, 0x4f, 0x5f}; + + constexpr static std::size_t m = field_type::arity; + constexpr static std::size_t k = 128; + /// L = ceil((ceil(log2(p)) + k) / 8) + constexpr static std::size_t L = 54; + }; } // namespace hashes - } // namespace crypto3 + } // namespace crypto3 } // namespace nil #endif // CRYPTO3_HASH_H2F_SUITES_HPP diff --git a/libs/hash/include/nil/crypto3/hash/detail/keccak/keccak_padding.hpp b/libs/hash/include/nil/crypto3/hash/detail/keccak/keccak_padding.hpp index 7a4b24a2c9..a0316be8c5 100644 --- a/libs/hash/include/nil/crypto3/hash/detail/keccak/keccak_padding.hpp +++ b/libs/hash/include/nil/crypto3/hash/detail/keccak/keccak_padding.hpp @@ -49,8 +49,8 @@ namespace nil { constexpr static const std::size_t block_words = policy_type::block_words; typedef typename policy_type::block_type block_type; - constexpr static const std::size_t digest_bits = policy_type::digest_bits; - typedef typename policy_type::digest_type digest_type; + // constexpr static const std::size_t digest_bits = policy_type::digest_bits; + // typedef typename policy_type::digest_type digest_type; typedef ::nil::crypto3::detail::injector diff --git a/libs/hash/include/nil/crypto3/hash/detail/shake/shake_functions.hpp b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_functions.hpp new file mode 100644 index 0000000000..072c899451 --- /dev/null +++ b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_functions.hpp @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Valeh Farzaliyev +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_SHAKE_FUNCTIONS_HPP +#define CRYPTO3_SHAKE_FUNCTIONS_HPP + +#include +#include + +#include + +namespace nil { + namespace crypto3 { + namespace hashes { + namespace detail { + template + struct shake_functions : public shake_policy { + using policy_type = shake_policy; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + using word_type = typename policy_type::word_type; + + constexpr static const std::size_t block_words = policy_type::block_words; + using block_type = typename policy_type::block_type; + + using state_type = typename policy_type::state_type; + + constexpr static const std::size_t round_constants_size = policy_type::rounds; + using round_constants_type = typename std::array; + + constexpr static const std::size_t pkcs_id_size = policy_type::pkcs_id_size; + constexpr static const std::size_t pkcs_id_bits = policy_type::pkcs_id_bits; + using pkcs_id_type = typename policy_type::pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = policy_type::pkcs_id; + + static void permute(state_type &A) { + keccak_1600_impl::permute(A); + } + + static void absorb(const block_type& block, state_type& state) { + for (std::size_t i = 0; i < block.size(); ++i) { + // XOR + state[i] ^= block[i]; + } + } + }; + } // namespace detail + } // namespace hashes + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_SHAKE_FUNCTIONS_HPP diff --git a/libs/hash/include/nil/crypto3/hash/detail/shake/shake_padding.hpp b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_padding.hpp new file mode 100644 index 0000000000..75705311d1 --- /dev/null +++ b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_padding.hpp @@ -0,0 +1,96 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2020 Alexander Sokolov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_SHAKE_PADDING_HPP +#define CRYPTO3_SHAKE_PADDING_HPP + +#include +#include +#include +#include + + +namespace nil { + namespace crypto3 { + namespace hashes { + namespace detail { + // pad10*1 scheme + template + class shake_padder { + typedef Policy policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t state_bits = policy_type::state_bits; + constexpr static const std::size_t state_words = policy_type::state_words; + typedef typename policy_type::state_type state_type; + + constexpr static const std::size_t block_bits = policy_type::block_bits; + constexpr static const std::size_t block_words = policy_type::block_words; + typedef typename policy_type::block_type block_type; + + typedef ::nil::crypto3::detail::injector + injector_type; + + public: + static std::vector get_padded_blocks(const block_type& block, std::size_t block_seen) { + // SHA3 padding consists of 11 11 10 0...0 1 (1111 + 10*1 keccak padding) + using namespace nil::crypto3::detail; + + std::vector padded_blocks; + block_type new_block = block; + // set variable to 1111 + word_type shake_specific_bits = high_bits(~word_type(), 4); + // get how many bits from it could fit into current block + const std::size_t shake_specific_bits_n_for_first_block = std::min(block_bits - block_seen, std::size_t{4}); + // inject this amount of bits + injector_type::inject(shake_specific_bits, shake_specific_bits_n_for_first_block, new_block, block_seen); + + if (block_seen == block_bits) { + // if current block is full, copy it to result vector, reset counter. Since we need + // to add, at least, the last 1 bit (and mb the rest of sha_specific_bits) + padded_blocks.push_back(new_block); + block_seen = 0; + } + + if (shake_specific_bits_n_for_first_block < 4) { + // if not all sha_specific_bits was injected, we inject the rest to the next block + injector_type::inject(shake_specific_bits, 4 - shake_specific_bits_n_for_first_block, new_block, + block_seen, shake_specific_bits_n_for_first_block); + } + + auto keccak_padding_result = keccak_1600_padder::get_padded_blocks(new_block, block_seen); + padded_blocks.insert(padded_blocks.end(), std::make_move_iterator(keccak_padding_result.begin()), std::make_move_iterator(keccak_padding_result.end())); + + return padded_blocks; + } + }; + } // namespace detail + } // namespace hashes + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_SHAKE_PADDING_HPP diff --git a/libs/hash/include/nil/crypto3/hash/detail/shake/shake_policy.hpp b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_policy.hpp new file mode 100644 index 0000000000..e449e1e3be --- /dev/null +++ b/libs/hash/include/nil/crypto3/hash/detail/shake/shake_policy.hpp @@ -0,0 +1,128 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Valeh Farzaliyev +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_SHAKE_POLICY_HPP +#define CRYPTO3_SHAKE_POLICY_HPP + +#include + +#include + +namespace nil { + namespace crypto3 { + namespace hashes { + namespace detail { + template + struct basic_shake_policy : public ::nil::crypto3::detail::basic_functions<64> { + typedef ::nil::crypto3::detail::basic_functions<64> policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t pkcs_id_size = 0; + constexpr static const std::size_t pkcs_id_bits = pkcs_id_size * CHAR_BIT; + typedef std::array pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = {}; + }; + + template<> + struct basic_shake_policy<256> : public ::nil::crypto3::detail::basic_functions<64> { + typedef ::nil::crypto3::detail::basic_functions<64> policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t pkcs_id_size = 19; + constexpr static const std::size_t pkcs_id_bits = pkcs_id_size * CHAR_BIT; + typedef std::array pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = {0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x0C, 0x05, 0x00, 0x04, 0x1C}; // fix-me: incorrect pcks_id (but, oid is true) + }; + + template<> + struct basic_shake_policy<128> : public ::nil::crypto3::detail::basic_functions<64> { + typedef ::nil::crypto3::detail::basic_functions<64> policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t pkcs_id_size = 19; + constexpr static const std::size_t pkcs_id_bits = pkcs_id_size * CHAR_BIT; + typedef std::array pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x0B, 0x05, 0x00, 0x04, 0x20}; // fix-me: incorrect pcks_id (but, oid is true) + }; + + + template + constexpr + typename basic_shake_policy::pkcs_id_type const basic_shake_policy::pkcs_id; + + template + struct shake_policy : public basic_shake_policy { + + typedef basic_shake_policy policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t half_capacity = HalfCapacity; + + constexpr static const std::size_t state_bits = 1600; + constexpr static const std::size_t state_words = state_bits / word_bits; + typedef typename std::array state_type; + + constexpr static const std::size_t block_bits = state_bits - 2 * half_capacity; + constexpr static const std::size_t block_words = block_bits / word_bits; + typedef std::array block_type; + + constexpr static const std::size_t pkcs_id_size = policy_type::pkcs_id_size; + constexpr static const std::size_t pkcs_id_bits = policy_type::pkcs_id_bits; + typedef typename policy_type::pkcs_id_type pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = policy_type::pkcs_id; + + constexpr static const std::size_t length_bits = 0; + + typedef typename stream_endian::little_octet_big_bit digest_endian; + + constexpr static const std::size_t rounds = 24; + + struct iv_generator { + static state_type generate() { + return keccak_1600_policy::iv_generator::generate(); + } + }; + }; + } // namespace detail + } // namespace hashes + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_SHA3_POLICY_HPP diff --git a/libs/hash/include/nil/crypto3/hash/h2f.hpp b/libs/hash/include/nil/crypto3/hash/h2f.hpp index 2201dd035a..b400271642 100644 --- a/libs/hash/include/nil/crypto3/hash/h2f.hpp +++ b/libs/hash/include/nil/crypto3/hash/h2f.hpp @@ -89,8 +89,8 @@ namespace nil { constexpr static std::size_t len_in_bytes = count * m * L; typedef typename std::conditional<(ExpandMsgVariant::rfc_xmd == expand_msg_variant), - detail::expand_message_xmd, - void>::type expand_message_type; + detail::expand_message_xmd, + detail::expand_message_xof >::type expand_message_type; static_assert(!std::is_void::value, "Undefined expand_message_type."); typedef std::array result_type; diff --git a/libs/hash/include/nil/crypto3/hash/shake.hpp b/libs/hash/include/nil/crypto3/hash/shake.hpp new file mode 100644 index 0000000000..cbb8dcd60b --- /dev/null +++ b/libs/hash/include/nil/crypto3/hash/shake.hpp @@ -0,0 +1,86 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Valeh Farzaliyev +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_HASH_SHA3_HPP +#define CRYPTO3_HASH_SHA3_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace hashes { + /*! + * @brief + * @tparam DigestBits + * @ingroup hashes + */ + template + class shake { + public: + typedef detail::shake_functions policy_type; + + constexpr static const std::size_t word_bits = policy_type::word_bits; + typedef typename policy_type::word_type word_type; + + constexpr static const std::size_t block_bits = policy_type::block_bits; + constexpr static const std::size_t block_words = policy_type::block_words; + typedef typename policy_type::block_type block_type; + + constexpr static const std::size_t digest_bits = DigestBits; + typedef static_digest digest_type; + + constexpr static const std::size_t pkcs_id_size = policy_type::pkcs_id_size; + constexpr static const std::size_t pkcs_id_bits = policy_type::pkcs_id_bits; + typedef typename policy_type::pkcs_id_type pkcs_id_type; + + constexpr static const pkcs_id_type pkcs_id = policy_type::pkcs_id; + + struct construction { + struct params_type { + typedef typename policy_type::digest_endian digest_endian; + + constexpr static const std::size_t length_bits = policy_type::length_bits; + constexpr static const std::size_t digest_bits = DigestBits; + }; + + typedef sponge_construction, detail::shake_functions, detail::shake_padder> + type; + }; + + constexpr static detail::stream_processor_type stream_processor = detail::stream_processor_type::Block; + using accumulator_tag = accumulators::tag::hash>; + }; + } // namespace hashes + } // namespace crypto3 +} // namespace nil + +#endif diff --git a/libs/hash/test/CMakeLists.txt b/libs/hash/test/CMakeLists.txt index 95e859d284..20a91a1ab0 100644 --- a/libs/hash/test/CMakeLists.txt +++ b/libs/hash/test/CMakeLists.txt @@ -60,6 +60,7 @@ set(TESTS_NAMES "sha1" "sha2" "sha3" + "shake" "static_digest" "tiger" "poseidon" diff --git a/libs/hash/test/data/shake.json b/libs/hash/test/data/shake.json new file mode 100644 index 0000000000..6b32ab411c --- /dev/null +++ b/libs/hash/test/data/shake.json @@ -0,0 +1,18 @@ +{ + "data_128": { + "a": "85c8de88d28866bf0868090b3961162bf82392f690d9e4730910f4af7c6ab3ee", + "abc": "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8", + "message digest": "cbef732961b55b4c31396796577df491b6eed61d8949ce967226801e411e53f0", + "abcdefghijklmnopqrstuvwxyz": "961c919c0854576e561320e81514bf3724197d0715e16a364520384ee997f6ef", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": "1a96182b50fb8c7e74e0a707788f55e98209b8d91fade8f32f8dd5cff7bf21f5", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": "54dd201e53249910db3c7d366574fbb64e71fae442a4bac13439f26dd4896883" + }, + "data_256": { + "a": "867e2cb04f5a04dcbd592501a5e8fe9ceaafca50255626ca736c138042530ba4", + "abc": "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739", + "message digest": "718e224088856840ade4dc73487e15826a07ecb8ed5e2bda526cc1acddb99d00", + "abcdefghijklmnopqrstuvwxyz": "b7b78b04a3dd30a265c8886c33fda94799853de5d3d10541fd4e9f4613701c61", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": "4d8c2dd2435a0128eefbb8c36f6f87133a7911e18d979ee1ae6be5d4fd2e3329", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": "31f19a097c723e91fa59b0998dd8523c2a9e7e13b4025d6b48fcbc328973a108" + } + } \ No newline at end of file diff --git a/libs/hash/test/h2f.cpp b/libs/hash/test/h2f.cpp index 1046b2479f..4a39983351 100644 --- a/libs/hash/test/h2f.cpp +++ b/libs/hash/test/h2f.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -79,9 +80,35 @@ namespace boost { }; } // namespace tt_detail - } // namespace test_tools + } // namespace test_tools } // namespace boost +template::value && + std::is_same::value && + std::is_same::value>::type> +void check_expand_message(const DstType &dst, const MsgType &msg, const ResultType &result) { + auto result_compare = [&result](auto my_result) { + if (result.size() != my_result.size()) { + return false; + } + bool ret = true; + for (std::size_t i = 0; i < result.size(); i++) { + ret &= result[i] == my_result[i]; + } + return ret; + }; + + typename Expander::internal_accumulator_type acc; + Expander::init_accumulator(acc); + Expander::update(acc, msg); + typename Expander::result_type uniform_bytes = Expander::process(acc, dst); + BOOST_CHECK(result_compare(uniform_bytes)); +} + template typename std::enable_if::value>::type check_hash_to_field_ro(const std::string &msg_str, const typename Hash::digest_type &result) { @@ -95,6 +122,325 @@ typename std::enable_if::value>::type BOOST_AUTO_TEST_SUITE(hash_h2f_manual_tests) +BOOST_AUTO_TEST_CASE(expand_message_xmd_sha256_test) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-K.1 + using hash_type = hashes::sha2<256>; + + std::string DST_str("QUUX-V01-CS02-with-expander"); + std::vector DST(DST_str.begin(), DST_str.end()); + + // {len_in_bytes, msg, uniform_bytes} + using samples_type = std::vector, std::vector>>; + samples_type samples { + {0x20, {}, {0xf6, 0x59, 0x81, 0x9a, 0x64, 0x73, 0xc1, 0x83, 0x5b, 0x25, 0xea, 0x59, 0xe3, 0xd3, 0x89, 0x14, + 0xc9, 0x8b, 0x37, 0x4f, 0x9, 0x70, 0xb7, 0xe4, 0xc9, 0x21, 0x81, 0xdf, 0x92, 0x8f, 0xca, 0x88}}, + {0x20, {0x61, 0x62, 0x63}, {0x1c, 0x38, 0xf7, 0xc2, 0x11, 0xef, 0x23, 0x33, 0x67, 0xb2, 0x42, + 0xd, 0x4, 0x79, 0x8f, 0xa4, 0x69, 0x80, 0x80, 0xa8, 0x90, 0x10, + 0x21, 0xa7, 0x95, 0xa1, 0x15, 0x17, 0x75, 0xfe, 0x4d, 0xa7}}, + {0x20, + {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}, + {0x8f, 0x7e, 0x7b, 0x66, 0x79, 0x1f, 0xd, 0xa0, 0xdb, 0xb5, 0xec, 0x7c, 0x22, 0xec, 0x63, 0x7f, + 0x79, 0x75, 0x8c, 0xa, 0x48, 0x17, 0xb, 0xfb, 0x7c, 0x46, 0x11, 0xbd, 0x30, 0x4e, 0xce, 0x89}}, + {0x20, + {0x71, 0x31, 0x32, 0x38, 0x5f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71}, + {0x72, 0xd5, 0xaa, 0x5e, 0xc8, 0x10, 0x37, 0xd, 0x1f, 0x0, 0x13, 0xc0, 0xdf, 0x2f, 0x1d, 0x65, + 0x69, 0x94, 0x94, 0xee, 0x2a, 0x39, 0xf7, 0x2e, 0x17, 0x16, 0xb1, 0xb9, 0x64, 0xe1, 0xc6, 0x42}}, + {0x20, + {0x61, 0x35, 0x31, 0x32, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}, + {0x3b, 0x8e, 0x70, 0x4f, 0xc4, 0x83, 0x36, 0xac, 0xa4, 0xc2, 0xa1, 0x21, 0x95, 0xb7, 0x20, 0x88, + 0x2f, 0x21, 0x62, 0xa4, 0xb7, 0xb1, 0x3a, 0x9c, 0x35, 0xd, 0xb4, 0x6f, 0x42, 0x9b, 0x77, 0x1b}}, + {0x80, {}, {0x8b, 0xcf, 0xfd, 0x1a, 0x3c, 0xae, 0x24, 0xcf, 0x9c, 0xd7, 0xab, 0x85, 0x62, 0x8f, 0xd1, 0x11, + 0xbb, 0x17, 0xe3, 0x73, 0x9d, 0x3b, 0x53, 0xf8, 0x95, 0x80, 0xd2, 0x17, 0xaa, 0x79, 0x52, 0x6f, + 0x17, 0x8, 0x35, 0x4a, 0x76, 0xa4, 0x2, 0xd3, 0x56, 0x9d, 0x6a, 0x9d, 0x19, 0xef, 0x3d, 0xe4, + 0xd0, 0xb9, 0x91, 0xe4, 0xf5, 0x4b, 0x9f, 0x20, 0xdc, 0xde, 0x9b, 0x95, 0xa6, 0x68, 0x24, 0xcb, + 0xdf, 0x6c, 0x1a, 0x96, 0x3a, 0x19, 0x13, 0xd4, 0x3f, 0xd7, 0xac, 0x44, 0x3a, 0x2, 0xfc, 0x5d, + 0x9d, 0x8d, 0x77, 0xe2, 0x7, 0x1b, 0x86, 0xab, 0x11, 0x4a, 0x9f, 0x34, 0x15, 0x9, 0x54, 0xa7, + 0x53, 0x1d, 0xa5, 0x68, 0xa1, 0xea, 0x8c, 0x76, 0x8, 0x61, 0xc0, 0xcd, 0xe2, 0x0, 0x5a, 0xfc, + 0x2c, 0x11, 0x40, 0x42, 0xee, 0x7b, 0x58, 0x48, 0xf5, 0x30, 0x3f, 0x6, 0x11, 0xcf, 0x29, 0x7f}}, + {0x80, + {0x61, 0x62, 0x63}, + {0xfe, 0x99, 0x4e, 0xc5, 0x1b, 0xda, 0xa8, 0x21, 0x59, 0x80, 0x47, 0xb3, 0x12, 0x1c, 0x14, 0x9b, + 0x36, 0x4b, 0x17, 0x86, 0x6, 0xd5, 0xe7, 0x2b, 0xfb, 0xb7, 0x13, 0x93, 0x3a, 0xcc, 0x29, 0xc1, + 0x86, 0xf3, 0x16, 0xba, 0xec, 0xf7, 0xea, 0x22, 0x21, 0x2f, 0x24, 0x96, 0xef, 0x3f, 0x78, 0x5a, + 0x27, 0xe8, 0x4a, 0x40, 0xd8, 0xb2, 0x99, 0xce, 0xc5, 0x60, 0x32, 0x76, 0x3e, 0xce, 0xef, 0xf4, + 0xc6, 0x1b, 0xd1, 0xfe, 0x65, 0xed, 0x81, 0xde, 0xca, 0xff, 0xf4, 0xa3, 0x1d, 0x1, 0x98, 0x61, + 0x9c, 0xa, 0xa0, 0xc6, 0xc5, 0x1f, 0xca, 0x15, 0x52, 0x7, 0x89, 0x92, 0x5e, 0x81, 0x3d, 0xcf, + 0xd3, 0x18, 0xb5, 0x42, 0xf8, 0x79, 0x94, 0x41, 0x27, 0x1f, 0x4d, 0xb9, 0xee, 0x3b, 0x80, 0x92, + 0xa7, 0xa2, 0xe8, 0xd5, 0xb7, 0x5b, 0x73, 0xe2, 0x8f, 0xb1, 0xab, 0x6b, 0x45, 0x73, 0xc1, 0x92}}, + {0x80, + {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}, + {0xc9, 0xec, 0x79, 0x41, 0x81, 0x1b, 0x1e, 0x19, 0xce, 0x98, 0xe2, 0x1d, 0xb2, 0x8d, 0x22, 0x25, + 0x93, 0x54, 0xd4, 0xd0, 0x64, 0x3e, 0x30, 0x11, 0x75, 0xe2, 0xf4, 0x74, 0xe0, 0x30, 0xd3, 0x26, + 0x94, 0xe9, 0xdd, 0x55, 0x20, 0xdd, 0xe9, 0x3f, 0x36, 0x0, 0xd8, 0xed, 0xad, 0x94, 0xe5, 0xc3, + 0x64, 0x90, 0x30, 0x88, 0xa7, 0x22, 0x8c, 0xc9, 0xef, 0xf6, 0x85, 0xd7, 0xea, 0xac, 0x50, 0xd5, + 0xa5, 0xa8, 0x22, 0x9d, 0x8, 0x3b, 0x51, 0xde, 0x4c, 0xcc, 0x37, 0x33, 0x91, 0x7f, 0x4b, 0x95, + 0x35, 0xa8, 0x19, 0xb4, 0x45, 0x81, 0x48, 0x90, 0xb7, 0x2, 0x9b, 0x5d, 0xe8, 0x5, 0xbf, 0x62, + 0xb3, 0x3a, 0x4d, 0xc7, 0xe2, 0x4a, 0xcd, 0xf2, 0xc9, 0x24, 0xe9, 0xfe, 0x50, 0xd5, 0x5a, 0x6b, + 0x83, 0x2c, 0x8c, 0x84, 0xc7, 0xf8, 0x24, 0x74, 0xb3, 0x4e, 0x48, 0xc6, 0xd4, 0x38, 0x67, 0xbe}}, + {0x80, + {0x71, 0x31, 0x32, 0x38, 0x5f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71}, + {0x48, 0xe2, 0x56, 0xdd, 0xba, 0x72, 0x20, 0x53, 0xba, 0x46, 0x2b, 0x2b, 0x93, 0x35, 0x1f, 0xc9, + 0x66, 0x2, 0x6e, 0x6d, 0x6d, 0xb4, 0x93, 0x18, 0x97, 0x98, 0x18, 0x1c, 0x5f, 0x3f, 0xee, 0xa3, + 0x77, 0xb5, 0xa6, 0xf1, 0xd8, 0x36, 0x8d, 0x74, 0x53, 0xfa, 0xef, 0x71, 0x5f, 0x9a, 0xec, 0xb0, + 0x78, 0xcd, 0x40, 0x2c, 0xbd, 0x54, 0x8c, 0xe, 0x17, 0x9c, 0x4e, 0xd1, 0xe4, 0xc7, 0xe5, 0xb0, + 0x48, 0xe0, 0xa3, 0x9d, 0x31, 0x81, 0x7b, 0x5b, 0x24, 0xf5, 0xd, 0xb5, 0x8b, 0xb3, 0x72, 0xf, + 0xe9, 0x6b, 0xa5, 0x3d, 0xb9, 0x47, 0x84, 0x21, 0x20, 0xa0, 0x68, 0x81, 0x6a, 0xc0, 0x5c, 0x15, + 0x9b, 0xb5, 0x26, 0x6c, 0x63, 0x65, 0x8b, 0x4f, 0x0, 0xc, 0xbf, 0x87, 0xb1, 0x20, 0x9a, 0x22, + 0x5d, 0xef, 0x8e, 0xf1, 0xdc, 0xa9, 0x17, 0xbc, 0xda, 0x79, 0xa1, 0xe4, 0x2a, 0xcd, 0x80, 0x69}}, + {0x80, + {0x61, 0x35, 0x31, 0x32, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}, + {0x39, 0x69, 0x62, 0xdb, 0x47, 0xf7, 0x49, 0xec, 0x3b, 0x50, 0x42, 0xce, 0x24, 0x52, 0xb6, 0x19, + 0x60, 0x7f, 0x27, 0xfd, 0x39, 0x39, 0xec, 0xe2, 0x74, 0x6a, 0x76, 0x14, 0xfb, 0x83, 0xa1, 0xd0, + 0x97, 0xf5, 0x54, 0xdf, 0x39, 0x27, 0xb0, 0x84, 0xe5, 0x5d, 0xe9, 0x2c, 0x78, 0x71, 0x43, 0xd, + 0x6b, 0x95, 0xc2, 0xa1, 0x38, 0x96, 0xd8, 0xa3, 0x3b, 0xc4, 0x85, 0x87, 0xb1, 0xf6, 0x6d, 0x21, + 0xb1, 0x28, 0xa1, 0xa8, 0x24, 0xd, 0x5b, 0xc, 0x26, 0xdf, 0xe7, 0x95, 0xa1, 0xa8, 0x42, 0xa0, + 0x80, 0x7b, 0xb1, 0x48, 0xb7, 0x7c, 0x2e, 0xf8, 0x2e, 0xd4, 0xb6, 0xc9, 0xf7, 0xfc, 0xb7, 0x32, + 0xe7, 0xf9, 0x44, 0x66, 0xc8, 0xb5, 0x1e, 0x52, 0xbf, 0x37, 0x8f, 0xba, 0x4, 0x4a, 0x31, 0xf5, + 0xcb, 0x44, 0x58, 0x3a, 0x89, 0x2f, 0x59, 0x69, 0xdc, 0xd7, 0x3b, 0x3f, 0xa1, 0x28, 0x81, 0x6e}}}; + + for (const auto &s : samples) { + + if (std::get<0>(s) == 0x20) { + using expand_message = typename hashes::detail::expand_message_xmd<128, 32, hash_type>; + check_expand_message(DST, std::get<1>(s), std::get<2>(s)); + } + + if (std::get<0>(s) == 0x80) { + using expand_message = hashes::detail::expand_message_xmd<128, 128, hash_type>; + check_expand_message(DST, std::get<1>(s), std::get<2>(s)); + } + } +} + +BOOST_AUTO_TEST_CASE(expand_message_xof_shake128_test) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-K.3 + + std::string DST_str("QUUX-V01-CS02-with-expander"); + std::vector DST(DST_str.begin(), DST_str.end()); + + // {len_in_bytes, msg, uniform_bytes} + using samples_type = std::vector, std::vector>>; + samples_type samples { + {0x20, {}, {0xec, 0xa3, 0xfe, 0x8f, 0x7f, 0x5f, 0x1d, 0x52, 0xd7, 0xed, 0x36, 0x91, 0xc3, 0x21, 0xad, 0xc7, + 0xd2, 0xa0, 0xfe, 0xf1, 0xf8, 0x43, 0xd2, 0x21, 0xf7, 0x00, 0x25, 0x30, 0x07, 0x007, 0x46, 0xde}}, + {0x20, {0x61, 0x62, 0x63}, {0xc7, 0x9b, 0x8e, 0xa0, 0xaf, 0x10, 0xfd, 0x88, 0x71, 0xed, 0xa9, + 0x83, 0x34, 0xea, 0x9d, 0x54, 0xe9, 0xe5, 0x28, 0x2b, 0xe9, 0x75, + 0x21, 0x67, 0x8f, 0x98, 0x77, 0x18, 0xb1, 0x87, 0xbc, 0x08}}, + {0x20, + {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}, + {0xfb, 0x6f, 0x4a, 0xf2, 0xa8, 0x3f, 0x62, 0x76, 0xe9, 0xd4, 0x17, 0x84, 0xf1, 0xe2, 0x9d, 0xa5, + 0xe2, 0x75, 0x66, 0x16, 0x7c, 0x33, 0xe5, 0xcf, 0x26, 0x82, 0xc3, 0x00, 0x96, 0x87, 0x8b, 0x73}}, + {0x20, + {0x71, 0x31, 0x32, 0x38, 0x5f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71}, + {0x12, 0x5d, 0x05, 0x85, 0x0d, 0xb9, 0x15, 0xe0, 0x68, 0x3d, 0x17, 0xd0, 0x44, 0xd8, 0x74, 0x77, + 0xe6, 0xe7, 0xb3, 0xf7, 0x0a, 0x45, 0x0d, 0xd0, 0x97, 0x76, 0x1e, 0x18, 0xd1, 0xd1, 0xdc, 0xdf}}, + {0x20, + {0x61, 0x35, 0x31, 0x32, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}, + {0xbe, 0xaf, 0xd0, 0x26, 0xcb, 0x94, 0x2c, 0x86, 0xf6, 0xa2, 0xb3, 0x1b, 0xb8, 0xe6, 0xbf, 0x71, + 0x73, 0xfb, 0x1b, 0x0c, 0xaf, 0x3c, 0x21, 0xea, 0x4b, 0x3b, 0x9d, 0x05, 0xd9, 0x04, 0xfd, 0x23}}, + {0x80, {}, {0x15, 0x73, 0x3b, 0x3f, 0xb2, 0x2f, 0xac, 0x0e, 0x09, 0x02, 0xc2, 0x20, 0xae, 0xea, 0x48, 0xe5, + 0xe4, 0x7d, 0x39, 0xf3, 0x6c, 0x2c, 0xc0, 0x3e, 0xac, 0x34, 0x36, 0x7c, 0x48, 0xf2, 0xa3, 0xeb, + 0xbc, 0xb3, 0xba, 0xa8, 0xa0, 0xcf, 0x17, 0xab, 0x12, 0xff, 0xf4, 0xde, 0xfc, 0x7c, 0xe2, 0x2a, + 0xed, 0x47, 0x18, 0x8b, 0x6c, 0x16, 0x3e, 0x82, 0x87, 0x41, 0x47, 0x3b, 0xd8, 0x9c, 0xc6, 0x46, + 0xa0, 0x82, 0xcb, 0x68, 0xb8, 0xe8, 0x35, 0xb1, 0x37, 0x4e, 0xa9, 0xa6, 0x31, 0x5d, 0x61, 0xdb, + 0x00, 0x43, 0xf4, 0xab, 0xf5, 0x06, 0xc2, 0x63, 0x86, 0xe8, 0x46, 0x68, 0xe0, 0x77, 0xc8, 0x5e, + 0xbd, 0x9d, 0x63, 0x2f, 0x43, 0x90, 0x55, 0x9b, 0x97, 0x9e, 0x70, 0xe9, 0xe7, 0xaf, 0xfb, 0xd0, + 0xac, 0x2a, 0x21, 0x2c, 0x03, 0xb6, 0x98, 0xef, 0xbb, 0xe9, 0x40, 0xf2, 0xd1, 0x64, 0x73, 0x2b}}, + {0x80, + {0x61, 0x62, 0x63}, + {0x4c, 0xca, 0xfb, 0x6d, 0x95, 0xb9, 0x15, 0x37, 0x79, 0x8d, 0x1f, 0xbb, 0x25, 0xb9, 0xfb, 0xe1, + 0xa5, 0xbb, 0xe1, 0x68, 0x3f, 0x43, 0xa4, 0xf6, 0xf0, 0x3e, 0xf5, 0x40, 0xb8, 0x11, 0x23, 0x53, + 0x17, 0xbf, 0xc0, 0xae, 0xfb, 0x21, 0x7f, 0xac, 0xa0, 0x55, 0xe1, 0xb8, 0xf3, 0x2d, 0xfd, 0xe9, + 0xeb, 0x10, 0x2c, 0xdc, 0x02, 0x6e, 0xd2, 0x7c, 0xaa, 0x71, 0x53, 0x0e, 0x36, 0x1b, 0x3a, 0xdb, + 0xb9, 0x2c, 0xcf, 0x68, 0xda, 0x35, 0xae, 0xd8, 0xb9, 0xdc, 0x7e, 0x4e, 0x6b, 0x5d, 0xb0, 0x66, + 0x6c, 0x60, 0x7a, 0x31, 0xdf, 0x05, 0x51, 0x3d, 0xda, 0xf4, 0xc8, 0xee, 0x23, 0xb0, 0xee, 0x7f, + 0x39, 0x5a, 0x6e, 0x8b, 0xe3, 0x2e, 0xb1, 0x3c, 0xa9, 0x7d, 0xa2, 0x89, 0xf2, 0x64, 0x36, 0x16, + 0xac, 0x30, 0xfe, 0x91, 0x04, 0xbb, 0x0d, 0x3a, 0x67, 0xa0, 0xa5, 0x25, 0x83, 0x7c, 0x2d, 0xc6}}, + {0x80, + {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}, + {0xc8, 0xee, 0x0e, 0x12, 0x73, 0x6e, 0xfb, 0xc9, 0xb4, 0x77, 0x81, 0xdb, 0x9d, 0x1e, 0x5d, 0xb9, + 0xc8, 0x53, 0x68, 0x43, 0x44, 0xa6, 0x77, 0x6e, 0xb3, 0x62, 0xd7, 0x5b, 0x35, 0x4f, 0x4b, 0x74, + 0xcf, 0x60, 0xba, 0x13, 0x73, 0xdc, 0x2e, 0x22, 0xc6, 0x8e, 0xfb, 0x76, 0xa0, 0x22, 0xed, 0x53, + 0x91, 0xf6, 0x7c, 0x77, 0x99, 0x08, 0x02, 0x01, 0x8c, 0x8c, 0xdc, 0x7a, 0xf6, 0xd0, 0x0c, 0x86, + 0xb6, 0x6a, 0x3b, 0x3c, 0xca, 0xd3, 0xf1, 0x8d, 0x90, 0xf4, 0x43, 0x7a, 0x16, 0x51, 0x86, 0xf6, + 0x60, 0x1c, 0xf0, 0xbb, 0x28, 0x1e, 0xa5, 0xd8, 0x0d, 0x1d, 0xe2, 0x0f, 0xe2, 0x2b, 0xb2, 0xe2, + 0xd8, 0xac, 0xab, 0x0c, 0x04, 0x3e, 0x76, 0xe3, 0xa0, 0xf3, 0x4e, 0x0a, 0x1e, 0x66, 0xc9, 0xad, + 0xe4, 0xfe, 0xf9, 0xef, 0x3b, 0x43, 0x11, 0x30, 0xad, 0x6f, 0x23, 0x2b, 0xab, 0xe9, 0xfe, 0x68}}, + {0x80, + {0x71, 0x31, 0x32, 0x38, 0x5f, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, + 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71}, + {0x3e, 0xeb, 0xe6, 0x72, 0x1b, 0x2e, 0xc7, 0x46, 0x62, 0x98, 0x56, 0xdc, 0x2d, 0xd3, 0xf0, 0x3a, + 0x83, 0x0d, 0xab, 0xfe, 0xfd, 0x7e, 0x2d, 0x1e, 0x72, 0xaa, 0xf2, 0x12, 0x7d, 0x6a, 0xd1, 0x7c, + 0x98, 0x8b, 0x57, 0x62, 0xf3, 0x2e, 0x6e, 0xdf, 0x61, 0x97, 0x23, 0x78, 0xa4, 0x10, 0x6d, 0xc4, + 0xb6, 0x3f, 0xa1, 0x08, 0xad, 0x03, 0xb7, 0x93, 0xee, 0xdf, 0x45, 0x88, 0xf3, 0x4c, 0x4d, 0xf2, + 0xa9, 0x5b, 0x30, 0x99, 0x5a, 0x46, 0x4c, 0xb3, 0xee, 0x31, 0xd6, 0xdc, 0xa3, 0x0a, 0xdb, 0xfc, + 0x90, 0xff, 0xdf, 0x54, 0x14, 0xd7, 0x89, 0x30, 0x82, 0xc5, 0x5b, 0x26, 0x9d, 0x9e, 0xc9, 0xcd, + 0x6d, 0x2a, 0x71, 0x5b, 0x9c, 0x4f, 0xad, 0x4e, 0xb7, 0x0e, 0xd5, 0x6f, 0x87, 0x8b, 0x55, 0xa1, + 0x7b, 0x59, 0x94, 0xef, 0x0d, 0xe5, 0xb3, 0x38, 0x67, 0x5a, 0xad, 0x35, 0x35, 0x41, 0x95, 0xcd}}, + {0x80, + {0x61, 0x35, 0x31, 0x32, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}, + {0x85, 0x8c, 0xb4, 0xa6, 0xa5, 0x66, 0x8a, 0x97, 0xd0, 0xf7, 0x03, 0x9b, 0x5d, 0x6d, 0x57, 0x4d, + 0xde, 0x18, 0xdd, 0x23, 0x23, 0xcf, 0x6b, 0x20, 0x39, 0x45, 0xc6, 0x6d, 0xf8, 0x64, 0x77, 0xd1, + 0xf7, 0x47, 0xb4, 0x64, 0x01, 0x90, 0x3b, 0x3f, 0xa6, 0x6d, 0x12, 0x76, 0x10, 0x8e, 0xa7, 0x18, + 0x7b, 0x44, 0x11, 0xb7, 0x49, 0x9a, 0xcf, 0x46, 0x00, 0x08, 0x0c, 0xe3, 0x4f, 0xf6, 0xd2, 0x15, + 0x55, 0xc2, 0xaf, 0x16, 0xf0, 0x91, 0xad, 0xf8, 0xb2, 0x85, 0xc8, 0x43, 0x9f, 0x2e, 0x47, 0xfa, + 0x05, 0x53, 0xc3, 0xa6, 0xef, 0x5a, 0x42, 0x27, 0xa1, 0x3f, 0x34, 0x40, 0x62, 0x41, 0xb7, 0xd7, + 0xfd, 0x88, 0x53, 0xa0, 0x80, 0xba, 0xd2, 0x5e, 0xc4, 0x80, 0x4c, 0xdf, 0xe4, 0xfd, 0xa5, 0x00, + 0xe1, 0xc8, 0x72, 0xe7, 0x1b, 0x8c, 0x61, 0xa8, 0xe1, 0x60, 0x69, 0x18, 0x94, 0xb9, 0x60, 0x58}}}; + + for (const auto &s : samples) { + + if (std::get<0>(s) == 0x20) { + using expand_message = typename hashes::detail::expand_message_xof<128, 32, hashes::shake<128, 256>>; + check_expand_message(DST, std::get<1>(s), std::get<2>(s)); + } + + if (std::get<0>(s) == 0x80) { + using expand_message = hashes::detail::expand_message_xof<128, 128, hashes::shake<128, 1024>>; + check_expand_message(DST, std::get<1>(s), std::get<2>(s)); + } + } +} + BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g1_h2c_sha256_test) { // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.9.1 using curve_type = curves::bls12_381; @@ -241,4 +587,280 @@ BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g2_h2c_sha256_test) { } } +BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g1_h2f_shake128_test) { + // field elements were generated using the SageMath code from https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve + using curve_type = curves::bls12_381; + using field_type = typename curve_type::base_field_type; + using field_value_type = typename field_type::value_type; + using integral_type = typename field_type::integral_type; + using hash_type = hashes::h2f, + hashes::h2f_default_params, + 128, + hashes::UniformityCount::uniform_count, + hashes::ExpandMsgVariant::rfc_xof>>; + + using samples_type = std::vector>>; + samples_type samples = { + {"", + {field_value_type(integral_type("34026336386083886614678315776001410990195491156146619751680086308817537707641" + "2511339581237807169328025849613607738")), + field_value_type(integral_type("35487283142688730820577587057340419437479971382706358249913182139983177321994" + "22366369249146063877280813873779598614"))}}, + {"abc", + {field_value_type(integral_type("10299742258189792071225127476569579055000139249317173341006693762374554218361" + "99735720081420774878644714920465448063")), + field_value_type(integral_type("26449079556749456547763240104029704617197602953243811123341487416058796720985" + "30793364734851520804076509786066300688"))}}, + {"abcdef0123456789", + {field_value_type(integral_type("25719599515144616098862759599781083245320818219725699327118811068540459040324" + "01497739611428750762925771009739672760")), + field_value_type(integral_type("48152350957069938418503459090703763601658613290098485815305620880423150293107" + "3834859207979148213406515909166856065"))}}, + {"q128_" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqq", + {field_value_type(integral_type("16746159338985009492917568934031554970366258991142848241908114029620654980095" + "63818288046948236719654148630540204822")), + field_value_type(integral_type("25816575372444607942054642448052352758295864608466091303597503924099696329006" + "72887772936290792382770151227422762659"))}}, + {"a512_" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + {field_value_type(integral_type("99872323850197704338735859571501164993467800869061716944285932457586706162378" + "994013296878816389726622832817306892")), + field_value_type(integral_type("75080915218496132457991278757568526706694821515781542981734814458320346931034" + "5473734242537722102188109771665077578"))}} + // {"", {field_value_type(integral_type("")), field_value_type(integral_type(""))}} + }; + + for (auto &s : samples) { + check_hash_to_field_ro(std::get<0>(s), std::get<1>(s)); + } +} + +BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g2_h2f_shake128_test) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.10.1 + using curve_type = curves::bls12_381; + using group_type = typename curve_type::g2_type<>; + using field_type = typename group_type::field_type; + using field_value_type = typename field_type::value_type; + using integral_type = typename field_type::integral_type; + using hash_type = hashes::h2f, + hashes::h2f_default_params, + 128, + hashes::UniformityCount::uniform_count, + hashes::ExpandMsgVariant::rfc_xof>>; + + using samples_type = std::vector>>; + samples_type samples = { + {"", + {field_value_type(integral_type("21761119417140609572957506711724462644916292942987174604015733000612083054138" + "77868370459391860290442637242685798287"), + integral_type("21727803743924291497680999138943700735898742815755951136165147607237967756386" + "41300727609117779478067420156555937182")), + field_value_type(integral_type("19802774580858068514278700330311615707558747455624782896791901258745532214031" + "68804685581811930976162756736377819200"), + integral_type("30577482064538241631055790494561748316708062368356777820792422645161630521893" + "90202713360090520912664585635089365842"))}}, + {"abc", + {field_value_type(integral_type("28095779702340744474188222080117336804030388680055502193888265667402470600038" + "53667807528408681210194383505927321734"), + integral_type("13480905020538778032639559738025205303070065891728990555656586377754061695581" + "74504663705980198627002645830947565535")), + field_value_type(integral_type("36128837908863750412786113353103990083658782138245371922196435006135331142272" + "55727791939831017201995232349524111099"), + integral_type("37031718815542562878057377216607493299341531037255524917868423138783142182529" + "72527052232848741612107413733184042704"))}}, + {"abcdef0123456789", + {field_value_type(integral_type("34179051443373825021627221887887003686762026645123594023800727335353607515140" + "90249139105898909846372034808498893681"), + integral_type("18602926449762697029401068753653039886784602628583881790458942559844506726399" + "97323424814684516295366461881861836534")), + field_value_type(integral_type("13725831502352924801704573350984719213058089778288294729248198070849411653182" + "66758515896635824313576096391677734981"), + integral_type("36908193745246653651064804888056323355497509997526047701009643674942412752742" + "19038923167463498905572382098560535117"))}}, + {"q128_" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqq", + {field_value_type(integral_type("39599762187870594643873274175209553764202031577019663999380556114139666401464" + "89507356572246555322990727985468040245"), + integral_type("25676933779138698592679819807400247892045745812751340998780556381675609475573" + "09341944273444974680463976608552489852")), + field_value_type(integral_type("61454319429737261771070011869457935134248576585039662467468431549997609359625" + "6444120666417881167834118723680453590"), + integral_type("23955509127144125773005085188669236528208316300227858678645065700992358659384" + "54674609909635896529114812122026503129"))}}, + {"a512_" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + {field_value_type(integral_type("42031133646911283970924437529711587195926963466037233984948270009038220365544" + "5945666063808629865323003385081140252"), + integral_type("32382326666448732822661723450194270503118452492444836120698898827195542329051" + "10784475616069209850193778954228519664")), + field_value_type(integral_type("12731197979403258068394380733350947413090025310423363781063761800501631636886" + "27388411388878626108888409981407889320"), + integral_type("15029123207785810142032112101030614655730726369761948395001369689467321863650" + "57656474980051133773877281944958080905"))}}, + + // {"", + // {field_value_type(integral_type(""), + // integral_type("")), + // field_value_type(integral_type(""), + // integral_type(""))}}, + }; + + for (auto &s : samples) { + check_hash_to_field_ro(std::get<0>(s), std::get<1>(s)); + } +} + +BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g1_h2f_shake256_test) { + // field elements were generated using the SageMath code from https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve + using curve_type = curves::bls12_381; + using field_type = typename curve_type::base_field_type; + using field_value_type = typename field_type::value_type; + using integral_type = typename field_type::integral_type; + using hash_type = hashes::h2f, + hashes::h2f_default_params, + 128, + hashes::UniformityCount::uniform_count, + hashes::ExpandMsgVariant::rfc_xof>>; + + using samples_type = std::vector>>; + samples_type samples = { + {"", + {field_value_type(integral_type("35649413618876074642626806365137625720526779547687130805164279468893543348816" + "81149428744233836573075940920773556605")), + field_value_type(integral_type("32191598794272535593202043296699690894078346767469611555064692257309991804181" + "2868917504156030442189555841682260203"))}}, + {"abc", + {field_value_type(integral_type("36297070445601380522183773418551096131819097989283494533273211638846992997294" + "86359633941000674339086857170774012891")), + field_value_type(integral_type("21336734814454478909919797987655643716116374700180214090544223636910007807464" + "09314360354255496017833770999585612365"))}}, + {"abcdef0123456789", + {field_value_type(integral_type("89562627513935962103233763683462050306922022114977595123138177164512223976408" + "2253394057881856751461508824060407068")), + field_value_type(integral_type("26390405268558144935650411401535229593735188494011206900329278546785106492536" + "24259827299638645593197965314405990223"))}}, + {"q128_" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqq", + {field_value_type(integral_type("22916397665345561448194985375368991003209854878197341043956812081252109413817" + "62551072041089523763472685246541885147")), + field_value_type(integral_type("29915744450377534368569430780604829283215920795851547158261172894680433208614" + "31194687978643395782359715681390717481"))}}, + {"a512_" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + {field_value_type(integral_type("24547068103260723032692377284190124714469178784622226928569646544131198218365" + "12158594441511421199579041183882320701")), + field_value_type(integral_type("32777440595410240006428031495965340366546892470064030857364419905126509912456" + "78958004541570391981799856710821139287"))}} + // {"", {field_value_type(integral_type("")), field_value_type(integral_type(""))}} + }; + + for (auto &s : samples) { + check_hash_to_field_ro(std::get<0>(s), std::get<1>(s)); + } +} + +BOOST_AUTO_TEST_CASE(hash_to_field_bls12_381_g2_h2f_shake256_test) { + // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-J.10.1 + using curve_type = curves::bls12_381; + using group_type = typename curve_type::g2_type<>; + using field_type = typename group_type::field_type; + using field_value_type = typename field_type::value_type; + using integral_type = typename field_type::integral_type; + using hash_type = hashes::h2f, + hashes::h2f_default_params, + 128, + hashes::UniformityCount::uniform_count, + hashes::ExpandMsgVariant::rfc_xof>>; + + using samples_type = std::vector>>; + samples_type samples = { + {"", + {field_value_type(integral_type("21963274071619108128097264722317071301606486779929326898554083672936128235770" + "4338072415018530247540214055249982132"), + integral_type("10590351498334984848373840030203446950121731278087575746096550910348395558555" + "1845368665743236877541939312930239681")), + field_value_type(integral_type("28091471905464214407695546469896700624773788481198476844345274031808508333074" + "97632818619741493854405328865108683275"), + integral_type("30726366767257068092443502510012136173512294464519767218243017912162500672713" + "34346694333455334523250618559647124233"))}}, + {"abc", + {field_value_type(integral_type("23225806639179019890338382797325715438756600031652555722973808596165865668617" + "34165851712176216313509198818511530980"), + integral_type("32557071023082220791916058169457485364134976942295371950651552550860380978496" + "48899273319477344766487385190825894003")), + field_value_type(integral_type("32194294443752251899867889497549719798956652948195916403399424005829214370036" + "91862946903896256965180933287123015934"), + integral_type("28319630043143611222959994456903801307817254469122958785870712904900231118040" + "53145378372949657374193108898073660733"))}}, + {"abcdef0123456789", + {field_value_type(integral_type("17902175988373130734012933586467293569612298137867080532295054921824759111317" + "92567425530299937389989900138225324599"), + integral_type("12969006743881285697018500257524475024956462836065688657073044500573635075580" + "27645375674431249396430197967082812936")), + field_value_type(integral_type("34406529846799115946535633828620145267368064157958635700227172206263842971745" + "02640487083363023891622316284584216690"), + integral_type("28213835204899604742609273129426581197007138205118023703504592620948962976872" + "75979972257250936391927795870833532960"))}}, + {"q128_" + "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" + "qqqqqqqqqqqqqqqqqqq", + {field_value_type(integral_type("10092932943035553727564168499381428496298566886087918016632369681584459692382" + "01675258277772727721484256251128244060"), + integral_type("17168004723799863694173561785055094879931106899957934052491965588500285242621" + "24538058198857628689491715908814880409")), + field_value_type(integral_type("25719222627124083185067835874983100017932189620376996637741387888990217611488" + "60467345466576023662564107715706227472"), + integral_type("36331609886282561421947333390942915867716324305897456844342657503519500457553" + "83718695873025565472006812136924244469"))}}, + {"a512_" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + {field_value_type(integral_type("35495382464173722991366714917826997437591972701057816539555858479132737998763" + "6201901377834680498342583094405742933"), + integral_type("16036052280914287202478767463603457793835943149293145136061129905834330994782" + "51445849500798421048684965287365764494")), + field_value_type(integral_type("19494580623629045697224611727282567482926073920822674841457409389744912206228" + "80992714498950980540123997447376922328"), + integral_type("98171940250611754694458305588405551184270341958151133249793446650353577775558" + "2925716311702110312401790485459582370"))}}, + + // {"", + // {field_value_type(integral_type(""), + // integral_type("")), + // field_value_type(integral_type(""), + // integral_type(""))}}, + }; + + for (auto &s : samples) { + check_hash_to_field_ro(std::get<0>(s), std::get<1>(s)); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/hash/test/shake.cpp b/libs/hash/test/shake.cpp new file mode 100644 index 0000000000..4b4373fde1 --- /dev/null +++ b/libs/hash/test/shake.cpp @@ -0,0 +1,296 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Valeh Farzaliyev +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE shake_test + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +using namespace nil::crypto3; +using namespace nil::crypto3::accumulators; + +namespace boost { + namespace test_tools { + namespace tt_detail { + template class P, typename K, typename V> + struct print_log_value> { + void operator()(std::ostream &, P const &) { + } + }; + } // namespace tt_detail + } // namespace test_tools +} // namespace boost + +// template +// class fixture { +// public: +// accumulator_set> acc; +// typedef hashes::shake hash_t; + +// virtual ~fixture() { +// } +// }; + +const char *test_data = TEST_DATA; + +boost::property_tree::ptree string_data(const char *child_name) { + boost::property_tree::ptree root_data; + boost::property_tree::read_json(test_data, root_data); + boost::property_tree::ptree string_data = root_data.get_child(child_name); + + return string_data; +} + +BOOST_AUTO_TEST_SUITE(shake_stream_processor_data_driven_algorithm_test_suite) + +BOOST_DATA_TEST_CASE(shake_128_range_hash, string_data("data_128"), array_element) { + std::string out = hash>(array_element.first); + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} + +BOOST_DATA_TEST_CASE(shake_128_string_various_itr_value_hash, string_data("data_128"), array_element) { + std::string out = hash>(array_element.first.begin(), array_element.first.end()); + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} + +BOOST_DATA_TEST_CASE(shake_256_string_various_range_value_hash, string_data("data_256"), array_element) { + std::string out = hash>(array_element.first); + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} + +BOOST_DATA_TEST_CASE(shake_256_string_various_itr_value_hash, string_data("data_256"), array_element) { + std::string out = hash>(array_element.first.begin(), array_element.first.end()); + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(shake_stream_processor_data_driven_adaptor_test_suite) + +BOOST_DATA_TEST_CASE(shake_128_range_hash, string_data("data_128"), array_element) { + std::string out = array_element.first | adaptors::hashed>; + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} + +BOOST_DATA_TEST_CASE(shake_256_string_various_range_value_hash, string_data("data_256"), array_element) { + std::string out = array_element.first | adaptors::hashed>; + + BOOST_CHECK_EQUAL(out, array_element.second.data()); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(shake_stream_processor_test_suite) + +/* BOOST_AUTO_TEST_CASE(shake_128_shortmsg_bit1) { + // Known-answer test from https://keccak.team/archives.html + // Len = 5, Msg = 48 + std::array a = {0, 1, 0, 0, 1}; + hashes::shake<128>::digest_type d = hashes>(a); + + BOOST_CHECK_EQUAL("e4384016d64610d75e0a5d73821a02d524e847a25a571b5940cd6450", std::to_string(d).data()); +}*/ + +BOOST_AUTO_TEST_CASE(shake_128_shortmsg_byte1) { + // "a" + std::array a = {'\x61'}; + hashes::shake<128, 128>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL("85c8de88d28866bf0868090b3961162b", std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_128_shortmsg_byte2) { + // "abc" + std::array a = {'\x61', '\x62', '\x63'}; + hashes::shake<128, 256>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL("5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8", std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_128_shortmsg_byte3) { + // "message digest" + std::array a = {'\x6d', '\x65', '\x73', '\x73', '\x61', '\x67', '\x65', + '\x20', '\x64', '\x69', '\x67', '\x65', '\x73', '\x74'}; + hashes::shake<128, 384>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL( + "cbef732961b55b4c31396796577df491b6eed61d8949ce967226801e411e53f09544c13fe4df40fc8df5f9853e8541d0", + std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_256_shortmsg_byte1) { + // "a" + std::array a = {'\x61'}; + hashes::shake<256, 256>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL("867e2cb04f5a04dcbd592501a5e8fe9ceaafca50255626ca736c138042530ba4", std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_256_shortmsg_byte2) { + // "abc" + std::array a = {'\x61', '\x62', '\x63'}; + hashes::shake<256, 512>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL( + "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739d5a15bef186a5386c75744c0527e1faa9f8726e462a12a" + "4feb06bd8801e751e4", + std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_256_shortmsg_byte3) { + // "message digest" + std::array a = {'\x6d', '\x65', '\x73', '\x73', '\x61', '\x67', '\x65', + '\x20', '\x64', '\x69', '\x67', '\x65', '\x73', '\x74'}; + hashes::shake<256, 768>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL( + "718e224088856840ade4dc73487e15826a07ecb8ed5e2bda526cc1acddb99d006049815844be0c6c29b759db80b7daa684cb46d90f7eef" + "107d24aafcfaf0dacaca2888dfaa737694bc46d5c95f17c5cfe7b0c95cfd6a126dd9640c8e62e5ad1c", + std::to_string(d).data()); +} + +BOOST_AUTO_TEST_CASE(shake_256_shortmsg_byte4) { + // "message digest" + std::array a = {'\x61'}; + hashes::shake<256, 2048>::digest_type d = hash>(a); + + BOOST_CHECK_EQUAL( + "867e2cb04f5a04dcbd592501a5e8fe9ceaafca50255626ca736c138042530ba436b7b1ec0e06a279bc790733bb0aee6fa802683c7b3550" + "63c434e91189b0c651d092b01e55ce4d610b54a5466d02f88fc378096fb0dad0254857fe1e6381abc04e07e33d916935935636004896c5" + "b1253464f1cb5ea73b007bc5028bbbea13ebc28668dbfc26b1240ce4239f8d50627ddaa01641dfeaa9d2fef03dd025e0b82cf071fb9ca3" + "232c742d836b3cbcc8c3cba5b058b76795c177012314196dc822768991c0f16f8a655a731fd37ec92460d61ea722e2723c8681235c4cfa" + "70fdddfeefac1a892d652cfbaa02b138e3b2d050d550f0c977c024bc2aab0c3456a6afef", + std::to_string(d).data()); +} + +BOOST_AUTO_TEST_SUITE_END() + +// BOOST_AUTO_TEST_SUITE(shake_accumulator_test_suite) + +// BOOST_FIXTURE_TEST_CASE(shake_128_accumulator, fixture<128>) { +// // "abc" +// hash_t::construction::type::block_type m = {{}}; + +// m[0] = UINT64_C(0x0000000000636261); +// acc(m, accumulators::bits = 24); + +// hash_t::digest_type s = extract::hash(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8", std::to_string(s).data()); +// } + +// BOOST_FIXTURE_TEST_CASE(shake_256_accumulator, fixture<256>) { +// // "abc" +// hash_t::construction::type::block_type m = {{}}; + +// m[0] = UINT64_C(0x0000000000636261); +// acc(m, accumulators::bits = 24); + +// hash_t::digest_type s = extract::hash(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", std::to_string(s).data()); +// } + +// BOOST_AUTO_TEST_SUITE_END() + +// BOOST_AUTO_TEST_SUITE(shake_preprocessor_test_suite) + +// BOOST_AUTO_TEST_CASE(shake_128_preprocessor1) { +// accumulator_set> acc; +// hashes::shake<128>::digest_type s = extract::hash>(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", std::to_string(s).data()); +// } + +// BOOST_AUTO_TEST_CASE(shake_128_preprocessor2) { +// accumulator_set> acc; + +// acc(UINT64_C(0x0000000000000061), accumulators::bits = 8); +// acc(UINT64_C(0x0000000000000062), accumulators::bits = 8); +// acc(UINT64_C(0x0000000000000063), accumulators::bits = 8); + +// hashes::shake<128>::digest_type s = extract::hash>(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8", std::to_string(s).data()); +// } + +// BOOST_AUTO_TEST_CASE(shake_256_preprocessor1) { +// accumulator_set> acc; +// hashes::shake<256>::digest_type s = extract::hash>(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", std::to_string(s).data()); +// } + +// BOOST_AUTO_TEST_CASE(shake_256_preprocessor2) { +// accumulator_set> acc; + +// acc(UINT64_C(0x0000000000000061), accumulators::bits = 8); +// acc(UINT64_C(0x0000000000000062), accumulators::bits = 8); +// acc(UINT64_C(0x0000000000000063), accumulators::bits = 8); + +// hashes::shake<256>::digest_type s = extract::hash>(acc); + +// #ifdef CRYPTO3_HASH_SHOW_PROGRESS +// std::printf("%s\n", std::to_string(s).data()); +// #endif + +// BOOST_CHECK_EQUAL("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", std::to_string(s).data()); +// } + +// BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp b/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp index d945c291b7..08c85a14b0 100644 --- a/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp +++ b/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -87,8 +88,7 @@ namespace nil { if constexpr (algebra::is_field_element::value) { BOOST_STATIC_ASSERT_MSG( algebra::is_field_element::value, - "Hash type consumes field elements, but provided value is not a field element" - ); + "Hash type consumes field elements, but provided value is not a field element"); acc(data); } else { nil::marshalling::status_type status; @@ -114,7 +114,8 @@ namespace nil { return FieldType::value_type::one(); } - template std::array challenges() { @@ -132,10 +133,11 @@ namespace nil { }; template - struct fiat_shamir_heuristic_sequential - { + struct fiat_shamir_heuristic_sequential { typedef Hash hash_type; - typedef typename boost::multiprecision::cpp_int_modular_backend modular_backend_of_hash_size; + + typedef typename boost::multiprecision::cpp_int_modular_backend + modular_backend_of_hash_size; fiat_shamir_heuristic_sequential() : state(hash({0})) { } @@ -150,10 +152,9 @@ namespace nil { } template - typename std::enable_if_t< - !algebra::is_group_element::value && - !algebra::is_field_element::value> - operator()(const InputRange &r) { + typename std::enable_if_t::value && + !algebra::is_field_element::value> + operator()(const InputRange &r) { auto acc_convertible = hash(state); state = accumulators::extract::hash( hash(r, static_cast &>(acc_convertible))); @@ -167,52 +168,74 @@ namespace nil { } template - typename std::enable_if_t< - algebra::is_group_element::value || - algebra::is_field_element::value - > - operator()(element const& data) { + typename std::enable_if_t::value || + algebra::is_field_element::value> + operator()(element const &data) { nil::marshalling::status_type status; std::vector byte_data = nil::marshalling::pack(data, status); BOOST_ASSERT(status == nil::marshalling::status_type::success); auto acc_convertible = hash(state); state = accumulators::extract::hash( - hash(byte_data, static_cast &>(acc_convertible))); + hash(byte_data, static_cast &>(acc_convertible))); } template - // typename std::enable_if<(Hash::digest_bits >= Field::modulus_bits), - // typename Field::value_type>::type - typename Field::value_type challenge() { + typename std::enable_if<(Hash::digest_bits >= Field::modulus_bits), + typename Field::value_type>::type + challenge() { using digest_value_type = typename hash_type::digest_type::value_type; const std::size_t digest_value_bits = sizeof(digest_value_type) * CHAR_BIT; const std::size_t element_size = Field::number_bits / digest_value_bits + - (Field::number_bits % digest_value_bits == 0 ? 0 : 1); + (Field::number_bits % digest_value_bits == 0 ? 0 : 1); std::array data; state = hash(state); - // TODO(martun): for now we copy 256 bits into a larger group element. For example for - // mnt6_base_field<298ul> the first 42 bits will be zero. - // Use something like hash to field(h2f.hpp) for this. + std::size_t count = std::min(data.size(), state.size()); std::copy(state.begin(), state.begin() + count, data.begin() + data.size() - count); - + nil::marshalling::status_type status; - boost::multiprecision::number raw_result = + boost::multiprecision::number raw_result = nil::marshalling::pack(state, status); BOOST_ASSERT(status == nil::marshalling::status_type::success); return raw_result; } + template + typename std::enable_if<(Hash::digest_bits < Field::modulus_bits), typename Field::value_type>::type + challenge() { + + // TODO: check hash is not h2f type + using h2f_type = + hashes::h2f>; + + typename h2f_type::digest_type result = hash(state); + nil::marshalling::status_type status; + std::vector byte_data = + nil::marshalling::pack(result[0], status); + BOOST_ASSERT(status == nil::marshalling::status_type::success); + + std::size_t count = std::min(byte_data.size(), state.size()); + std::copy(byte_data.end() - count, byte_data.end(), state.begin()); + return result[0]; + } + template Integral int_challenge() { state = hash(state); nil::marshalling::status_type status; - boost::multiprecision::number raw_result = nil::marshalling::pack(state, status); - // If we remove the next line, raw_result is a much larger number, conversion to 'Integral' will overflow - // and in debug mode an assert will fire. In release mode nothing will change. + boost::multiprecision::number raw_result = + nil::marshalling::pack(state, status); + // If we remove the next line, raw_result is a much larger number, conversion to 'Integral' will + // overflow and in debug mode an assert will fire. In release mode nothing will change. raw_result &= ~Integral(0); return static_cast(raw_result); } @@ -239,12 +262,7 @@ namespace nil { struct fiat_shamir_heuristic_sequential< Hash, typename std::enable_if_t< - nil::crypto3::hashes::is_specialization_of< - nil::crypto3::hashes::poseidon, - Hash - >::value - > - > { + nil::crypto3::hashes::is_specialization_of::value>> { // After refactoring an attempt to remove this Nil Poseidon specialization was made. // The difference between challenge() for other hashes and for Nil Poseidon is // how the second challenge is produced. For the first call things are the same: @@ -266,7 +284,7 @@ namespace nil { template fiat_shamir_heuristic_sequential(const InputRange &r) { - if(r.size() != 0) { + if (r.size() != 0) { sponge.absorb(static_cast(hash(r))); } } @@ -281,18 +299,14 @@ namespace nil { } template - typename std::enable_if_t< - !algebra::is_group_element::value - > - operator()(const InputRange &r) { + typename std::enable_if_t::value> + operator()(const InputRange &r) { sponge.absorb(static_cast(hash(r))); } template - typename std::enable_if_t< - algebra::is_group_element::value - > - operator()(element const& data) { + typename std::enable_if_t::value> + operator()(element const &data) { auto affine = data.to_affine(); sponge.absorb(affine.X); sponge.absorb(affine.Y); @@ -346,8 +360,8 @@ namespace nil { }; } // namespace transcript - } // namespace zk - } // namespace crypto3 + } // namespace zk + } // namespace crypto3 } // namespace nil #endif // CRYPTO3_ZK_TRANSCRIPT_FIAT_SHAMIR_HEURISTIC_HPP diff --git a/libs/zk/test/transcript/transcript.cpp b/libs/zk/test/transcript/transcript.cpp index 1b124c21ac..d76bf86769 100644 --- a/libs/zk/test/transcript/transcript.cpp +++ b/libs/zk/test/transcript/transcript.cpp @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #include @@ -136,21 +139,17 @@ void test_transcript(typename curve_type::base_field_type::value_type const& exp BOOST_AUTO_TEST_CASE(mnt4_keccak) { test_transcript> - (0xb985b0419fda7e26db3867b38cbb55465717e8d3ff208768cac6949bd68c2b7_cppui_modular298); + (0x2b4e9c317f18745b6b89cbb97728923a2d797e261f8320d90f204192c7aabd2b397a0cc155c_cppui_modular298); } BOOST_AUTO_TEST_CASE(mnt6_keccak) { test_transcript> - (0x56d23a0a6f75fe3a7670906b341b29cdde80696fc418771e3c84910217546ef1_cppui_modular298); + (0x25a45c6b7d107961d135e640abfb1840cefd9c8ea318f7f33cd327cd55dabdd18c125d6c6b_cppui_modular298); } BOOST_AUTO_TEST_CASE(bls12_keccak) { - test_transcript> - (0x7cc24317960f68f067e0a1cfe610fe3db024d52b064ff2115ea0f594602f0784_cppui_modular381); - /* TODO: no marshalling for bls12-377 curve - test_transcript> - (0x0_cppui_modular377); - */ + test_transcript> + (0x122a878f445070db1680540fb6e8105eb8edd62767b2269d24ba2d76c319340226b15b9740c3ae669d995c3d48efc66c_cppui_modular381); } BOOST_AUTO_TEST_CASE(pallas_poseidon) {