h2c_expand.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Ilias Khairullin <ilias@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_ALGEBRA_CURVES_HASH_TO_CURVE_EXPAND_HPP
27 #define CRYPTO3_ALGEBRA_CURVES_HASH_TO_CURVE_EXPAND_HPP
28 
31 
33 
35 
38 
39 #include <boost/assert.hpp>
40 #include <boost/static_assert.hpp>
41 #include <boost/concept/assert.hpp>
42 
43 #include <array>
44 #include <type_traits>
45 #include <iterator>
46 
47 namespace nil {
48  namespace crypto3 {
49  namespace algebra {
50  namespace curves {
51  namespace detail {
52  using namespace nil::crypto3::detail;
53  template<std::size_t k, typename HashType,
55  typename = typename std::enable_if<
56  std::is_same<std::uint8_t, typename HashType::digest_type::value_type>::value>::type>
58  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1
59  BOOST_STATIC_ASSERT_MSG(HashType::block_bits % 8 == 0, "r_in_bytes is not a multiple of 8");
60  BOOST_STATIC_ASSERT_MSG(HashType::digest_bits % 8 == 0, "b_in_bytes is not a multiple of 8");
61  BOOST_STATIC_ASSERT_MSG(HashType::digest_bits >= 2 * k,
62  "k-bit collision resistance is not fulfilled");
63 
64  constexpr static const std::size_t b_in_bytes = HashType::digest_bits / 8;
65  constexpr static const std::size_t r_in_bytes = HashType::block_bits / 8;
66 
67  constexpr static const std::array<std::uint8_t, r_in_bytes> Z_pad {0};
68 
69  public:
70  template<typename InputMsgType, typename InputDstType, typename OutputType,
71  typename = typename std::enable_if<
72  std::is_same<std::uint8_t, typename InputMsgType::value_type>::value &&
73  std::is_same<std::uint8_t, typename InputDstType::value_type>::value &&
74  std::is_same<std::uint8_t, typename OutputType::value_type>::value>::type>
75  static inline void process(const std::size_t len_in_bytes, const InputMsgType &msg,
76  const InputDstType &dst, OutputType &uniform_bytes) {
77  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<InputMsgType>));
78  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<InputDstType>));
79  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<OutputType>));
80  BOOST_CONCEPT_ASSERT((boost::WriteableRangeConcept<OutputType>));
81 
82  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1
83  BOOST_ASSERT(len_in_bytes < 0x10000);
84  BOOST_ASSERT(std::distance(dst.begin(), dst.end()) >= 16 &&
85  std::distance(dst.begin(), dst.end()) <= 255);
86  BOOST_ASSERT(std::distance(uniform_bytes.begin(), uniform_bytes.end()) >= len_in_bytes);
87 
88  const std::array<std::uint8_t, 2> l_i_b_str = {
89  static_cast<std::uint8_t>(len_in_bytes >> 8u),
90  static_cast<std::uint8_t>(len_in_bytes % 0x100)};
91  const std::size_t ell = static_cast<std::size_t>(len_in_bytes / b_in_bytes) +
92  static_cast<std::size_t>(len_in_bytes % b_in_bytes != 0);
93 
94  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1
95  BOOST_ASSERT(ell <= 255);
96 
97  // TODO: use accumulators when they will be fixed
98  // accumulator_set<HashType> b0_acc;
99  // hash<HashType>(Z_pad, b0_acc);
100  // hash<HashType>(msg, b0_acc);
101  // hash<HashType>(l_i_b_str, b0_acc);
102  // hash<HashType>(std::array<std::uint8_t, 1> {0}, b0_acc);
103  // hash<HashType>(dst, b0_acc);
104  // hash<HashType>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst.size())},
105  // b0_acc); typename HashType::digest_type b0 =
106  // accumulators::extract::hash<HashType>(b0_acc);
107  std::vector<std::uint8_t> msg_prime;
108  msg_prime.insert(msg_prime.end(), Z_pad.begin(), Z_pad.end());
109  msg_prime.insert(msg_prime.end(), msg.begin(), msg.end());
110  msg_prime.insert(msg_prime.end(), l_i_b_str.begin(), l_i_b_str.end());
111  msg_prime.insert(msg_prime.end(), static_cast<std::uint8_t>(0));
112  msg_prime.insert(msg_prime.end(), dst.begin(), dst.end());
113  msg_prime.insert(msg_prime.end(),
114  static_cast<std::uint8_t>(std::distance(dst.begin(), dst.end())));
115  typename HashType::digest_type b0 = hash<HashType>(msg_prime);
116 
117  // TODO: use accumulators when they will be fixed
118  // accumulator_set<HashType> bi_acc;
119  // hash<HashType>(b0, bi_acc);
120  // hash<HashType>(std::array<std::uint8_t, 1> {1}, bi_acc);
121  // hash<HashType>(dst, bi_acc);
122  // hash<HashType>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst.size())},
123  // bi_acc); typename HashType::digest_type bi =
124  // accumulators::extract::hash<HashType>(bi_acc); std::copy(bi.begin(), bi.end(),
125  // uniform_bytes.begin());
126  std::vector<std::uint8_t> b_i_str;
127  b_i_str.insert(b_i_str.end(), b0.begin(), b0.end());
128  b_i_str.insert(b_i_str.end(), static_cast<std::uint8_t>(1));
129  b_i_str.insert(b_i_str.end(), dst.begin(), dst.end());
130  b_i_str.insert(b_i_str.end(),
131  static_cast<std::uint8_t>(std::distance(dst.begin(), dst.end())));
132  typename HashType::digest_type bi = hash<HashType>(b_i_str);
133  std::copy(bi.begin(), bi.end(), uniform_bytes.begin());
134 
135  typename HashType::digest_type xored_b;
136  for (std::size_t i = 2; i <= ell; i++) {
137  // TODO: use accumulators when they will be fixed
138  // accumulator_set<HashType> bi_acc;
139  // strxor(b0, bi, xored_b);
140  // hash<HashType>(xored_b, bi_acc);
141  // hash<HashType>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(i)}, bi_acc);
142  // hash<HashType>(dst, bi_acc);
143  // hash<HashType>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst.size())},
144  // bi_acc);
145  // bi = accumulators::extract::hash<HashType>(bi_acc);
146  // std::copy(bi.begin(), bi.end(), uniform_bytes.begin() + (i - 1) * b_in_bytes);
147  strxor(b0, bi, xored_b);
148  std::vector<std::uint8_t> b_i_str;
149  b_i_str.insert(b_i_str.end(), xored_b.begin(), xored_b.end());
150  b_i_str.insert(b_i_str.end(), static_cast<std::uint8_t>(i));
151  b_i_str.insert(b_i_str.end(), dst.begin(), dst.end());
152  b_i_str.insert(b_i_str.end(),
153  static_cast<std::uint8_t>(std::distance(dst.begin(), dst.end())));
154  bi = hash<HashType>(b_i_str);
155  std::copy(bi.begin(), bi.end(), uniform_bytes.begin() + (i - 1) * b_in_bytes);
156  }
157  }
158  };
159  } // namespace detail
160  } // namespace curves
161  } // namespace algebra
162  } // namespace crypto3
163 } // namespace nil
164 
165 #endif // CRYPTO3_ALGEBRA_CURVES_HASH_TO_CURVE_EXPAND_HPP
static void process(const std::size_t len_in_bytes, const InputMsgType &msg, const InputDstType &dst, OutputType &uniform_bytes)
Definition: h2c_expand.hpp:75
constexpr std::enable_if< std::is_same< typename std::iterator_traits< InputIterator1 >::value_type, typename std::iterator_traits< InputIterator2 >::value_type >::value, OutputIterator >::type strxor(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator out)
Definition: algebra/include/nil/crypto3/algebra/algorithms/strxor.hpp:42
Definition: algebra/include/nil/crypto3/detail/make_array.hpp:33
Definition: pair.hpp:31