zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Nikita Kaskov <nbering@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 // @file Declaration of interfaces for a ppzkSNARK for R1CS with a security proof
26 // in the generic group (GG) model.
27 //
28 // This includes:
29 //- class for proving key
30 //- class for verification key
31 //- class for processed verification key
32 //- class for key pair (proving key & verification key)
33 //- class for proof
34 //- generator algorithm
35 //- prover algorithm
36 //- verifier algorithm (with strong or weak input consistency)
37 //- online verifier algorithm (with strong or weak input consistency)
38 //
39 // The implementation instantiates the protocol of \[Gro16].
40 //
41 //
42 // Acronyms:
43 //
44 //- R1CS = "Rank-1 Constraint Systems"
45 //- ppzkSNARK = "PreProcessing Zero-Knowledge Succinct Non-interactive ARgument of Knowledge"
46 //
47 // References:
48 //
49 //\[Gro16]:
50 // "On the Size of Pairing-based Non-interactive Arguments",
51 // Jens Groth,
52 // EUROCRYPT 2016,
53 // <https://eprint.iacr.org/2016/260>
54 //---------------------------------------------------------------------------//
55 
56 #ifndef CRYPTO3_MARSHALLING_R1CS_GG_PPZKSNARK_TYPES_HPP
57 #define CRYPTO3_MARSHALLING_R1CS_GG_PPZKSNARK_TYPES_HPP
58 
59 #include <vector>
60 #include <tuple>
61 
62 #include <nil/crypto3/multiprecision/number.hpp>
63 #include <nil/crypto3/multiprecision/cpp_int.hpp>
64 #include <nil/crypto3/multiprecision/modular/modular_adaptor.hpp>
65 
73 
81 
83 
84 #include <nil/crypto3/detail/pack.hpp>
85 #include <nil/crypto3/detail/stream_endian.hpp>
86 
87 #include <nil/marshalling/status_type.hpp>
88 
89 namespace nil {
90  namespace marshalling {
91 
92  using namespace nil::crypto3::zk::snark;
93  using namespace nil::crypto3;
94 
95  /************************ TON Virtual Machine compatible serialization *************************/
96 
97  template<typename ProofSystem>
99 
100  template<>
102  nil::crypto3::zk::snark::r1cs_gg_ppzksnark<algebra::curves::bls12<381>>> {
103 
106 
107  using chunk_type = std::uint8_t;
108  constexpr static const std::size_t chunk_size = 8;
109 
110  static const std::size_t std_size_t_byteblob_size = 4;
111  static const std::size_t g1_byteblob_size = curve_element_serializer<CurveType>::sizeof_field_element;
112  static const std::size_t g2_byteblob_size = 2 * curve_element_serializer<CurveType>::sizeof_field_element;
113  static const std::size_t fp_byteblob_size = CurveType::base_field_type::modulus_bits / chunk_size +
114  (CurveType::base_field_type::modulus_bits % chunk_size ? 1 : 0);
115  static const std::size_t gt_byteblob_size = 2 * 3 * 2 * fp_byteblob_size;
116  static const std::size_t fr_byteblob_size =
117  CurveType::scalar_field_type::modulus_bits / chunk_size +
118  (CurveType::scalar_field_type::modulus_bits % chunk_size ? 1 : 0);
119  static const std::size_t linear_term_byteblob_size = std_size_t_byteblob_size + fr_byteblob_size;
120  static const std::size_t g2g1_element_kc_byteblob_size = g2_byteblob_size + g1_byteblob_size;
121 
122  template<typename FieldType>
123  static inline typename std::enable_if<!::nil::crypto3::algebra::is_extended_field<FieldType>::value,
124  typename FieldType::value_type>::type
125  field_type_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
126  typename std::vector<chunk_type>::const_iterator read_iter_end,
127  status_type &processingStatus) {
128 
129  processingStatus = status_type::success;
130 
131  using integral_type = typename FieldType::integral_type;
132  using field_type = FieldType;
133 
134  std::pair<bool, typename field_type::value_type> processed =
135  field_bincode<field_type>::field_element_from_bytes(read_iter_begin, read_iter_end);
136 
137  if (!std::get<0>(processed)) {
138  processingStatus = status_type::invalid_msg_data;
139 
140  return field_type::value_type::zero();
141  }
142 
143  return std::get<1>(processed);
144  }
145 
146  template<typename FieldType>
147  static inline typename std::enable_if<::nil::crypto3::algebra::is_extended_field<FieldType>::value,
148  typename FieldType::value_type>::type
149  field_type_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
150  typename std::vector<chunk_type>::const_iterator read_iter_end,
151  status_type &processingStatus) {
152 
153  processingStatus = status_type::success;
154 
155  using integral_type = typename FieldType::integral_type;
156  using field_type = FieldType;
157 
158  std::pair<bool, typename field_type::value_type> processed =
159  field_bincode<field_type>::field_element_from_bytes(read_iter_begin, read_iter_end);
160 
161  if (!std::get<0>(processed)) {
162  processingStatus = status_type::invalid_msg_data;
163 
164  return field_type::value_type::zero();
165  }
166 
167  return std::get<1>(processed);
168  }
169 
170  template<typename GroupType>
171  static inline typename GroupType::value_type
172  g1_group_type_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
173  typename std::vector<chunk_type>::const_iterator read_iter_end,
174  status_type &processingStatus) {
175 
176  processingStatus = status_type::success;
177 
179 
180  for (std::size_t i = 0; i < g1_byteblob_size; ++i) {
181  input_array[i] = read_iter_begin[i];
182  }
183 
185  }
186 
187  template<typename GroupType>
188  static inline typename GroupType::value_type
189  g2_group_type_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
190  typename std::vector<chunk_type>::const_iterator read_iter_end,
191  status_type &processingStatus) {
192 
193  processingStatus = status_type::success;
194 
196 
197  for (std::size_t i = 0; i < g2_byteblob_size; ++i) {
198  input_array[i] = read_iter_begin[i];
199  }
200 
202  }
203 
205  linear_term_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
206  typename std::vector<chunk_type>::const_iterator read_iter_end,
207  status_type &processingStatus) {
208 
209  processingStatus = status_type::success;
210 
211  std::size_t index =
212  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
213 
214  if (processingStatus != status_type::success) {
216  }
217 
218  typename CurveType::scalar_field_type::value_type coeff =
219  field_type_process<typename CurveType::scalar_field_type>(
220  read_iter_begin + std_size_t_byteblob_size,
221  read_iter_begin + std_size_t_byteblob_size + fr_byteblob_size,
222  processingStatus);
223 
226  }
227 
229  linear_combination_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
230  typename std::vector<chunk_type>::const_iterator read_iter_end,
231  status_type &processingStatus) {
232 
233  processingStatus = status_type::success;
234 
235  std::size_t terms_count =
236  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
237 
238  if (processingStatus != status_type::success) {
240  }
241 
242  std::vector<linear_term<typename CurveType::scalar_field_type>> terms(terms_count);
243 
244  for (std::size_t i = 0; i < terms_count; i++) {
245  terms[i] = linear_term_process(
246  read_iter_begin + std_size_t_byteblob_size + i * linear_term_byteblob_size,
247  read_iter_begin + std_size_t_byteblob_size + (i + 1) * linear_term_byteblob_size,
248  processingStatus);
249 
250  if (processingStatus != status_type::success) {
252  }
253  }
254 
256  }
257 
259  r1cs_constraint_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
260  typename std::vector<chunk_type>::const_iterator read_iter_end,
261  status_type &processingStatus) {
262 
263  std::size_t a_terms_count =
264  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
265 
266  if (processingStatus != status_type::success) {
268  }
269 
270  std::size_t a_byte_size = a_terms_count * linear_term_byteblob_size + std_size_t_byteblob_size;
272  linear_combination_process(read_iter_begin, read_iter_begin + a_byte_size, processingStatus);
273  if (processingStatus != status_type::success) {
275  }
276 
277  std::size_t b_terms_count = std_size_t_process(read_iter_begin + a_byte_size,
278  read_iter_begin + a_byte_size + std_size_t_byteblob_size,
279  processingStatus);
280 
281  if (processingStatus != status_type::success) {
283  }
284 
285  std::size_t b_byte_size = b_terms_count * linear_term_byteblob_size + std_size_t_byteblob_size;
286  linear_combination<typename CurveType::scalar_field_type> b = linear_combination_process(
287  read_iter_begin + a_byte_size, read_iter_begin + a_byte_size + b_byte_size, processingStatus);
288  if (processingStatus != status_type::success) {
290  }
291 
292  std::size_t c_terms_count =
293  std_size_t_process(read_iter_begin + a_byte_size + b_byte_size,
294  read_iter_begin + a_byte_size + b_byte_size + std_size_t_byteblob_size,
295  processingStatus);
296 
297  if (processingStatus != status_type::success) {
299  }
300 
301  std::size_t c_byte_size = c_terms_count * linear_term_byteblob_size + std_size_t_byteblob_size;
303  linear_combination_process(read_iter_begin + a_byte_size + b_byte_size,
304  read_iter_begin + a_byte_size + b_byte_size + c_byte_size,
305  processingStatus);
306  if (processingStatus != status_type::success) {
308  }
309 
311  }
312 
314  r1cs_constraint_system_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
315  typename std::vector<chunk_type>::const_iterator read_iter_end,
316  status_type &processingStatus) {
317 
318  std::size_t primary_input_size =
319  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
320 
321  if (processingStatus != status_type::success) {
323  }
324 
325  std::size_t auxiliary_input_size = std_size_t_process(read_iter_begin + std_size_t_byteblob_size,
326  read_iter_begin + 2 * std_size_t_byteblob_size,
327  processingStatus);
328 
329  if (processingStatus != status_type::success) {
331  }
332 
333  std::size_t rc_count = std_size_t_process(read_iter_begin + 2 * std_size_t_byteblob_size,
334  read_iter_begin + 3 * std_size_t_byteblob_size,
335  processingStatus);
336 
337  if (processingStatus != status_type::success) {
339  }
340 
341  std::vector<r1cs_constraint<typename CurveType::scalar_field_type>> constraints(rc_count);
342 
343  auto read_iter_current_begin = read_iter_begin + 3 * std_size_t_byteblob_size;
344 
345  for (std::size_t i = 0; i < rc_count; i++) {
346 
347  std::size_t total_r1cs_constraint_byteblob_size = std_size_t_process(
348  read_iter_current_begin, read_iter_current_begin + std_size_t_byteblob_size, processingStatus);
349 
350  read_iter_current_begin += std_size_t_byteblob_size;
351 
352  constraints[i] =
353  r1cs_constraint_process(read_iter_current_begin,
354  read_iter_current_begin + total_r1cs_constraint_byteblob_size,
355  processingStatus);
356  read_iter_current_begin += total_r1cs_constraint_byteblob_size;
357  }
358 
361 
362  res.primary_input_size = primary_input_size;
363  res.auxiliary_input_size = auxiliary_input_size;
364  res.constraints = constraints;
365 
366  return res;
367  }
368 
370  typename CurveType::template g1_type<>>
371  g2g1_element_kc_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
372  typename std::vector<chunk_type>::const_iterator read_iter_end,
373  status_type &processingStatus) {
374 
375  typename CurveType::template g2_type<>::value_type g = g2_group_type_process<typename CurveType::template g2_type<>>(
376  read_iter_begin, read_iter_begin + g2_byteblob_size, processingStatus);
377 
378  typename CurveType::template g1_type<>::value_type h = g1_group_type_process<typename CurveType::template g1_type<>>(
379  read_iter_begin + g2_byteblob_size,
380  read_iter_begin + g2_byteblob_size + g1_byteblob_size,
381  processingStatus);
382  return crypto3::zk::snark::detail::element_kc<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>>(
383  g, h);
384  }
385 
386  static inline knowledge_commitment_vector<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>>
388  typename std::vector<chunk_type>::const_iterator read_iter_begin,
389  typename std::vector<chunk_type>::const_iterator read_iter_end,
390  status_type &processingStatus) {
391 
392  using T = knowledge_commitment<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>>;
393 
394  if (std::distance(read_iter_begin, read_iter_end) < std_size_t_byteblob_size) {
395 
396  processingStatus = status_type::not_enough_data;
397 
398  return sparse_vector<T>();
399  }
400 
401  std::size_t indices_count =
402  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
403 
404  if (processingStatus != status_type::success) {
405  return sparse_vector<T>();
406  }
407 
408  std::vector<std::size_t> indices(indices_count, 0);
409 
410  for (std::size_t i = 0; i < indices_count; i++) {
411  indices[i] = std_size_t_process(
412  read_iter_begin + std_size_t_byteblob_size + std_size_t_byteblob_size * i,
413  read_iter_begin + std_size_t_byteblob_size + (i + 1) * std_size_t_byteblob_size,
414  processingStatus);
415  if (processingStatus != status_type::success) {
416  return sparse_vector<T>();
417  }
418  }
419 
420  std::vector<typename T::value_type> values(indices_count);
421 
422  for (std::size_t i = 0; i < indices_count; i++) {
423  values[i] = g2g1_element_kc_process(
424  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
425  i * g2g1_element_kc_byteblob_size,
426  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
427  (i + 1) * g2g1_element_kc_byteblob_size,
428  processingStatus);
429  if (processingStatus != status_type::success) {
430  return sparse_vector<T>();
431  }
432  }
433 
434  std::size_t domain_size_ = std_size_t_process(
435  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
436  indices_count * g2g1_element_kc_byteblob_size,
437  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
438  indices_count * g2g1_element_kc_byteblob_size + std_size_t_byteblob_size,
439  processingStatus);
440  if (processingStatus != status_type::success) {
441  return sparse_vector<T>();
442  }
443 
444  sparse_vector<T> sv;
445 
446  sv.indices = indices;
447  sv.values = values;
448  sv.domain_size_ = domain_size_;
449 
450  // assert (sv.is_valid());
451  assert(sv.values.size() == sv.indices.size());
452 
453  return sv;
454  }
455 
456  static inline std::size_t
457  std_size_t_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
458  typename std::vector<chunk_type>::const_iterator read_iter_end,
459  status_type &processingStatus) {
460 
461  processingStatus = status_type::success;
462 
463  if (std::distance(read_iter_begin, read_iter_end) < std_size_t_byteblob_size) {
464 
465  processingStatus = status_type::not_enough_data;
466 
467  return 0;
468  }
469 
470  std::vector<std::size_t> vector_s(1, 0);
471  auto iter = vector_s.begin();
472 
473  std::size_t vector_c_size = std_size_t_byteblob_size;
474  std::vector<chunk_type> vector_c;
475 
476  vector_c.reserve(vector_c_size);
477  vector_c.insert(vector_c.end(), read_iter_begin, read_iter_begin + vector_c_size);
478 
479  nil::crypto3::detail::pack_from<nil::crypto3::stream_endian::big_octet_big_bit, 8, 32>(vector_c, iter);
480 
481  return vector_s[0];
482  }
483 
484  template<typename T>
485  static inline sparse_vector<T>
486  g1_sparse_vector_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
487  typename std::vector<chunk_type>::const_iterator read_iter_end,
488  status_type &processingStatus) {
489 
490  if (std::distance(read_iter_begin, read_iter_end) < std_size_t_byteblob_size) {
491 
492  processingStatus = status_type::not_enough_data;
493 
494  return sparse_vector<T>();
495  }
496 
497  std::size_t indices_count =
498  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
499 
500  if (processingStatus != status_type::success) {
501  return sparse_vector<T>();
502  }
503 
504  if (std::distance(read_iter_begin, read_iter_end) <
505  std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
506  indices_count * g1_byteblob_size + std_size_t_byteblob_size) {
507 
508  processingStatus = status_type::not_enough_data;
509 
510  return sparse_vector<T>();
511  }
512 
513  std::vector<std::size_t> indices(indices_count, 0);
514 
515  for (std::size_t i = 0; i < indices_count; i++) {
516  indices[i] = std_size_t_process(
517  read_iter_begin + std_size_t_byteblob_size + std_size_t_byteblob_size * i,
518  read_iter_begin + std_size_t_byteblob_size + (i + 1) * std_size_t_byteblob_size,
519  processingStatus);
520  if (processingStatus != status_type::success) {
521  return sparse_vector<T>();
522  }
523  }
524 
525  std::vector<typename T::value_type> values(indices_count);
526 
527  for (std::size_t i = 0; i < indices_count; i++) {
528  values[i] = g1_group_type_process<T>(
529  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
530  i * g1_byteblob_size,
531  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
532  (i + 1) * g1_byteblob_size,
533  processingStatus);
534  if (processingStatus != status_type::success) {
535  return sparse_vector<T>();
536  }
537  }
538 
539  std::size_t domain_size_ = std_size_t_process(
540  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
541  indices_count * g1_byteblob_size,
542  read_iter_begin + std_size_t_byteblob_size + indices_count * std_size_t_byteblob_size +
543  indices_count * g1_byteblob_size + std_size_t_byteblob_size,
544  processingStatus);
545  if (processingStatus != status_type::success) {
546  return sparse_vector<T>();
547  }
548 
549  sparse_vector<T> sv;
550 
551  sv.indices = indices;
552  sv.values = values;
553  sv.domain_size_ = domain_size_;
554 
555  // assert (sv.is_valid());
556  assert(sv.values.size() == sv.indices.size());
557 
558  return sv;
559  }
560 
561  template<typename T>
562  static inline accumulation_vector<T>
563  g1_accumulation_vector_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
564  typename std::vector<chunk_type>::const_iterator read_iter_end,
565  status_type &processingStatus) {
566 
567  if (std::distance(read_iter_begin, read_iter_end) < g1_byteblob_size) {
568 
569  processingStatus = status_type::not_enough_data;
570 
571  return accumulation_vector<T>();
572  }
573 
574  typename T::value_type first =
575  g1_group_type_process<T>(read_iter_begin, read_iter_begin + g1_byteblob_size, processingStatus);
576 
577  if (processingStatus != status_type::success) {
578  return accumulation_vector<T>();
579  }
580 
581  sparse_vector<T> rest =
582  g1_sparse_vector_process<T>(read_iter_begin + g1_byteblob_size, read_iter_end, processingStatus);
583 
584  if (processingStatus != status_type::success) {
585  return accumulation_vector<T>();
586  }
587 
588  return accumulation_vector<T>(std::move(first), std::move(rest));
589  }
590 
591  static inline typename scheme_type::verification_key_type
592  verification_key_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
593  typename std::vector<chunk_type>::const_iterator read_iter_end,
594  status_type &processingStatus) {
595 
596  if (std::distance(read_iter_begin, read_iter_end) <
597  gt_byteblob_size + g2_byteblob_size + g2_byteblob_size) {
598 
599  processingStatus = status_type::not_enough_data;
600 
601  return typename scheme_type::verification_key_type();
602  }
603 
604  typename CurveType::gt_type::value_type alpha_g1_beta_g2 =
605  field_type_process<typename CurveType::gt_type>(read_iter_begin, read_iter_begin + gt_byteblob_size,
606  processingStatus);
607 
608  if (processingStatus != status_type::success) {
609  return typename scheme_type::verification_key_type();
610  }
611 
612  typename CurveType::template g2_type<>::value_type gamma_g2 = g2_group_type_process<typename CurveType::template g2_type<>>(
613  read_iter_begin + gt_byteblob_size,
614  read_iter_begin + gt_byteblob_size + g2_byteblob_size,
615  processingStatus);
616  if (processingStatus != status_type::success) {
617  return typename scheme_type::verification_key_type();
618  }
619 
620  typename CurveType::template g2_type<>::value_type delta_g2 = g2_group_type_process<typename CurveType::template g2_type<>>(
621  read_iter_begin + gt_byteblob_size + g2_byteblob_size,
622  read_iter_begin + gt_byteblob_size + g2_byteblob_size + g2_byteblob_size,
623  processingStatus);
624  if (processingStatus != status_type::success) {
625  return typename scheme_type::verification_key_type();
626  }
627 
629  g1_accumulation_vector_process<typename CurveType::template g1_type<>>(read_iter_begin + gt_byteblob_size +
630  g2_byteblob_size + g2_byteblob_size,
631  read_iter_end,
632  processingStatus);
633 
634  if (processingStatus != status_type::success) {
635  return typename scheme_type::verification_key_type();
636  }
637 
638  return typename scheme_type::verification_key_type(alpha_g1_beta_g2, gamma_g2, delta_g2, gamma_ABC_g1);
639  }
640 
641  static inline typename scheme_type::proving_key_type
642  proving_key_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
643  typename std::vector<chunk_type>::const_iterator read_iter_end,
644  status_type &processingStatus) {
645 
646  auto read_iter_current_begin = read_iter_begin;
647 
648  typename CurveType::template g1_type<>::value_type alpha_g1 = g1_group_type_process<typename CurveType::template g1_type<>>(
649  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
650  read_iter_current_begin += g1_byteblob_size;
651  typename CurveType::template g1_type<>::value_type beta_g1 = g1_group_type_process<typename CurveType::template g1_type<>>(
652  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
653  read_iter_current_begin += g1_byteblob_size;
654  typename CurveType::template g2_type<>::value_type beta_g2 = g2_group_type_process<typename CurveType::template g2_type<>>(
655  read_iter_current_begin, read_iter_current_begin + g2_byteblob_size, processingStatus);
656  read_iter_current_begin += g2_byteblob_size;
657  typename CurveType::template g1_type<>::value_type delta_g1 = g1_group_type_process<typename CurveType::template g1_type<>>(
658  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
659  read_iter_current_begin += g1_byteblob_size;
660  typename CurveType::template g2_type<>::value_type delta_g2 = g2_group_type_process<typename CurveType::template g2_type<>>(
661  read_iter_current_begin, read_iter_current_begin + g2_byteblob_size, processingStatus);
662  read_iter_current_begin += g2_byteblob_size;
663  std::size_t A_query_size = std_size_t_process(
664  read_iter_current_begin, read_iter_current_begin + std_size_t_byteblob_size, processingStatus);
665 
666  read_iter_current_begin += std_size_t_byteblob_size;
667  std::vector<typename CurveType::template g1_type<>::value_type> A_query(A_query_size);
668 
669  for (std::size_t i = 0; i < A_query_size; ++i) {
670  A_query[i] = g1_group_type_process<typename CurveType::template g1_type<>>(
671  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
672  read_iter_current_begin += g1_byteblob_size;
673  }
674 
675  std::size_t total_B_query_size = std_size_t_process(
676  read_iter_current_begin, read_iter_current_begin + std_size_t_byteblob_size, processingStatus);
677 
678  read_iter_current_begin += std_size_t_byteblob_size;
679 
680  knowledge_commitment_vector<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>> B_query =
681  g2g1_knowledge_commitment_vector_process(
682  read_iter_current_begin, read_iter_current_begin + total_B_query_size, processingStatus);
683 
684  read_iter_current_begin += total_B_query_size;
685 
686  std::size_t H_query_size = std_size_t_process(
687  read_iter_current_begin, read_iter_current_begin + std_size_t_byteblob_size, processingStatus);
688 
689  read_iter_current_begin += std_size_t_byteblob_size;
690  std::vector<typename CurveType::template g1_type<>::value_type> H_query(H_query_size);
691 
692  for (std::size_t i = 0; i < H_query_size; ++i) {
693  H_query[i] = g1_group_type_process<typename CurveType::template g1_type<>>(
694  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
695  read_iter_current_begin += g1_byteblob_size;
696  }
697 
698  std::size_t L_query_size = std_size_t_process(
699  read_iter_current_begin, read_iter_current_begin + std_size_t_byteblob_size, processingStatus);
700 
701  read_iter_current_begin += std_size_t_byteblob_size;
702  std::vector<typename CurveType::template g1_type<>::value_type> L_query(L_query_size);
703 
704  for (std::size_t i = 0; i < L_query_size; ++i) {
705  L_query[i] = g1_group_type_process<typename CurveType::template g1_type<>>(
706  read_iter_current_begin, read_iter_current_begin + g1_byteblob_size, processingStatus);
707  read_iter_current_begin += g1_byteblob_size;
708  }
709 
711  r1cs_constraint_system_process(read_iter_current_begin, read_iter_end, processingStatus);
712 
713  return typename scheme_type::proving_key_type(
714  std::move(alpha_g1), std::move(beta_g1), std::move(beta_g2), std::move(delta_g1),
715  std::move(delta_g2), std::move(A_query), std::move(B_query), std::move(H_query), std::move(L_query),
716  std::move(constraint_system));
717  }
718 
719  static inline typename scheme_type::primary_input_type
720  primary_input_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
721  typename std::vector<chunk_type>::const_iterator read_iter_end,
722  status_type &processingStatus) {
723 
724  if (std::distance(read_iter_begin, read_iter_end) < std_size_t_byteblob_size) {
725 
726  processingStatus = status_type::not_enough_data;
727 
728  return typename scheme_type::primary_input_type();
729  }
730 
731  std::size_t pi_count =
732  std_size_t_process(read_iter_begin, read_iter_begin + std_size_t_byteblob_size, processingStatus);
733 
734  if (processingStatus != status_type::success) {
735  return typename scheme_type::primary_input_type();
736  }
737 
738  if (std::distance(read_iter_begin, read_iter_end) <
739  std_size_t_byteblob_size + pi_count * fr_byteblob_size) {
740 
741  processingStatus = status_type::not_enough_data;
742 
743  return typename scheme_type::primary_input_type();
744  }
745 
746  std::vector<typename CurveType::scalar_field_type::value_type> pi(pi_count);
747 
748  for (std::size_t i = 0; i < pi_count; i++) {
749  pi[i] = field_type_process<typename CurveType::scalar_field_type>(
750  read_iter_begin + std_size_t_byteblob_size + i * fr_byteblob_size,
751  read_iter_begin + std_size_t_byteblob_size + (i + 1) * fr_byteblob_size,
752  processingStatus);
753 
754  if (processingStatus != status_type::success) {
755  return typename scheme_type::primary_input_type();
756  }
757  }
758 
759  return typename scheme_type::primary_input_type(pi);
760  }
761 
762  static inline typename scheme_type::proof_type
763  proof_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
764  typename std::vector<chunk_type>::const_iterator read_iter_end,
765  status_type &processingStatus) {
766 
767  if (std::distance(read_iter_begin, read_iter_end) <
768  g1_byteblob_size + g2_byteblob_size + g1_byteblob_size) {
769 
770  processingStatus = status_type::not_enough_data;
771 
772  return typename scheme_type::proof_type();
773  }
774 
775  typename CurveType::template g1_type<>::value_type g_A = g1_group_type_process<typename CurveType::template g1_type<>>(
776  read_iter_begin, read_iter_begin + g1_byteblob_size, processingStatus);
777 
778  if (processingStatus != status_type::success) {
779  return typename scheme_type::proof_type();
780  }
781 
782  typename CurveType::template g2_type<>::value_type g_B = g2_group_type_process<typename CurveType::template g2_type<>>(
783  read_iter_begin + g1_byteblob_size,
784  read_iter_begin + g1_byteblob_size + g2_byteblob_size,
785  processingStatus);
786 
787  if (processingStatus != status_type::success) {
788  return typename scheme_type::proof_type();
789  }
790 
791  typename CurveType::template g1_type<>::value_type g_C = g1_group_type_process<typename CurveType::template g1_type<>>(
792  read_iter_begin + g1_byteblob_size + g2_byteblob_size,
793  read_iter_begin + g1_byteblob_size + g2_byteblob_size + g1_byteblob_size,
794  processingStatus);
795 
796  if (processingStatus != status_type::success) {
797  return typename scheme_type::proof_type();
798  }
799 
800  return typename scheme_type::proof_type(std::move(g_A), std::move(g_B), std::move(g_C));
801  }
802 
803  static inline std::tuple<typename scheme_type::verification_key_type,
804  typename scheme_type::primary_input_type, typename scheme_type::proof_type>
805  verifier_input_process(typename std::vector<chunk_type>::const_iterator read_iter_begin,
806  typename std::vector<chunk_type>::const_iterator read_iter_end,
807  status_type &processingStatus) {
808 
809  const std::size_t proof_byteblob_size = g1_byteblob_size + g2_byteblob_size + g1_byteblob_size;
810 
811  if (std::distance(read_iter_begin, read_iter_end) < proof_byteblob_size) {
812 
813  processingStatus = status_type::not_enough_data;
814 
815  return std::make_tuple(typename scheme_type::verification_key_type(),
816  typename scheme_type::primary_input_type(),
817  typename scheme_type::proof_type());
818  }
819 
820  typename scheme_type::proof_type de_prf =
821  proof_process(read_iter_begin, read_iter_begin + proof_byteblob_size, processingStatus);
822 
823  if (processingStatus != status_type::success) {
824  return std::make_tuple(typename scheme_type::verification_key_type(),
825  typename scheme_type::primary_input_type(),
826  typename scheme_type::proof_type());
827  }
828 
829  const std::size_t primary_input_byteblob_size =
830  std_size_t_byteblob_size +
831  fr_byteblob_size *
832  std_size_t_process(read_iter_begin + proof_byteblob_size,
833  read_iter_begin + proof_byteblob_size + std_size_t_byteblob_size,
834  processingStatus);
835 
836  if (processingStatus != status_type::success) {
837  return std::make_tuple(typename scheme_type::verification_key_type(),
838  typename scheme_type::primary_input_type(),
839  typename scheme_type::proof_type());
840  }
841 
842  typename scheme_type::primary_input_type de_pi =
843  primary_input_process(read_iter_begin + proof_byteblob_size,
844  read_iter_begin + proof_byteblob_size + primary_input_byteblob_size,
845  processingStatus);
846 
847  if (processingStatus != status_type::success) {
848  return std::make_tuple(typename scheme_type::verification_key_type(),
849  typename scheme_type::primary_input_type(),
850  typename scheme_type::proof_type());
851  }
852 
853  typename scheme_type::verification_key_type de_vk =
854  verification_key_process(read_iter_begin + proof_byteblob_size + primary_input_byteblob_size,
855  read_iter_end,
856  processingStatus);
857 
858  if (processingStatus != status_type::success) {
859  return std::make_tuple(typename scheme_type::verification_key_type(),
860  typename scheme_type::primary_input_type(),
861  typename scheme_type::proof_type());
862  }
863 
864  return std::make_tuple(de_vk, de_pi, de_prf);
865  }
866  };
867 
868  template<typename ProofSystem>
870 
871  template<>
873 
876 
877  using chunk_type = std::uint8_t;
878  constexpr static const std::size_t chunk_size = 8;
879 
880  static const std::size_t std_size_t_byteblob_size = 4;
881  static const std::size_t g1_byteblob_size = curve_element_serializer<CurveType>::sizeof_field_element;
882  static const std::size_t g2_byteblob_size = 2 * curve_element_serializer<CurveType>::sizeof_field_element;
883  static const std::size_t fp_byteblob_size = CurveType::base_field_type::modulus_bits / chunk_size +
884  (CurveType::base_field_type::modulus_bits % chunk_size ? 1 : 0);
885  static const std::size_t gt_byteblob_size = 2 * 3 * 2 * fp_byteblob_size;
886  static const std::size_t fr_byteblob_size =
887  CurveType::scalar_field_type::modulus_bits / chunk_size +
888  (CurveType::scalar_field_type::modulus_bits % chunk_size ? 1 : 0);
889  static const std::size_t linear_term_byteblob_size = std_size_t_byteblob_size + fr_byteblob_size;
890  static const std::size_t g2g1_element_kc_byteblob_size = g2_byteblob_size + g1_byteblob_size;
891 
892  template<typename FieldType>
893  static inline
894  typename std::enable_if<!::nil::crypto3::algebra::is_extended_field<FieldType>::value, void>::type
895  field_type_process(typename FieldType::value_type input_fp,
896  typename std::vector<chunk_type>::iterator &write_iter) {
897 
898  typedef nil::crypto3::multiprecision::number<nil::crypto3::multiprecision::backends::cpp_int_backend<>>
899  integral_type;
900 
901  constexpr const std::size_t modulus_bits = FieldType::modulus_bits;
902 
903  constexpr const std::size_t modulus_chunks =
904  modulus_bits / chunk_size + (modulus_bits % chunk_size ? 1 : 0);
905 
906  nil::crypto3::multiprecision::export_bits(integral_type(input_fp.data), write_iter, chunk_size, false);
907  write_iter += modulus_chunks;
908  }
909 
910  template<typename FieldType>
911  static inline
912  typename std::enable_if<::nil::crypto3::algebra::is_extended_field<FieldType>::value, void>::type
913  field_type_process(typename FieldType::value_type input_fp,
914  typename std::vector<chunk_type>::iterator &write_iter) {
915 
916  using field_type = FieldType;
917 
918  const std::size_t data_dimension = field_type::arity / field_type::underlying_field_type::arity;
919 
920  for (int n = 0; n < data_dimension; ++n) {
921  field_type_process<typename field_type::underlying_field_type>(input_fp.data[n], write_iter);
922  }
923  }
924 
925  template<typename GroupType>
926  static inline void g1_group_type_process(typename GroupType::value_type input_g,
927  typename std::vector<chunk_type>::iterator &write_iter) {
928 
929  auto compressed_curve_group_element =
931 
932  copy(compressed_curve_group_element.begin(), compressed_curve_group_element.end(), write_iter);
933 
934  write_iter += compressed_curve_group_element.size();
935  }
936 
937  template<typename GroupType>
938  static inline void g2_group_type_process(typename GroupType::value_type input_g,
939  typename std::vector<chunk_type>::iterator &write_iter) {
940 
941  auto compressed_curve_group_element =
943 
944  copy(compressed_curve_group_element.begin(), compressed_curve_group_element.end(), write_iter);
945 
946  write_iter += compressed_curve_group_element.size();
947  }
948 
949  static inline void std_size_t_process(std::size_t input_s, std::vector<chunk_type>::iterator &write_iter) {
950 
951  std::size_t std_size_t_byteblob_size = 4;
952  std::vector<std::size_t> vector_s = {input_s};
953 
954  auto internal_write_iter = write_iter;
955  nil::crypto3::detail::pack_to<nil::crypto3::stream_endian::big_octet_big_bit, 32, 8>(
956  vector_s, internal_write_iter);
957 
958  write_iter += std_size_t_byteblob_size;
959  }
960 
961  template<typename T>
962  static inline void g1_sparse_vector_process(sparse_vector<T> input_sv,
963  std::vector<chunk_type>::iterator &write_iter) {
964 
965  std::size_t ic_size = input_sv.values.size();
966  // assert (input_sv.is_valid());
967  assert(input_sv.values.size() == input_sv.indices.size());
968  // Actual sparse_vector byteblob size is equal to
969  // (2 + ic_size) * std_size_t_byteblob_size + ic_size * g1_byteblob_size;
970  // For accumulation vector it is
971  // g1_byteblob_size more because of accumulation_vector.first
972 
973  std_size_t_process(ic_size, write_iter);
974 
975  for (auto ic_iter = input_sv.indices.begin(); ic_iter != input_sv.indices.end(); ic_iter++) {
976  std_size_t_process(*ic_iter, write_iter);
977  }
978 
979  for (auto ic_iter = input_sv.values.begin(); ic_iter != input_sv.values.end(); ic_iter++) {
980  g1_group_type_process<typename CurveType::template g1_type<>>(*ic_iter, write_iter);
981  }
982 
983  std_size_t_process(input_sv.domain_size(), write_iter);
984  }
985 
986  template<typename T>
988  std::vector<chunk_type>::iterator &write_iter) {
989 
990  g1_group_type_process<typename CurveType::template g1_type<>>(input_av.first, write_iter);
991 
992  g1_sparse_vector_process(input_av.rest, write_iter);
993  }
994 
995  template<typename T>
996  static inline void linear_term_process(linear_term<T> input_lt,
997  std::vector<chunk_type>::iterator &write_iter) {
998 
999  std_size_t_process(input_lt.index, write_iter);
1000 
1001  field_type_process<T>(input_lt.coeff, write_iter);
1002  }
1003 
1004  template<typename T>
1006  std::vector<chunk_type>::iterator &write_iter) {
1007 
1008  std_size_t_process(input_cm.terms.size(), write_iter);
1009 
1010  for (auto it = input_cm.terms.begin(); it != input_cm.terms.end(); it++) {
1011  linear_term_process<T>(*it, write_iter);
1012  }
1013  }
1014 
1015  static inline std::size_t
1017 
1018  return input_rc.a.terms.size() * (std_size_t_byteblob_size + fr_byteblob_size) +
1019  std_size_t_byteblob_size +
1020  input_rc.b.terms.size() * (std_size_t_byteblob_size + fr_byteblob_size) +
1021  std_size_t_byteblob_size +
1022  input_rc.c.terms.size() * (std_size_t_byteblob_size + fr_byteblob_size) +
1023  std_size_t_byteblob_size;
1024  }
1025 
1026  template<typename T>
1027  static inline void r1cs_constraint_process(r1cs_constraint<T> input_rc,
1028  std::vector<chunk_type>::iterator &write_iter) {
1029 
1030  std_size_t_process(get_r1cs_constraint_byteblob_size(input_rc), write_iter);
1031  linear_combination_process<T>(input_rc.a, write_iter);
1032  linear_combination_process<T>(input_rc.b, write_iter);
1033  linear_combination_process<T>(input_rc.c, write_iter);
1034  }
1035 
1036  template<typename T>
1038  std::vector<chunk_type>::iterator &write_iter) {
1039 
1040  std_size_t_process(input_rs.primary_input_size, write_iter);
1041  std_size_t_process(input_rs.auxiliary_input_size, write_iter);
1042  std_size_t_process(input_rs.constraints.size(), write_iter);
1043 
1044  for (auto it = input_rs.constraints.begin(); it != input_rs.constraints.end(); it++) {
1045  r1cs_constraint_process<T>(*it, write_iter);
1046  }
1047  }
1048 
1049  static inline void g2g1_element_kc_process(
1050  crypto3::zk::snark::detail::element_kc<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>>
1051  input_ek,
1052  std::vector<chunk_type>::iterator &write_iter) {
1053 
1054  g2_group_type_process<typename CurveType::template g2_type<>>(input_ek.g, write_iter);
1055  g1_group_type_process<typename CurveType::template g1_type<>>(input_ek.h, write_iter);
1056  }
1057 
1059  knowledge_commitment_vector<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>> input_kv) {
1060 
1061  return (2 + input_kv.indices.size()) * std_size_t_byteblob_size +
1062  input_kv.values.size() * (g2_byteblob_size + g1_byteblob_size);
1063  }
1064 
1066  knowledge_commitment_vector<typename CurveType::template g2_type<>, typename CurveType::template g1_type<>>
1067  input_kv,
1068  std::vector<chunk_type>::iterator &write_iter) {
1069 
1070  std_size_t_process(get_g2g1_knowledge_commitment_vector_size(input_kv), write_iter);
1071 
1072  std::size_t ic_size = input_kv.values.size();
1073 
1074  std_size_t_process(ic_size, write_iter);
1075 
1076  for (auto ic_iter = input_kv.indices.begin(); ic_iter != input_kv.indices.end(); ic_iter++) {
1077  std_size_t_process(*ic_iter, write_iter);
1078  }
1079 
1080  for (auto ic_iter = input_kv.values.begin(); ic_iter != input_kv.values.end(); ic_iter++) {
1081  g2g1_element_kc_process(*ic_iter, write_iter);
1082  }
1083 
1084  std_size_t_process(input_kv.domain_size(), write_iter);
1085  }
1086 
1087  static inline std::vector<chunk_type> process(typename scheme_type::proving_key_type pk) {
1088 
1089  std::size_t proving_key_size = 3*g1_byteblob_size +
1090  2*g2_byteblob_size + pk.A_query.size()*g1_byteblob_size +
1091  get_g2g1_knowledge_commitment_vector_size(pk.B_query) +
1092  pk.H_query.size()*g1_byteblob_size +
1093  pk.L_query.size()*g1_byteblob_size +
1094  2 * std_size_t_byteblob_size;
1095 
1096  for (auto it = pk.constraint_system.constraints.begin();
1097  it != pk.constraint_system.constraints.end(); it++) {
1098  proving_key_size += get_r1cs_constraint_byteblob_size(*it);
1099  }
1100 
1101  proving_key_size *= 2;
1102 
1103  std::vector<chunk_type> output(proving_key_size);
1104 
1105  typename std::vector<chunk_type>::iterator write_iter = output.begin();
1106 
1107  g1_group_type_process<typename CurveType::template g1_type<>>(pk.alpha_g1, write_iter);
1108  g1_group_type_process<typename CurveType::template g1_type<>>(pk.beta_g1, write_iter);
1109  g2_group_type_process<typename CurveType::template g2_type<>>(pk.beta_g2, write_iter);
1110  g1_group_type_process<typename CurveType::template g1_type<>>(pk.delta_g1, write_iter);
1111  g2_group_type_process<typename CurveType::template g2_type<>>(pk.delta_g2, write_iter);
1112 
1113  std_size_t_process(pk.A_query.size(), write_iter);
1114 
1115  for (auto it = pk.A_query.begin(); it != pk.A_query.end(); it++) {
1116  g1_group_type_process<typename CurveType::template g1_type<>>(*it, write_iter);
1117  }
1118 
1119  g2g1_knowledge_commitment_vector_process(pk.B_query, write_iter);
1120 
1121  std_size_t_process(pk.H_query.size(), write_iter);
1122 
1123  for (auto it = pk.H_query.begin(); it != pk.H_query.end(); it++) {
1124  g1_group_type_process<typename CurveType::template g1_type<>>(*it, write_iter);
1125  }
1126 
1127  std_size_t_process(pk.L_query.size(), write_iter);
1128 
1129  for (auto it = pk.L_query.begin(); it != pk.L_query.end(); it++) {
1130  g1_group_type_process<typename CurveType::template g1_type<>>(*it, write_iter);
1131  }
1132 
1133  r1cs_constraint_system_process<typename CurveType::scalar_field_type>(pk.constraint_system, write_iter);
1134 
1135  return output;
1136  }
1137 
1138  static inline std::vector<chunk_type> process(typename scheme_type::verification_key_type vk) {
1139 
1140  constexpr const std::size_t modulus_bits = CurveType::base_field_type::modulus_bits;
1141 
1142  constexpr const std::size_t modulus_chunks =
1143  modulus_bits / chunk_size + (modulus_bits % chunk_size ? 1 : 0);
1144 
1145  std::size_t ic_size = 1 + vk.gamma_ABC_g1.rest.values.size();
1146 
1147  std::size_t g1_byteblob_size = curve_element_serializer<CurveType>::sizeof_field_element;
1148  std::size_t g2_byteblob_size = 2 * curve_element_serializer<CurveType>::sizeof_field_element;
1149  std::size_t std_size_t_byteblob_size = 4;
1150 
1151  std::size_t gt_byteblob_size = modulus_chunks * CurveType::gt_type::arity;
1152 
1153  std::size_t ic_byteblob_size = std_size_t_byteblob_size + ic_size * g1_byteblob_size;
1154  std::size_t sparse_vector_byteblob_size =
1155  (2 + ic_size) * std_size_t_byteblob_size + ic_size * g1_byteblob_size;
1156  std::size_t accumulation_vector_byteblob_size = sparse_vector_byteblob_size + g1_byteblob_size;
1157 
1158  std::size_t verification_key_size =
1159  gt_byteblob_size + g2_byteblob_size + g2_byteblob_size + accumulation_vector_byteblob_size;
1160 
1161  std::vector<chunk_type> output(verification_key_size);
1162 
1163  typename std::vector<chunk_type>::iterator write_iter = output.begin();
1164 
1165  field_type_process<typename CurveType::gt_type>(vk.alpha_g1_beta_g2, write_iter);
1166  g2_group_type_process<typename CurveType::template g2_type<>>(vk.gamma_g2, write_iter);
1167  g2_group_type_process<typename CurveType::template g2_type<>>(vk.delta_g2, write_iter);
1168 
1169  // std_size_t_process(ic_size, write_iter);
1170 
1171  // g1_group_type_process<typename CurveType::template g1_type<>>(vk.gamma_ABC_g1.first, write_iter);
1172 
1173  // for (auto ic_iter = vk.gamma_ABC_g1.rest.values.begin(); ic_iter !=
1174  // vk.gamma_ABC_g1.rest.values.end(); ic_iter++) {
1175  // g1_group_type_process<typename CurveType::template g1_type<>>(*ic_iter, write_iter);
1176  // }
1177 
1178  g1_accumulation_vector_process(vk.gamma_ABC_g1, write_iter);
1179 
1180  return output;
1181  }
1182 
1183  static inline std::vector<chunk_type> process(typename scheme_type::primary_input_type pi) {
1184 
1185  constexpr const std::size_t modulus_bits = CurveType::scalar_field_type::modulus_bits;
1186 
1187  constexpr const std::size_t modulus_chunks =
1188  modulus_bits / chunk_size + (modulus_bits % chunk_size ? 1 : 0);
1189 
1190  std::size_t std_size_t_byteblob_size = 4;
1191 
1192  std::size_t pi_count = pi.size();
1193 
1194  std::size_t primary_byteblob_input_size = std_size_t_byteblob_size + pi_count * modulus_chunks;
1195 
1196  std::vector<chunk_type> output(primary_byteblob_input_size);
1197 
1198  typename std::vector<chunk_type>::iterator write_iter = output.begin();
1199 
1200  std_size_t_process(pi_count, write_iter);
1201 
1202  for (std::size_t i = 0; i < pi_count; i++) {
1203  field_type_process<typename CurveType::scalar_field_type>(pi[i], write_iter);
1204  }
1205 
1206  return output;
1207  }
1208 
1209  static inline std::vector<chunk_type> process(typename scheme_type::proof_type pr) {
1210 
1211  std::size_t g1_byteblob_size = curve_element_serializer<CurveType>::sizeof_field_element;
1212  std::size_t g2_byteblob_size = 2 * curve_element_serializer<CurveType>::sizeof_field_element;
1213 
1214  std::size_t proof_size = g1_byteblob_size + g2_byteblob_size + g1_byteblob_size;
1215 
1216  std::vector<chunk_type> output(proof_size);
1217 
1218  typename std::vector<chunk_type>::iterator write_iter = output.begin();
1219 
1220  g1_group_type_process<typename CurveType::template g1_type<>>(pr.g_A, write_iter);
1221  g2_group_type_process<typename CurveType::template g2_type<>>(pr.g_B, write_iter);
1222  g1_group_type_process<typename CurveType::template g1_type<>>(pr.g_C, write_iter);
1223 
1224  return output;
1225  }
1226  };
1227 
1228  } // namespace marshalling
1229 } // namespace nil
1230 
1231 #endif // CRYPTO3_MARSHALLING_R1CS_GG_PPZKSNARK_TYPES_HPP
A struct representing a BLS12-381 and BLS12-377 curve.
Definition: curves/bls12.hpp:49
Definition: accumulation_vector.hpp:46
sparse_vector< Type > rest
Definition: accumulation_vector.hpp:53
underlying_value_type first
Definition: accumulation_vector.hpp:52
ppzkSNARK for R1CS with a security proof in the generic group (GG) model
Definition: r1cs_gg_ppzksnark.hpp:109
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
Definition: set_commitment_component.hpp:37
Definition: pair.hpp:32
Definition: pair.hpp:31
Definition: element_knowledge_commitment.hpp:54
Definition: knowledge_commitment.hpp:49
std::vector< linear_term< FieldType > > terms
Definition: variable.hpp:233
Definition: variable.hpp:144
field_value_type coeff
Definition: variable.hpp:149
variable< FieldType >::index_type index
Definition: variable.hpp:148
std::vector< r1cs_constraint< FieldType > > constraints
Definition: r1cs.hpp:130
std::size_t primary_input_size
Definition: r1cs.hpp:127
std::size_t auxiliary_input_size
Definition: r1cs.hpp:128
linear_combination< FieldType > c
Definition: r1cs.hpp:63
linear_combination< FieldType > a
Definition: r1cs.hpp:63
linear_combination< FieldType > b
Definition: r1cs.hpp:63
Definition: sparse_vector.hpp:48
std::vector< underlying_value_type > values
Definition: sparse_vector.hpp:58
std::size_t domain_size() const
Definition: sparse_vector.hpp:167
std::vector< std::size_t > indices
Definition: sparse_vector.hpp:57
std::size_t domain_size_
Definition: sparse_vector.hpp:59
Definition: variable.hpp:66
Definition: algebra/include/nil/crypto3/algebra/curves/detail/marshalling.hpp:43
static GroupType::value_type g1_group_type_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:172
static knowledge_commitment_vector< typename CurveType::template g2_type<>, typename CurveType::template g1_type<> > g2g1_knowledge_commitment_vector_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:387
static std::size_t std_size_t_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:457
static scheme_type::proof_type proof_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:763
static std::enable_if<::nil::crypto3::algebra::is_extended_field< FieldType >::value, typename FieldType::value_type >::type field_type_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:149
static sparse_vector< T > g1_sparse_vector_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:486
static scheme_type::proving_key_type proving_key_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:642
static r1cs_constraint_system< typename CurveType::scalar_field_type > r1cs_constraint_system_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:314
static linear_term< typename CurveType::scalar_field_type > linear_term_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:205
static std::tuple< typename scheme_type::verification_key_type, typename scheme_type::primary_input_type, typename scheme_type::proof_type > verifier_input_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:805
static scheme_type::primary_input_type primary_input_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:720
static GroupType::value_type g2_group_type_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:189
static crypto3::zk::snark::detail::element_kc< typename CurveType::template g2_type<>, typename CurveType::template g1_type<> > g2g1_element_kc_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:371
static linear_combination< typename CurveType::scalar_field_type > linear_combination_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:229
std::uint8_t chunk_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:107
static r1cs_constraint< typename CurveType::scalar_field_type > r1cs_constraint_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:259
typename algebra::curves::bls12< 381 > CurveType
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:104
static std::enable_if<!::nil::crypto3::algebra::is_extended_field< FieldType >::value, typename FieldType::value_type >::type field_type_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:125
static accumulation_vector< T > g1_accumulation_vector_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:563
static scheme_type::verification_key_type verification_key_process(typename std::vector< chunk_type >::const_iterator read_iter_begin, typename std::vector< chunk_type >::const_iterator read_iter_end, status_type &processingStatus)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:592
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:98
static void linear_combination_process(linear_combination< T > input_cm, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1005
static std::vector< chunk_type > process(typename scheme_type::primary_input_type pi)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1183
static std::enable_if<!::nil::crypto3::algebra::is_extended_field< FieldType >::value, void >::type field_type_process(typename FieldType::value_type input_fp, typename std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:895
static void linear_term_process(linear_term< T > input_lt, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:996
static void g1_group_type_process(typename GroupType::value_type input_g, typename std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:926
static void r1cs_constraint_system_process(r1cs_constraint_system< T > input_rs, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1037
std::uint8_t chunk_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:877
static std::vector< chunk_type > process(typename scheme_type::verification_key_type vk)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1138
static std::vector< chunk_type > process(typename scheme_type::proving_key_type pk)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1087
static void g2_group_type_process(typename GroupType::value_type input_g, typename std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:938
static void std_size_t_process(std::size_t input_s, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:949
static void g2g1_knowledge_commitment_vector_process(knowledge_commitment_vector< typename CurveType::template g2_type<>, typename CurveType::template g1_type<>> input_kv, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1065
static void g1_accumulation_vector_process(accumulation_vector< T > input_av, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:987
static std::size_t get_g2g1_knowledge_commitment_vector_size(knowledge_commitment_vector< typename CurveType::template g2_type<>, typename CurveType::template g1_type<>> input_kv)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1058
static std::vector< chunk_type > process(typename scheme_type::proof_type pr)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1209
typename algebra::curves::bls12< 381 > CurveType
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:874
static void g1_sparse_vector_process(sparse_vector< T > input_sv, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:962
static void r1cs_constraint_process(r1cs_constraint< T > input_rc, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1027
static std::enable_if<::nil::crypto3::algebra::is_extended_field< FieldType >::value, void >::type field_type_process(typename FieldType::value_type input_fp, typename std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:913
static std::size_t get_r1cs_constraint_byteblob_size(r1cs_constraint< typename CurveType::scalar_field_type > input_rc)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1016
static void g2g1_element_kc_process(crypto3::zk::snark::detail::element_kc< typename CurveType::template g2_type<>, typename CurveType::template g1_type<>> input_ek, std::vector< chunk_type >::iterator &write_iter)
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:1049
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/marshalling.hpp:869