Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

261 shake function orand map to field for transcript #302

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libs/hash/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
69 changes: 66 additions & 3 deletions libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ namespace nil {
namespace detail {
template<std::size_t k, std::size_t len_in_bytes, typename Hash,
/// Hash::digest_type is required to be uint8_t[]
typename = typename std::enable_if<std::is_same<
std::uint8_t,
typename std::iterator_traits<typename Hash::digest_type>::value_type>::value>::type>
typename = typename std::enable_if<
std::is_same<std::uint8_t, typename Hash::digest_type::value_type>::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");
Expand Down Expand Up @@ -136,6 +135,70 @@ namespace nil {
return uniform_bytes;
}
};

template<std::size_t k, std::size_t len_in_bytes, typename Hash,
/// Hash::digest_type is required to be uint8_t[].
typename = typename std::enable_if<
std::is_same<std::uint8_t, typename Hash::digest_type::value_type>::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<std::uint8_t, 2> l_i_b_str = {
static_cast<std::uint8_t>(len_in_bytes >> 8u), static_cast<std::uint8_t>(len_in_bytes % 0x100)};
constexpr static std::size_t ell = static_cast<std::size_t>(len_in_bytes / b_in_bytes) +
static_cast<std::size_t>(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<std::uint8_t, len_in_bytes> result_type;
typedef accumulator_set<Hash> internal_accumulator_type;

static inline void init_accumulator(internal_accumulator_type &acc) {

}

template<typename InputRange>
static inline void update(internal_accumulator_type &acc, const InputRange &range) {
BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<InputRange>));

hash<Hash>(range, acc);
}

template<typename InputIterator>
static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<InputIterator>));

hash<Hash>(first, last, acc);
}

template<typename DstRange>
static inline typename std::enable_if<
std::is_same<std::uint8_t,
typename std::iterator_traits<typename DstRange::iterator>::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<Hash>(l_i_b_str, b0_acc);
hash<Hash>(dst, b0_acc);
hash<Hash>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst_size)}, b0_acc);
typename Hash::digest_type b0 = ::nil::crypto3::accumulators::extract::hash<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
Expand Down
132 changes: 131 additions & 1 deletion libs/hash/include/nil/crypto3/hash/detail/h2f/h2f_suites.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <nil/crypto3/algebra/curves/bls12.hpp>

#include <nil/crypto3/hash/sha2.hpp>
#include <nil/crypto3/hash/keccak.hpp>
#include <nil/crypto3/hash/shake.hpp>

namespace nil {
namespace crypto3 {
Expand Down Expand Up @@ -74,8 +76,136 @@ namespace nil {
/// L = ceil((ceil(log2(p)) + k) / 8)
constexpr static std::size_t L = 64;
};

template<>
struct h2f_suite<typename algebra::curves::bls12_381::base_field_type, shake<128, 1024>, 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<std::uint8_t, 32> 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<typename algebra::fields::fp2<typename algebra::curves::bls12_381::base_field_type>,
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<std::uint8_t, 32> 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<typename algebra::curves::bls12_381::base_field_type, shake<256, 1024>, 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<std::uint8_t, 32> 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<typename algebra::fields::fp2<typename algebra::curves::bls12_381::base_field_type>,
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<std::uint8_t, 32> 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<typename algebra::curves::pallas::base_field_type, keccak_1600<256>, 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<std::uint8_t, 30> 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<typename algebra::curves::mnt4_298::base_field_type, keccak_1600<256>, 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<std::uint8_t, 31> 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<typename algebra::curves::mnt6_298::base_field_type, keccak_1600<256>, 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<std::uint8_t, 31> 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
Original file line number Diff line number Diff line change
Expand Up @@ -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<stream_endian::big_octet_big_bit, stream_endian::little_octet_little_bit, word_bits,
block_words>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2024 Valeh Farzaliyev <[email protected]>
//
// 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 <nil/crypto3/hash/detail/keccak/keccak_impl.hpp>
#include <nil/crypto3/hash/detail/shake/shake_policy.hpp>

#include <array>

namespace nil {
namespace crypto3 {
namespace hashes {
namespace detail {
template<std::size_t HalfCapacity>
struct shake_functions : public shake_policy<HalfCapacity> {
using policy_type = shake_policy<HalfCapacity>;

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<word_type, round_constants_size>;

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<policy_type>::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
Loading
Loading