h2c_functions.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 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_HASH_DETAIL_H2C_FUNCTIONS_HPP
27 #define CRYPTO3_HASH_DETAIL_H2C_FUNCTIONS_HPP
28 
29 #include <cstdint>
30 #include <array>
31 #include <vector>
32 #include <iterator>
33 #include <type_traits>
34 
35 #include <boost/assert.hpp>
36 #include <boost/static_assert.hpp>
37 #include <boost/concept/assert.hpp>
38 
39 #include <nil/crypto3/multiprecision/cpp_int.hpp>
40 #include <nil/marshalling/endianness.hpp>
41 #include <nil/marshalling/algorithms/pack.hpp>
42 #include <nil/crypto3/marshalling/multiprecision/types/integral.hpp>
43 
45 
47 
48 #include <nil/crypto3/detail/strxor.hpp>
49 
51 
54 
55 namespace nil {
56  namespace crypto3 {
57  namespace hashes {
58  namespace detail {
59  template<typename FieldParams>
61  using modular_type = typename FieldParams::modular_type;
62 
63  static const modular_type two =
65 
66  return static_cast<bool>(e.data % two);
67  }
68 
69  template<typename FieldParams>
72  using modular_type = typename FieldParams::modular_type;
73 
74  static const modular_type two = modular_type(2, underlying_type::modulus);
75 
76  modular_type sign_0 = e.data[0].data % two;
77  bool zero_0 = e.data[0].data.is_zero();
78  modular_type sign_1 = e.data[1].data % two;
79  return static_cast<bool>(sign_0) || (zero_0 && static_cast<bool>(sign_1));
80  }
81 
82  template<typename Group>
83  struct iso_map;
84 
85  // 11-isogeny map for BLS12-381 G1
86  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-E.2
87  template<typename Coordinates, typename Form>
88  class iso_map<typename algebra::curves::bls12_381::g1_type<Coordinates, Form>> {
91 
92  typedef typename suite_type::group_value_type group_value_type;
93  typedef typename suite_type::field_value_type field_value_type;
94  typedef typename suite_type::integral_type integral_type;
95 
96  // TODO: change integral_type on field_value_type when constexpr will be finished
97  constexpr static std::array<integral_type, 12> k_x_num = {
98  0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7_cppui381,
99  0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb_cppui381,
100  0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0_cppui381,
101  0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861_cppui381,
102  0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9_cppui381,
103  0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983_cppui381,
104  0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84_cppui381,
105  0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e_cppui381,
106  0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317_cppui381,
107  0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e_cppui381,
108  0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b_cppui381,
109  0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229_cppui381};
110 
111  constexpr static std::array<integral_type, 10> k_x_den = {
112  0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c_cppui381,
113  0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff_cppui381,
114  0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19_cppui381,
115  0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8_cppui381,
116  0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e_cppui381,
117  0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5_cppui381,
118  0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a_cppui381,
119  0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e_cppui381,
120  0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641_cppui381,
121  0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a_cppui381};
122 
123  constexpr static std::array<integral_type, 16> k_y_num = {
124  0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33_cppui381,
125  0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696_cppui381,
126  0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6_cppui381,
127  0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb_cppui381,
128  0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb_cppui381,
129  0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0_cppui381,
130  0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2_cppui381,
131  0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29_cppui381,
132  0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587_cppui381,
133  0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30_cppui381,
134  0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132_cppui381,
135  0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e_cppui381,
136  0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8_cppui381,
137  0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133_cppui381,
138  0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b_cppui381,
139  0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604_cppui381};
140 
141  constexpr static std::array<integral_type, 15> k_y_den = {
142  0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1_cppui381,
143  0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d_cppui381,
144  0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2_cppui381,
145  0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416_cppui381,
146  0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d_cppui381,
147  0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac_cppui381,
148  0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c_cppui381,
149  0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9_cppui381,
150  0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a_cppui381,
151  0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55_cppui381,
152  0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8_cppui381,
153  0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092_cppui381,
154  0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc_cppui381,
155  0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7_cppui381,
156  0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f_cppui381};
157 
158  public:
159  static inline group_value_type process(const group_value_type &ci) {
160  field_value_type x_num = field_value_type::zero();
161  field_value_type x_den = field_value_type::zero();
162  field_value_type y_num = field_value_type::zero();
163  field_value_type y_den = field_value_type::zero();
164 
165  std::vector<field_value_type> xi_powers = [&ci]() {
166  std::vector<field_value_type> xi_powers {field_value_type::one()};
167  for (std::size_t i = 0; i < 15; i++) {
168  xi_powers.emplace_back(xi_powers.back() * ci.X);
169  }
170  return xi_powers;
171  }();
172 
173  for (std::size_t i = 0; i < k_x_den.size(); i++) {
174  x_den += field_value_type(k_x_den[i]) * xi_powers[i];
175  }
176  x_den += xi_powers[k_x_den.size()];
177 
178  for (std::size_t i = 0; i < k_y_den.size(); i++) {
179  y_den += field_value_type(k_y_den[i]) * xi_powers[i];
180  }
181  y_den += xi_powers[k_y_den.size()];
182 
183  if (x_den.is_zero() || y_den.is_zero()) {
184  return group_value_type::one();
185  }
186 
187  for (std::size_t i = 0; i < k_x_num.size(); i++) {
188  x_num += field_value_type(k_x_num[i]) * xi_powers[i];
189  }
190 
191  for (std::size_t i = 0; i < k_y_num.size(); i++) {
192  y_num += field_value_type(k_y_num[i]) * xi_powers[i];
193  }
194 
195  return group_value_type(x_num / x_den, ci.Y * y_num / y_den, field_value_type::one());
196  }
197  };
198 
199  // 3-isogeny map for BLS12-381 G2
200  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#appendix-E.3
201  template<typename Coordinates, typename Form>
202  class iso_map<typename algebra::curves::bls12_381::g2_type<Coordinates, Form>> {
203  typedef typename algebra::curves::bls12_381::g2_type<Coordinates, Form> group_type;
205 
206  typedef typename suite_type::group_value_type group_value_type;
207  typedef typename suite_type::field_value_type field_value_type;
208  typedef typename suite_type::integral_type integral_type;
209 
210  // TODO: change integral_type on field_value_type when constexpr will be finished
211  constexpr static std::array<std::array<integral_type, 2>, 4> k_x_num = {
212  {{{0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6_cppui381,
213  0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6_cppui381}},
214  {{0,
215  0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a_cppui381}},
216  {{0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e_cppui381,
217  0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d_cppui381}},
218  {{0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1_cppui381,
219  0}}}};
220 
221  constexpr static std::array<std::array<integral_type, 2>, 2> k_x_den = {
222  {{{0,
223  0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63_cppui381}},
224  {{0xc,
225  0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f_cppui381}}}};
226 
227  constexpr static std::array<std::array<integral_type, 2>, 4> k_y_num = {
228  {{{0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706_cppui381,
229  0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706_cppui381}},
230  {{0,
231  0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be_cppui381}},
232  {{0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c_cppui381,
233  0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f_cppui381}},
234  {{0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10_cppui381,
235  0}}}};
236 
237  constexpr static std::array<std::array<integral_type, 2>, 3> k_y_den = {
238  {{{0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb_cppui381,
239  0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb_cppui381}},
240  {{0,
241  0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3_cppui381}},
242  {{0x12,
243  0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99_cppui381}}}};
244 
245  public:
246  static inline group_value_type process(const group_value_type &ci) {
247  field_value_type x_num = field_value_type::zero();
248  field_value_type x_den = field_value_type::zero();
249  field_value_type y_num = field_value_type::zero();
250  field_value_type y_den = field_value_type::zero();
251 
252  std::vector<field_value_type> xi_powers = [&ci]() {
253  std::vector<field_value_type> xi_powers {field_value_type::one()};
254  for (std::size_t i = 0; i < 3; i++) {
255  auto v = xi_powers.back();
256  xi_powers.emplace_back(xi_powers.back() * ci.X);
257  }
258  return xi_powers;
259  }();
260 
261  for (std::size_t i = 0; i < k_x_den.size(); i++) {
262  x_den += field_value_type(k_x_den[i][0], k_x_den[i][1]) * xi_powers[i];
263  }
264  x_den += xi_powers[k_x_den.size()];
265 
266  for (std::size_t i = 0; i < k_y_den.size(); i++) {
267  y_den += field_value_type(k_y_den[i][0], k_y_den[i][1]) * xi_powers[i];
268  }
269  y_den += xi_powers[k_y_den.size()];
270 
271  if (x_den.is_zero() || y_den.is_zero()) {
272  return group_value_type::one();
273  }
274 
275  for (std::size_t i = 0; i < k_x_num.size(); i++) {
276  x_num += field_value_type(k_x_num[i][0], k_x_num[i][1]) * xi_powers[i];
277  }
278 
279  for (std::size_t i = 0; i < k_y_num.size(); i++) {
280  y_num += field_value_type(k_y_num[i][0], k_y_num[i][1]) * xi_powers[i];
281  }
282 
283  return group_value_type(x_num / x_den, ci.Y * y_num / y_den, field_value_type::one());
284  }
285  };
286 
287  template<typename Group>
288  struct m2c_simple_swu {
290 
291  typedef typename suite_type::group_value_type group_value_type;
292  typedef typename suite_type::field_value_type field_value_type;
293 
294  static inline group_value_type process(const field_value_type &u) {
295  // TODO: We assume that Z meets the following criteria -- correct for predefined suites,
296  // but wrong in general case
297  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-6.6.2
298  // Preconditions:
299  // 1. Z is non-square in F,
300  // 2. Z != -1 in F,
301  // 3. the polynomial g(x) - Z is irreducible over F, and
302  // 4. g(B / (Z * A)) is square in F.
303  static const field_value_type one = field_value_type::one();
304 
305  field_value_type tv1 = (suite_type::Z.pow(2) * u.pow(4) + suite_type::Z * u.pow(2)).inversed();
306  field_value_type x1 = (-suite_type::Bi / suite_type::Ai) * (one + tv1);
307  if (tv1.is_zero()) {
308  x1 = suite_type::Bi / (suite_type::Z * suite_type::Ai);
309  }
310  field_value_type gx1 = x1.pow(3) + suite_type::Ai * x1 + suite_type::Bi;
311  field_value_type x2 = suite_type::Z * u.pow(2) * x1;
312  field_value_type gx2 = x2.pow(3) + suite_type::Ai * x2 + suite_type::Bi;
313  field_value_type x, y;
314  if (gx1.is_square()) {
315  x = x1;
316  y = gx1.sqrt();
317  } else {
318  x = x2;
319  y = gx2.sqrt();
320  }
321  if (sgn0(u) != sgn0(y)) {
322  y = -y;
323  }
324  return group_value_type(x, y, one);
325  }
326  };
327 
328  template<typename Group>
331 
332  typedef typename suite_type::group_value_type group_value_type;
333  typedef typename suite_type::field_value_type field_value_type;
334 
335  static inline group_value_type process(const field_value_type &u) {
337  return iso_map<Group>::process(ci);
338  }
339  };
340 
341  template<typename Group>
342  struct map_to_curve;
343 
344  template<typename Coordinates, typename Form>
345  struct map_to_curve<typename algebra::curves::bls12_381::g1_type<Coordinates, Form>>
346  : m2c_simple_swu_zeroAB<typename algebra::curves::bls12_381::g1_type<Coordinates, Form>> { };
347 
348  template<typename Coordinates, typename Form>
349  struct map_to_curve<typename algebra::curves::bls12_381::g2_type<Coordinates, Form>>
350  : m2c_simple_swu_zeroAB<typename algebra::curves::bls12_381::g2_type<Coordinates, Form>> { };
351 
352  template<std::size_t k,
353  std::size_t len_in_bytes,
354  typename Hash,
355  typename PublicParams,
357  typename = typename std::enable_if<
358  std::is_same<std::uint8_t, typename Hash::digest_type::value_type>::value>::type>
360  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1
361  static_assert(Hash::block_bits % 8 == 0, "r_in_bytes is not a multiple of 8");
362  static_assert(Hash::digest_bits % 8 == 0, "b_in_bytes is not a multiple of 8");
363  static_assert(Hash::digest_bits >= 2 * k, "k-bit collision resistance is not fulfilled");
364  static_assert(len_in_bytes < 0x10000, "len_in_bytes should be less than 0x10000");
365 
366  constexpr static std::size_t b_in_bytes = Hash::digest_bits / 8;
367  constexpr static std::size_t r_in_bytes = Hash::block_bits / 8;
368  constexpr static std::array<std::uint8_t, 2> l_i_b_str = {
369  static_cast<std::uint8_t>(len_in_bytes >> 8u), static_cast<std::uint8_t>(len_in_bytes % 0x100)};
370  constexpr static std::size_t ell = static_cast<std::size_t>(len_in_bytes / b_in_bytes) +
371  static_cast<std::size_t>(len_in_bytes % b_in_bytes != 0);
372  constexpr static const std::array<std::uint8_t, r_in_bytes> Z_pad {0};
373 
374  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-5.4.1
375  static_assert(ell <= 255, "ell should be less than 256");
376 
377  public:
378  typedef std::array<std::uint8_t, len_in_bytes> result_type;
380 
381  static inline void init_accumulator(internal_accumulator_type &acc) {
382  hash<Hash>(Z_pad, acc);
383  }
384 
385  template<typename InputRange>
386  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
387  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<InputRange>));
388 
389  hash<Hash>(range, acc);
390  }
391 
392  template<typename InputIterator>
393  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
394  BOOST_CONCEPT_ASSERT((boost::InputIteratorConcept<InputIterator>));
395 
396  hash<Hash>(first, last, acc);
397  }
398 
400  auto dst_size = std::distance(std::cbegin(PublicParams::dst), std::cend(PublicParams::dst));
401  assert(dst_size >= 16 && dst_size <= 255);
402 
403  hash<Hash>(l_i_b_str, b0_acc);
404  hash<Hash>(std::array<std::uint8_t, 1> {0}, b0_acc);
405  hash<Hash>(PublicParams::dst, b0_acc);
406  hash<Hash>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst_size)}, b0_acc);
407  typename Hash::digest_type b0 = ::nil::crypto3::accumulators::extract::hash<Hash>(b0_acc);
408 
409  result_type uniform_bytes;
411  hash<Hash>(b0, bi_acc);
412  hash<Hash>(std::array<std::uint8_t, 1> {1}, bi_acc);
413  hash<Hash>(PublicParams::dst, bi_acc);
414  hash<Hash>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst_size)}, bi_acc);
415  typename Hash::digest_type bi = ::nil::crypto3::accumulators::extract::hash<Hash>(bi_acc);
416  std::copy(bi.begin(), bi.end(), uniform_bytes.begin());
417 
418  typename Hash::digest_type xored_b;
419  for (std::size_t i = 2; i <= ell; i++) {
421  ::nil::crypto3::detail::strxor(b0, bi, xored_b.begin());
422  hash<Hash>(xored_b, bi_acc);
423  hash<Hash>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(i)}, bi_acc);
424  hash<Hash>(PublicParams::dst, bi_acc);
425  hash<Hash>(std::array<std::uint8_t, 1> {static_cast<std::uint8_t>(dst_size)}, bi_acc);
426  bi = ::nil::crypto3::accumulators::extract::hash<Hash>(bi_acc);
427  std::copy(bi.begin(), bi.end(), uniform_bytes.begin() + (i - 1) * b_in_bytes);
428  }
429 
430  return uniform_bytes;
431  }
432  };
433 
434  template<typename Group,
435  typename PublicParams,
436  UniformityCount uniformity_count,
437  ExpandMsgVariant expand_msg_variant = ExpandMsgVariant::rfc_xmd,
438  typename = void>
439  struct ep_map;
440 
441  template<typename Group,
442  typename PublicParams,
443  UniformityCount uniformity_count,
444  ExpandMsgVariant expand_msg_variant>
445  struct ep_map<Group,
446  PublicParams,
447  uniformity_count,
448  expand_msg_variant,
449  typename std::enable_if< // algebra::is_group_element<typename
450  // Group::value_type>::value &&
451  (ExpandMsgVariant::rfc_xmd == expand_msg_variant)>::type> {
453 
454  typedef typename suite_type::group_value_type group_value_type;
455  typedef typename suite_type::field_type field_type;
456  typedef typename suite_type::field_value_type field_value_type;
457  typedef typename suite_type::modular_type modular_type;
458  typedef typename suite_type::integral_type integral_type;
459  typedef typename suite_type::hash_type hash_type;
460 
461  constexpr static std::size_t digest_bits = hash_type::digest_bits;
462  constexpr static std::size_t modulus_bits = field_type::modulus_bits;
463 
464  constexpr static std::size_t m = suite_type::m;
465  constexpr static std::size_t L = suite_type::L;
466  constexpr static std::size_t k = suite_type::k;
467  constexpr static std::size_t count = static_cast<std::size_t>(uniformity_count);
468 
469  static_assert(count == 1 || count == 2, "unavailable count value");
470 
471  constexpr static std::size_t len_in_bytes = count * m * L;
472 
476 
477  static inline void init_accumulator(internal_accumulator_type &acc) {
478  expand_message_type::init_accumulator(acc);
479  }
480 
481  template<typename InputRange>
482  static inline void update(internal_accumulator_type &acc, const InputRange &range) {
483  expand_message_type::update(acc, range);
484  }
485 
486  template<typename InputIterator>
487  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
488  expand_message_type::update(acc, first, last);
489  }
490 
491  // TODO: use type deducing to element_fp instead of arity, make FieldParams public for this
492  template<std::size_t arity = m, typename std::enable_if<1 == arity, bool>::type = true>
493  static inline std::array<field_value_type, count> hash_to_field(internal_accumulator_type &acc) {
494  typename expand_message_type::result_type uniform_bytes = expand_message_type::process(acc);
495 
496  std::array<modular_type, m> coordinates;
497  std::array<field_value_type, count> result;
498  for (std::size_t i = 0; i < count; i++) {
499  for (std::size_t j = 0; j < m; j++) {
500  auto elm_offset = L * (j + i * m);
501 
502  // TODO: creating copy of range is a bottleneck:
503  // extend marshaling interface by function supporting initialization from
504  // container which length is less than modulus_octets
505  std::vector<std::uint8_t> imported_octets;
506  std::copy(std::cbegin(uniform_bytes) + elm_offset,
507  std::cbegin(uniform_bytes) + elm_offset + L,
508  std::back_inserter(imported_octets));
509  nil::marshalling::status_type status;
510  multiprecision::cpp_int tmp = nil::marshalling::pack<nil::marshalling::option::big_endian>(imported_octets, status);
511  coordinates[j] = modular_type(tmp, suite_type::p);
512  }
513  result[i] = coordinates[0];
514  }
515 
516  return result;
517  }
518 
519  // TODO: use type deducing to element_fp2 instead of arity, make FieldParams public for this
520  template<std::size_t arity = m, typename std::enable_if<2 == arity, bool>::type = true>
521  static inline std::array<field_value_type, count> hash_to_field(internal_accumulator_type &acc) {
522  typename expand_message_type::result_type uniform_bytes = expand_message_type::process(acc);
523 
524  std::array<modular_type, m> coordinates;
525  std::array<field_value_type, count> result;
526  for (std::size_t i = 0; i < count; i++) {
527  for (std::size_t j = 0; j < m; j++) {
528  auto elm_offset = L * (j + i * m);
529 
530  // TODO: creating copy of range is a bottleneck:
531  // extend marshaling interface by function supporting initialization from
532  // container which length is less than modulus_octets
533  std::vector<std::uint8_t> imported_octets;
534  std::copy(std::cbegin(uniform_bytes) + elm_offset,
535  std::cbegin(uniform_bytes) + elm_offset + L,
536  std::back_inserter(imported_octets));
537  nil::marshalling::status_type status;
538  multiprecision::cpp_int tmp = nil::marshalling::pack<nil::marshalling::option::big_endian>(imported_octets, status);
539  coordinates[j] = modular_type(tmp, suite_type::p);
540  }
541  result[i] = field_value_type(coordinates[0], coordinates[1]);
542  }
543 
544  return result;
545  }
546 
548  return R * suite_type::h_eff;
549  }
550 
552  auto u = hash_to_field(acc);
555  return clear_cofactor(Q0 + Q1);
556  }
557  };
558  } // namespace detail
559  } // namespace hashes
560  } // namespace crypto3
561 } // namespace nil
562 
563 #endif // CRYPTO3_HASH_DETAIL_H2C_FUNCTIONS_HPP
typename detail::bls12_g2< Version, Form, Coordinates > g2_type
Definition: curves/bls12.hpp:63
typename detail::bls12_g1< Version, Form, Coordinates > g1_type
Definition: curves/bls12.hpp:59
Definition: detail/element/fp2.hpp:39
policy_type::underlying_type underlying_type
Definition: detail/element/fp2.hpp:52
data_type data
Definition: detail/element/fp2.hpp:56
Definition: h2c_functions.hpp:359
accumulator_set< Hash > internal_accumulator_type
Definition: h2c_functions.hpp:379
static result_type process(internal_accumulator_type &b0_acc)
Definition: h2c_functions.hpp:399
static void update(internal_accumulator_type &acc, const InputRange &range)
Definition: h2c_functions.hpp:386
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: h2c_functions.hpp:393
std::array< std::uint8_t, len_in_bytes > result_type
Definition: h2c_functions.hpp:375
static void init_accumulator(internal_accumulator_type &acc)
Definition: h2c_functions.hpp:381
static group_value_type process(const group_value_type &ci)
Definition: h2c_functions.hpp:159
static group_value_type process(const group_value_type &ci)
Definition: h2c_functions.hpp:246
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
bool sgn0(const algebra::fields::detail::element_fp< FieldParams > &e)
Definition: h2c_functions.hpp:60
UniformityCount
Definition: h2c_policy.hpp:32
ExpandMsgVariant
Definition: h2c_policy.hpp:34
Definition: pair.hpp:31
Definition: hash_state.hpp:43
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: h2c_functions.hpp:487
Definition: h2c_functions.hpp:439
Definition: h2c_functions.hpp:83
static group_value_type process(const field_value_type &u)
Definition: h2c_functions.hpp:335
suite_type::group_value_type group_value_type
Definition: h2c_functions.hpp:332
suite_type::field_value_type field_value_type
Definition: h2c_functions.hpp:333
h2c_suite< Group > suite_type
Definition: h2c_functions.hpp:330
Definition: h2c_functions.hpp:288
h2c_suite< Group > suite_type
Definition: h2c_functions.hpp:289
suite_type::field_value_type field_value_type
Definition: h2c_functions.hpp:292
suite_type::group_value_type group_value_type
Definition: h2c_functions.hpp:291
static group_value_type process(const field_value_type &u)
Definition: h2c_functions.hpp:294
Definition: h2c_functions.hpp:342
Definition: hash/include/nil/crypto3/hash/h2c_suites.hpp:44