algebra/include/nil/crypto3/algebra/marshalling.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Nikita Kaskov <nbering@nil.foundation>
4 // Copyright (c) 2020 Ilias Khairullin <ilias@nil.foundation>
5 //
6 // MIT License
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //---------------------------------------------------------------------------//
26 
27 #ifndef CRYPTO3_ALGEBRA_MARSHALLING_HPP
28 #define CRYPTO3_ALGEBRA_MARSHALLING_HPP
29 
30 #include <vector>
31 #include <tuple>
32 
33 #include <nil/crypto3/detail/pack.hpp>
34 #include <nil/crypto3/detail/stream_endian.hpp>
35 
37 
39 #include <type_traits>
40 
41 namespace nil {
42  namespace marshalling {
43  namespace bincode {
44  template<typename FieldType>
45  struct field {
46  typedef FieldType field_type;
47  typedef typename field_type::value_type field_value_type;
48 
49  typedef uint8_t chunk_type;
50  constexpr static const size_t chunk_size = 8;
51 
52  constexpr static size_t modulus_chunks =
53  field_type::modulus_bits / chunk_size + (field_type::modulus_bits % chunk_size ? 1 : 0);
54  constexpr static size_t field_octets_num = field_type::arity * modulus_chunks;
55 
56  constexpr static inline size_t get_element_size() {
57  return field_octets_num;
58  }
59 
60  template<typename InputFieldValueIterator>
61  static inline typename std::enable_if<
63  std::is_same<chunk_type,
64  typename std::iterator_traits<InputFieldValueIterator>::value_type>::value,
65  std::pair<bool, field_value_type>>::type
66  field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last) {
67  BOOST_ASSERT(field_octets_num == std::distance(first, last));
68 
69  typename FieldType::integral_type result;
70  ::nil::crypto3::multiprecision::import_bits(result, first, last, chunk_size, false);
71 
72  return std::make_pair(result < FieldType::modulus, field_value_type(result));
73  }
74 
75  template<typename InputFieldValueIterator>
76  static inline typename std::enable_if<
78  std::is_same<chunk_type,
79  typename std::iterator_traits<InputFieldValueIterator>::value_type>::value,
80  std::pair<bool, field_value_type>>::type
81  field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last) {
82  constexpr size_t data_dimension = field_type::arity / field_type::underlying_field_type::arity;
83  BOOST_ASSERT(field_octets_num == std::distance(first, last));
84 
85  typename field_value_type::data_type data;
86  bool bres = true;
87  for (size_t n = 0; n < data_dimension; ++n) {
88  std::pair<bool, typename field_type::underlying_field_type::value_type> valid_coord =
90  first + n * field_type::underlying_field_type::arity * modulus_chunks,
91  first + (n + 1) * field_type::underlying_field_type::arity * modulus_chunks);
92  bres = bres && valid_coord.first;
93  data[n] = valid_coord.second;
94  }
95 
96  return std::make_pair(bres, field_value_type(data));
97  }
98 
99  template<typename OutputIterator>
100  static inline typename std::enable_if<
102  std::is_same<chunk_type, typename std::iterator_traits<OutputIterator>::value_type>::value,
103  size_t>::type
104  field_element_to_bytes(const field_value_type &element, OutputIterator out_first,
105  OutputIterator out_last) {
106  BOOST_ASSERT(field_octets_num == std::distance(out_first, out_last));
107 
108  ::nil::crypto3::multiprecision::export_bits(
109  element.data.template convert_to<typename FieldType::integral_type>(), out_first, chunk_size,
110  false);
111 
112  return field_octets_num;
113  }
114 
115  template<typename OutputIterator>
116  static inline typename std::enable_if<
118  std::is_same<chunk_type, typename std::iterator_traits<OutputIterator>::value_type>::value,
119  size_t>::type
120  field_element_to_bytes(const field_value_type &element, OutputIterator out_first,
121  OutputIterator out_last) {
122  BOOST_ASSERT(field_octets_num == std::distance(out_first, out_last));
123 
124  size_t offset = 0;
125  for (auto data_it = element.data.begin(); data_it != element.data.end(); ++data_it) {
127  *data_it, out_first + offset,
128  out_first + offset + field_type::underlying_field_type::arity * modulus_chunks);
129  }
130 
131  return field_octets_num;
132  }
133  };
134 
135  template<typename CurveType>
136  struct curve;
137 
138  template<>
139  struct curve<algebra::curves::bls12<381>> {
143  typedef typename curve_type::template g1_type<> g1_type;
144  typedef typename curve_type::template g2_type<> g2_type;
145  typedef typename curve_type::gt_type gt_type;
146 
147  typedef uint8_t chunk_type;
148  constexpr static const size_t chunk_size = 8;
149 
150  constexpr static size_t fp_octets_num =
151  curve_type::base_field_type::modulus_bits / chunk_size + 1;
152  constexpr static size_t fr_octets_num =
153  curve_type::scalar_field_type::modulus_bits / chunk_size + 1;
154  static_assert(curve_element_serializer<curve_type>::sizeof_field_element == fp_octets_num);
155 
156  constexpr static size_t g1_octets_num = fp_octets_num;
157  constexpr static size_t g2_octets_num = 2 * fp_octets_num;
158  constexpr static size_t gt_octets_num = gt_type::arity * fp_octets_num;
159 
160  // template<typename FieldType>
161  // constexpr static inline std::size_t get_field_element_size() {
162  // return (FieldType::modulus_bits / chunk_size + (FieldType::modulus_bits % chunk_size ? 1 : 0)) *
163  // FieldType::arity;
164  // }
165 
166  template<typename FieldType>
167  constexpr static inline typename std::enable_if<std::is_same<fr_type, FieldType>::value, size_t>::type
169  return fr_octets_num;
170  }
171 
172  template<typename FieldType>
173  constexpr static inline typename std::enable_if<std::is_same<fp_type, FieldType>::value, size_t>::type
175  return fp_octets_num;
176  }
177 
178  template<typename FieldType>
179  constexpr static inline typename std::enable_if<std::is_same<gt_type, FieldType>::value, size_t>::type
181  return gt_octets_num;
182  }
183 
184  template<typename GroupType>
185  constexpr static inline typename std::enable_if<std::is_same<g1_type, GroupType>::value, size_t>::type
187  return g1_octets_num;
188  }
189 
190  template<typename GroupType>
191  constexpr static inline typename std::enable_if<std::is_same<g2_type, GroupType>::value, size_t>::type
193  return g2_octets_num;
194  }
195 
196  template<typename FieldType, typename InputFieldValueIterator>
197  static inline typename std::enable_if<
199  std::is_same<chunk_type,
200  typename std::iterator_traits<InputFieldValueIterator>::value_type>::value &&
201  (std::is_same<fp_type, FieldType>::value || std::is_same<fr_type, FieldType>::value),
202  std::pair<bool, typename FieldType::value_type>>::type
203  field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last) {
204  return field<FieldType>::field_element_from_bytes(first, last);
205  }
206 
207  template<typename FieldType, typename InputFieldValueIterator>
208  static inline typename std::enable_if<
210  std::is_same<chunk_type,
211  typename std::iterator_traits<InputFieldValueIterator>::value_type>::value,
212  std::pair<bool, typename FieldType::value_type>>::type
213  field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last) {
214  return field<FieldType>::field_element_from_bytes(first, last);
215  }
216 
217  template<typename InputG1Iterator>
218  static inline typename std::enable_if<
219  std::is_same<chunk_type, typename std::iterator_traits<InputG1Iterator>::value_type>::value,
220  typename g1_type::value_type>::type
221  g1_point_from_bytes(InputG1Iterator first, InputG1Iterator last) {
222  BOOST_ASSERT(g1_octets_num == std::distance(first, last));
223 
225  auto it1 = first;
226  auto it2 = input_array.begin();
227  while (it1 != last && it2 != input_array.end()) {
228  *it2++ = *it1++;
229  }
230 
232  }
233 
234  template<typename InputG2Iterator>
235  static inline typename std::enable_if<
236  std::is_same<chunk_type, typename std::iterator_traits<InputG2Iterator>::value_type>::value,
237  typename g2_type::value_type>::type
238  g2_point_from_bytes(InputG2Iterator first, InputG2Iterator last) {
239  BOOST_ASSERT(g2_octets_num == std::distance(first, last));
240 
242  auto it1 = first;
243  auto it2 = input_array.begin();
244  while (it1 != last && it2 != input_array.end()) {
245  *it2++ = *it1++;
246  }
247 
249  }
250 
251  template<typename FieldType, typename OutputIterator>
252  static inline typename std::enable_if<
254  (std::is_same<fp_type, FieldType>::value || std::is_same<fr_type, FieldType>::value) &&
255  std::is_same<chunk_type, typename std::iterator_traits<OutputIterator>::value_type>::value,
256  size_t>::type
257  field_element_to_bytes(const typename FieldType::value_type &element, OutputIterator out_first,
258  OutputIterator out_last) {
259  return field<FieldType>::field_element_to_bytes(element, out_first, out_last);
260  }
261 
262  template<typename FieldType, typename OutputIterator>
263  static inline typename std::enable_if<
265  std::is_same<chunk_type, typename std::iterator_traits<OutputIterator>::value_type>::value,
266  size_t>::type
267  field_element_to_bytes(const typename FieldType::value_type &element, OutputIterator out_first,
268  OutputIterator out_last) {
269  return field<FieldType>::field_element_to_bytes(element, out_first, out_last);
270  }
271 
272  template<typename GroupType, typename OutputIterator>
273  static inline typename std::enable_if<std::is_same<g1_type, GroupType>::value, size_t>::type
274  point_to_bytes(const typename GroupType::value_type &point, OutputIterator out_first,
275  OutputIterator out_last) {
276  BOOST_ASSERT(g1_octets_num == std::distance(out_first, out_last));
277 
279  std::copy(out_array.begin(), out_array.end(), out_first);
280  return out_array.size();
281  }
282 
283  template<typename GroupType, typename OutputIterator>
284  static inline typename std::enable_if<std::is_same<g2_type, GroupType>::value, size_t>::type
285  point_to_bytes(const typename GroupType::value_type &point, OutputIterator out_first,
286  OutputIterator out_last) {
287  BOOST_ASSERT(g2_octets_num == std::distance(out_first, out_last));
288 
290  std::copy(out_array.begin(), out_array.end(), out_first);
291  return out_array.size();
292  }
293  };
294  } // namespace bincode
295 
296  } // namespace marshalling
297 } // namespace nil
298 
299 #endif // CRYPTO3_ALGEBRA_MARSHALLING_HPP
A struct representing a BLS12-381 and BLS12-377 curve.
Definition: curves/bls12.hpp:49
policy_type::gt_field_type gt_type
Definition: curves/bls12.hpp:71
Definition: pair.hpp:31
IETF IPsec groups.
Definition: bls12/base_field.hpp:46
Definition: bls12/scalar_field.hpp:46
Definition: algebra/include/nil/crypto3/algebra/type_traits.hpp:105
constexpr static std::enable_if< std::is_same< g2_type, GroupType >::value, size_t >::type element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:192
static std::enable_if< !algebra::is_extended_field< FieldType >::value &&(std::is_same< fp_type, FieldType >::value||std::is_same< fr_type, FieldType >::value) &&std::is_same< chunk_type, typename std::iterator_traits< OutputIterator >::value_type >::value, size_t >::type field_element_to_bytes(const typename FieldType::value_type &element, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:257
static std::enable_if< algebra::is_extended_field< FieldType >::value &&std::is_same< chunk_type, typename std::iterator_traits< OutputIterator >::value_type >::value, size_t >::type field_element_to_bytes(const typename FieldType::value_type &element, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:267
static std::enable_if< std::is_same< g2_type, GroupType >::value, size_t >::type point_to_bytes(const typename GroupType::value_type &point, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:285
uint8_t chunk_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:147
static std::enable_if< std::is_same< g1_type, GroupType >::value, size_t >::type point_to_bytes(const typename GroupType::value_type &point, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:274
constexpr static std::enable_if< std::is_same< g1_type, GroupType >::value, size_t >::type element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:186
curve_type::scalar_field_type fr_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:142
static std::enable_if< algebra::is_extended_field< FieldType >::value &&std::is_same< chunk_type, typename std::iterator_traits< InputFieldValueIterator >::value_type >::value, std::pair< bool, typename FieldType::value_type > >::type field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:213
curve_type::base_field_type fp_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:141
algebra::curves::bls12< 381 > curve_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:140
static std::enable_if< std::is_same< chunk_type, typename std::iterator_traits< InputG1Iterator >::value_type >::value, typename g1_type::value_type >::type g1_point_from_bytes(InputG1Iterator first, InputG1Iterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:221
curve_type::template g2_type g2_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:144
static std::enable_if< std::is_same< chunk_type, typename std::iterator_traits< InputG2Iterator >::value_type >::value, typename g2_type::value_type >::type g2_point_from_bytes(InputG2Iterator first, InputG2Iterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:238
constexpr static std::enable_if< std::is_same< gt_type, FieldType >::value, size_t >::type element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:180
constexpr static std::enable_if< std::is_same< fr_type, FieldType >::value, size_t >::type element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:168
curve_type::gt_type gt_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:145
static std::enable_if< !algebra::is_extended_field< FieldType >::value &&std::is_same< chunk_type, typename std::iterator_traits< InputFieldValueIterator >::value_type >::value &&(std::is_same< fp_type, FieldType >::value||std::is_same< fr_type, FieldType >::value), std::pair< bool, typename FieldType::value_type > >::type field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:203
constexpr static std::enable_if< std::is_same< fp_type, FieldType >::value, size_t >::type element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:174
curve_type::template g1_type g1_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:143
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:136
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:45
static std::enable_if< algebra::is_extended_field< field_type >::value &&std::is_same< chunk_type, typename std::iterator_traits< OutputIterator >::value_type >::value, size_t >::type field_element_to_bytes(const field_value_type &element, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:120
static std::enable_if< algebra::is_extended_field< field_type >::value &&std::is_same< chunk_type, typename std::iterator_traits< InputFieldValueIterator >::value_type >::value, std::pair< bool, field_value_type > >::type field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:81
constexpr static size_t field_octets_num
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:54
constexpr static const size_t chunk_size
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:50
static std::enable_if< !algebra::is_extended_field< field_type >::value &&std::is_same< chunk_type, typename std::iterator_traits< InputFieldValueIterator >::value_type >::value, std::pair< bool, field_value_type > >::type field_element_from_bytes(InputFieldValueIterator first, InputFieldValueIterator last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:66
FieldType field_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:46
static std::enable_if< !algebra::is_extended_field< field_type >::value &&std::is_same< chunk_type, typename std::iterator_traits< OutputIterator >::value_type >::value, size_t >::type field_element_to_bytes(const field_value_type &element, OutputIterator out_first, OutputIterator out_last)
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:104
constexpr static size_t modulus_chunks
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:52
uint8_t chunk_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:49
constexpr static size_t get_element_size()
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:56
field_type::value_type field_value_type
Definition: algebra/include/nil/crypto3/algebra/marshalling.hpp:47
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:43