mp_pcd_circuits.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 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 functionality for creating and using the two PCD circuits in
26 // a multi-predicate PCD construction.
27 //
28 // The implementation follows, extends, and optimizes the approach described
29 // in \[CTV15]. At high level, there is a "compliance step" circuit and a
30 // "translation step" circuit, for each compliance predicate. For more details,
31 // see \[CTV15].
32 //
33 //
34 // References:
35 //
36 // \[CTV15]:
37 // "Cluster Computing in Zero Knowledge",
38 // Alessandro Chiesa, Eran Tromer, Madars Virza
39 //---------------------------------------------------------------------------//
40 
41 #ifndef CRYPTO3_ZK_BLUEPRINT_MP_PCD_CIRCUITS_HPP
42 #define CRYPTO3_ZK_BLUEPRINT_MP_PCD_CIRCUITS_HPP
43 
46 #include <nil/crypto3/zk/components/hashes/crh_component.hpp>
48 #include <nil/crypto3/zk/components/schemes/snark/verifiers/r1cs_pp_zksnark/verifier.hpp>
50 
51 namespace nil {
52  namespace crypto3 {
53  namespace zk {
54  namespace snark {
55 
56  /**************************** Compliance step ********************************/
57 
64  template<typename CurveType>
66 
67  // for now all CRH components are knapsack CRH's; can be easily extended
68  // later to more expressive selector types.
69  template<typename FieldType>
70  using crh_with_field_out_component = knapsack_crh_with_field_out_component<FieldType>;
71 
72  template<typename FieldType>
73  using crh_with_bit_out_component = knapsack_crh_with_bit_out_component<FieldType>;
74 
75  public:
76  typedef typename CurveType::scalar_field_type FieldType;
77 
79 
80  blueprint<FieldType> bp;
81 
82  blueprint_variable<FieldType> zero;
83 
84  std::shared_ptr<block_variable<FieldType>> block_for_outgoing_message;
85  std::shared_ptr<crh_with_field_out_component<FieldType>> hash_outgoing_message;
86 
87  std::vector<block_variable<FieldType>> block_for_incoming_messages;
88  std::vector<blueprint_variable_vector<FieldType>> commitment_and_incoming_message_digests;
89  std::vector<multipacking_component<FieldType>> unpack_commitment_and_incoming_message_digests;
90  std::vector<blueprint_variable_vector<FieldType>> commitment_and_incoming_messages_digest_bits;
91  std::vector<crh_with_field_out_component<FieldType>> hash_incoming_messages;
92 
93  std::vector<r1cs_ppzksnark_verification_key_variable<CurveType>> translation_step_vks;
94  std::vector<blueprint_variable_vector<FieldType>> translation_step_vks_bits;
95 
96  blueprint_variable<FieldType> outgoing_message_type;
97  blueprint_variable_vector<FieldType> outgoing_message_payload;
98  blueprint_variable_vector<FieldType> outgoing_message_vars;
99 
100  blueprint_variable<FieldType> arity;
101  std::vector<blueprint_variable<FieldType>> incoming_message_types;
102  std::vector<blueprint_variable_vector<FieldType>> incoming_message_payloads;
103  std::vector<blueprint_variable_vector<FieldType>> incoming_message_vars;
104 
105  blueprint_variable_vector<FieldType> local_data;
106  blueprint_variable_vector<FieldType> cp_witness;
107  std::shared_ptr<component_from_r1cs<FieldType>> compliance_predicate_as_component;
108 
109  blueprint_variable_vector<FieldType> outgoing_message_bits;
110  std::shared_ptr<multipacking_component<FieldType>> unpack_outgoing_message;
111 
112  std::vector<blueprint_variable_vector<FieldType>> incoming_messages_bits;
113  std::vector<multipacking_component<FieldType>> unpack_incoming_messages;
114 
115  blueprint_variable_vector<FieldType> mp_compliance_step_pcd_circuit_input;
116  blueprint_variable_vector<FieldType> padded_translation_step_vk_and_outgoing_message_digest;
117  std::vector<blueprint_variable_vector<FieldType>> padded_commitment_and_incoming_messages_digest;
118 
119  std::shared_ptr<set_commitment_variable<FieldType, crh_with_bit_out_component<FieldType>>>
121  std::vector<set_membership_proof_variable<FieldType, crh_with_bit_out_component<FieldType>>>
123  std::vector<set_commitment_component<FieldType, crh_with_bit_out_component<FieldType>>>
125  blueprint_variable_vector<FieldType> membership_check_results;
126  blueprint_variable<FieldType> common_type;
127  blueprint_variable_vector<FieldType> common_type_check_aux;
128 
129  std::vector<blueprint_variable_vector<FieldType>> verifier_input;
130  std::vector<r1cs_ppzksnark_proof_variable<CurveType>> proof;
131  blueprint_variable_vector<FieldType> verification_results;
132  std::vector<r1cs_ppzksnark_verifier_component<CurveType>> verifier;
133 
136  const std::size_t max_number_of_predicates);
139 
141  const set_commitment &commitment_to_translation_step_r1cs_vks,
142  const std::vector<r1cs_ppzksnark_verification_key<other_curve<CurveType>>>
143  &mp_translation_step_pcd_circuit_vks,
144  const std::vector<set_membership_proof> &vk_membership_proofs,
146  &compliance_predicate_primary_input,
148  &compliance_predicate_auxiliary_input,
149  const std::vector<r1cs_ppzksnark_proof<other_curve<CurveType>>> &translation_step_proofs);
152 
153  static std::size_t field_logsize();
154  static std::size_t field_capacity();
155  static std::size_t input_size_in_elts();
156  static std::size_t input_capacity_in_bits();
157  static std::size_t input_size_in_bits();
158  };
159 
160  /*************************** Translation step ********************************/
161 
167  template<typename CurveType>
169  public:
170  typedef typename CurveType::scalar_field_type FieldType;
171 
172  blueprint<FieldType> bp;
173 
174  blueprint_variable_vector<FieldType> mp_translation_step_pcd_circuit_input;
175  blueprint_variable_vector<FieldType> unpacked_mp_translation_step_pcd_circuit_input;
176  blueprint_variable_vector<FieldType> verifier_input;
177  std::shared_ptr<multipacking_component<FieldType>> unpack_mp_translation_step_pcd_circuit_input;
178 
179  std::shared_ptr<r1cs_ppzksnark_preprocessed_r1cs_ppzksnark_verification_key_variable<CurveType>>
181  std::shared_ptr<r1cs_ppzksnark_proof_variable<CurveType>> proof;
182  std::shared_ptr<r1cs_ppzksnark_online_verifier_component<CurveType>> online_verifier;
183 
185  const r1cs_ppzksnark_verification_key<other_curve<CurveType>> &compliance_step_vk);
188 
190  translation_step_input,
191  const r1cs_ppzksnark_proof<other_curve<CurveType>> &prev_proof);
194 
195  static std::size_t field_logsize();
196  static std::size_t field_capacity();
197  static std::size_t input_size_in_elts();
198  static std::size_t input_capacity_in_bits();
199  static std::size_t input_size_in_bits();
200  };
201 
202  /****************************** Input maps ***********************************/
203 
207  template<typename CurveType>
210  const set_commitment &commitment_to_translation_step_r1cs_vks,
212  &primary_input);
213 
217  template<typename CurveType>
220  const set_commitment &commitment_to_translation_step_r1cs_vks,
221  const r1cs_pcd_compliance_predicate_primary_input<other_curve<CurveType>::scalar_field_type>
222  &primary_input);
223 
224  template<typename CurveType>
226  const r1cs_pcd_compliance_predicate<FieldType> &compliance_predicate,
227  const std::size_t max_number_of_predicates) :
228  compliance_predicate(compliance_predicate) {
229  /* calculate some useful sizes */
230  const std::size_t digest_size = crh_with_field_out_component<FieldType>::get_digest_len();
231  const std::size_t outgoing_msg_size_in_bits =
232  field_logsize() * (1 + compliance_predicate.outgoing_message_payload_length);
233  assert(compliance_predicate.has_equal_input_lengths());
234  const std::size_t translation_step_vk_size_in_bits =
235  r1cs_ppzksnark_verification_key_variable<CurveType>::size_in_bits(
236  mp_translation_step_pcd_circuit_maker<other_curve<CurveType>>::input_size_in_elts());
237  const std::size_t padded_verifier_input_size =
239  const std::size_t commitment_size =
240  set_commitment_component<FieldType, crh_with_bit_out_component<FieldType>>::root_size_in_bits();
241 
242  const std::size_t output_block_size = commitment_size + outgoing_msg_size_in_bits;
243  const std::size_t max_incoming_payload_length =
244  *std::max_element(compliance_predicate.incoming_message_payload_lengths.begin(),
245  compliance_predicate.incoming_message_payload_lengths.end());
246  const std::size_t max_input_block_size =
247  commitment_size + field_logsize() * (1 + max_incoming_payload_length);
248 
249  crh_with_bit_out_component<FieldType>::sample_randomness(
250  std::max(output_block_size, max_input_block_size));
251 
252  /* allocate input of the compliance MP_PCD circuit */
254 
255  /* allocate inputs to the compliance predicate */
256  outgoing_message_type.allocate(bp);
257  outgoing_message_payload.allocate(bp, compliance_predicate.outgoing_message_payload_length);
258 
262 
263  arity.allocate(bp);
264 
268  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
269  incoming_message_types[i].allocate(bp);
270  incoming_message_payloads[i].allocate(bp,
271  compliance_predicate.incoming_message_payload_lengths[i]);
272 
274  incoming_message_vars[i].insert(incoming_message_vars[i].end(),
275  incoming_message_payloads[i].begin(),
276  incoming_message_payloads[i].end());
277  }
278 
279  local_data.allocate(bp, compliance_predicate.local_data_length);
280  cp_witness.allocate(bp, compliance_predicate.witness_length);
281 
282  /* convert compliance predicate from a constraint system into a component */
283  blueprint_variable_vector<FieldType> incoming_messages_concat;
284  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
285  incoming_messages_concat.insert(incoming_messages_concat.end(),
286  incoming_message_vars[i].begin(),
287  incoming_message_vars[i].end());
288  }
289 
290  compliance_predicate_as_component.reset(new component_from_r1cs<FieldType>(
291  bp,
292  {outgoing_message_vars, blueprint_variable_vector<FieldType>(1, arity),
293  incoming_messages_concat, local_data, cp_witness},
294  compliance_predicate.constraint_system));
295 
296  /* unpack messages to bits */
297  outgoing_message_bits.allocate(bp, outgoing_msg_size_in_bits);
298  unpack_outgoing_message.reset(new multipacking_component<FieldType>(
300 
302  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
303  const std::size_t incoming_msg_size_in_bits =
304  field_logsize() * (1 + compliance_predicate.incoming_message_payload_lengths[i]);
305 
306  incoming_messages_bits[i].allocate(bp, incoming_msg_size_in_bits);
307  unpack_incoming_messages.emplace_back(multipacking_component<FieldType>(
309  }
310 
311  /* allocate digests */
313  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
314  commitment_and_incoming_message_digests[i].allocate(bp, digest_size);
315  }
316 
317  /* allocate commitment, verification key(s) and membership checker(s)/proof(s) */
318  commitment.reset(new set_commitment_variable<FieldType, crh_with_bit_out_component<FieldType>>(
319  bp, commitment_size));
320 
321  if (compliance_predicate.relies_on_same_type_inputs) {
322  /* only one set_commitment_component is needed */
323  common_type.allocate(bp);
324  common_type_check_aux.allocate(bp, compliance_predicate.accepted_input_types.size());
325 
326  translation_step_vks_bits.resize(1);
327  translation_step_vks_bits[0].allocate(bp, translation_step_vk_size_in_bits);
328  membership_check_results.allocate(bp, 1);
329 
330  membership_proofs.emplace_back(
331  set_membership_proof_variable<FieldType, crh_with_bit_out_component<FieldType>>(
332  bp, max_number_of_predicates));
333  membership_checkers.emplace_back(
334  set_commitment_component<FieldType, crh_with_bit_out_component<FieldType>>(
335  bp, max_number_of_predicates, translation_step_vks_bits[0], *commitment,
337  } else {
338  /* check for max_arity possibly different VKs */
340  membership_check_results.allocate(bp, compliance_predicate.max_arity);
341 
342  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
343  translation_step_vks_bits[i].allocate(bp, translation_step_vk_size_in_bits);
344 
345  membership_proofs.emplace_back(
346  set_membership_proof_variable<FieldType, crh_with_bit_out_component<FieldType>>(
347  bp, max_number_of_predicates));
348  membership_checkers.emplace_back(
349  set_commitment_component<FieldType, crh_with_bit_out_component<FieldType>>(
350  bp,
351  max_number_of_predicates,
353  *commitment,
356  }
357  }
358 
359  /* allocate blocks */
361  new block_variable<FieldType>(bp, {commitment->bits, outgoing_message_bits}));
362 
363  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
364  block_for_incoming_messages.emplace_back(
365  block_variable<FieldType>(bp, {commitment->bits, incoming_messages_bits[i]}));
366  }
367 
368  /* allocate hash checkers */
369  hash_outgoing_message.reset(new crh_with_field_out_component<FieldType>(
371 
372  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
373  const std::size_t input_block_size = commitment_size + incoming_messages_bits[i].size();
374  hash_incoming_messages.emplace_back(crh_with_field_out_component<FieldType>(
375  bp, input_block_size, block_for_incoming_messages[i],
377  }
378 
379  /* allocate useful zero variable */
380  zero.allocate(bp);
381 
382  /* prepare arguments for the verifier */
383  if (compliance_predicate.relies_on_same_type_inputs) {
384  translation_step_vks.emplace_back(r1cs_ppzksnark_verification_key_variable<CurveType>(
386  mp_translation_step_pcd_circuit_maker<other_curve<CurveType>>::input_size_in_elts()));
387  } else {
388  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
389  translation_step_vks.emplace_back(r1cs_ppzksnark_verification_key_variable<CurveType>(
391  mp_translation_step_pcd_circuit_maker<other_curve<CurveType>>::input_size_in_elts()));
392  }
393  }
394 
395  verification_results.allocate(bp, compliance_predicate.max_arity);
397 
398  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
399  commitment_and_incoming_messages_digest_bits[i].allocate(bp, digest_size * field_logsize());
401  multipacking_component<FieldType>(bp,
404  field_logsize()));
405 
407  while (verifier_input[i].size() < padded_verifier_input_size) {
408  verifier_input[i].emplace_back(zero);
409  }
410 
411  proof.emplace_back(r1cs_ppzksnark_proof_variable<CurveType>(bp));
412  const r1cs_ppzksnark_verification_key_variable<CurveType> &vk_to_be_used =
413  (compliance_predicate.relies_on_same_type_inputs ? translation_step_vks[0] :
415  verifier.emplace_back(r1cs_ppzksnark_verifier_component<CurveType>(
416  bp,
417  vk_to_be_used,
418  verifier_input[i],
419  mp_translation_step_pcd_circuit_maker<other_curve<CurveType>>::field_capacity(),
420  proof[i],
422  }
423 
424  bp.set_input_sizes(input_size_in_elts());
425  }
426 
427  template<typename CurveType>
429  const std::size_t digest_size = crh_with_bit_out_component<FieldType>::get_digest_len();
430  const std::size_t dimension = knapsack_dimension<FieldType>::dimension;
431  unpack_outgoing_message->generate_r1cs_constraints(true);
432 
433  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
434  unpack_incoming_messages[i].generate_r1cs_constraints(true);
435  }
436 
437  for (std::size_t i = 0; i < translation_step_vks.size(); ++i) {
438  translation_step_vks[i].generate_r1cs_constraints(true);
439  }
440 
441  hash_outgoing_message->generate_r1cs_constraints();
442 
443  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
444  hash_incoming_messages[i].generate_r1cs_constraints();
445  }
446 
447  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
448  unpack_commitment_and_incoming_message_digests[i].generate_r1cs_constraints(true);
449  }
450 
451  for (auto &membership_proof : membership_proofs) {
452  membership_proof.generate_r1cs_constraints();
453  }
454 
455  for (auto &membership_checker : membership_checkers) {
456  membership_checker.generate_r1cs_constraints();
457  }
458 
459  compliance_predicate_as_component->generate_r1cs_constraints();
460 
461  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
462  proof[i].generate_r1cs_constraints();
463  }
464 
465  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
466  verifier[i].generate_r1cs_constraints();
467  }
468 
469  generate_r1cs_equals_const_constraint<FieldType>(bp, zero, FieldType::value_type::zero());
470 
471  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
472  generate_boolean_r1cs_constraint<FieldType>(bp, verification_results[i]);
473  }
474 
475  /* either type = 0 or proof verified w.r.t. a valid verification key */
476  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
477  bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(incoming_message_types[i],
478  1 - verification_results[i], 0));
479  }
480 
481  if (compliance_predicate.relies_on_same_type_inputs) {
482 
483  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
484  bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
485  incoming_message_types[i], incoming_message_types[i] - common_type, 0));
486  }
487 
488  bp.add_r1cs_constraint(
489  snark::r1cs_constraint<FieldType>(common_type, 1 - membership_check_results[0], 0));
490 
491  auto it = compliance_predicate.accepted_input_types.begin();
492  for (std::size_t i = 0; i < compliance_predicate.accepted_input_types.size(); ++i, ++it) {
493  bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
494  (i == 0 ? common_type : common_type_check_aux[i - 1]),
495  common_type - typename FieldType::value_type(*it),
496  (i == compliance_predicate.accepted_input_types.size() - 1 ?
497  0 * blueprint_variable<FieldType>(0) :
498  common_type_check_aux[i])));
499  }
500  } else {
501  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
502  bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
503  incoming_message_types[i], 1 - membership_check_results[i], 0));
504  }
505  }
506  bp.add_r1cs_constraint(snark::r1cs_constraint<FieldType>(
507  1, outgoing_message_type, typename FieldType::value_type(compliance_predicate.type)));
508  }
509 
510  template<typename CurveType>
513  return bp.get_constraint_system();
514  }
515 
516  template<typename CurveType>
519  return bp.primary_input();
520  }
521 
522  template<typename CurveType>
525  return bp.auxiliary_input();
526  }
527 
528  template<typename CurveType>
530  const set_commitment &commitment_to_translation_step_r1cs_vks,
531  const std::vector<r1cs_ppzksnark_verification_key<other_curve<CurveType>>>
532  &mp_translation_step_pcd_circuit_vks,
533  const std::vector<set_membership_proof> &vk_membership_proofs,
534  const r1cs_pcd_compliance_predicate_primary_input<FieldType> &compliance_predicate_primary_input,
536  &compliance_predicate_auxiliary_input,
537  const std::vector<r1cs_ppzksnark_proof<other_curve<CurveType>>> &translation_step_proofs) {
538 
539  this->bp.clear_values();
540  this->bp.val(zero) = FieldType::value_type::zero();
541 
542  compliance_predicate_as_component->generate_r1cs_witness(
543  compliance_predicate_primary_input.as_r1cs_primary_input(),
544  compliance_predicate_auxiliary_input.as_r1cs_auxiliary_input(
545  compliance_predicate.incoming_message_payload_lengths));
546 
547  unpack_outgoing_message->generate_r1cs_witness_from_packed();
548  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
549  unpack_incoming_messages[i].generate_r1cs_witness_from_packed();
550  }
551 
552  for (std::size_t i = 0; i < translation_step_vks.size(); ++i) {
553  translation_step_vks[i].generate_r1cs_witness(mp_translation_step_pcd_circuit_vks[i]);
554  }
555 
556  commitment->generate_r1cs_witness(commitment_to_translation_step_r1cs_vks);
557 
558  if (compliance_predicate.relies_on_same_type_inputs) {
559  /* all messages (except base case) must be of the same type */
560  this->bp.val(common_type) = FieldType::value_type::zero();
561  std::size_t nonzero_type_idx = 0;
562  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
563  if (this->bp.val(incoming_message_types[i]) == 0) {
564  continue;
565  }
566 
567  if (this->bp.val(common_type).is_zero()) {
568  this->bp.val(common_type) = this->bp.val(incoming_message_types[i]);
569  nonzero_type_idx = i;
570  } else {
571  assert(this->bp.val(common_type) == this->bp.val(incoming_message_types[i]));
572  }
573  }
574 
575  this->bp.val(membership_check_results[0]) =
576  (this->bp.val(common_type).is_zero() ? FieldType::value_type::zero() :
577  FieldType::value_type::zero());
578  membership_proofs[0].generate_r1cs_witness(vk_membership_proofs[nonzero_type_idx]);
579  membership_checkers[0].generate_r1cs_witness();
580 
581  auto it = compliance_predicate.accepted_input_types.begin();
582  for (std::size_t i = 0; i < compliance_predicate.accepted_input_types.size(); ++i, ++it) {
583  bp.val(common_type_check_aux[i]) =
584  ((i == 0 ? bp.val(common_type) : bp.val(common_type_check_aux[i - 1])) *
585  (bp.val(common_type) - typename FieldType::value_type(*it)));
586  }
587 
588  } else {
589  for (std::size_t i = 0; i < membership_checkers.size(); ++i) {
590  this->bp.val(membership_check_results[i]) =
591  (this->bp.val(incoming_message_types[i]).is_zero() ? FieldType::value_type::zero() :
592  FieldType::value_type::zero());
593  membership_proofs[i].generate_r1cs_witness(vk_membership_proofs[i]);
594  membership_checkers[i].generate_r1cs_witness();
595  }
596  }
597 
598  hash_outgoing_message->generate_r1cs_witness();
599  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
600  hash_incoming_messages[i].generate_r1cs_witness();
601  unpack_commitment_and_incoming_message_digests[i].generate_r1cs_witness_from_packed();
602  }
603 
604  for (std::size_t i = 0; i < compliance_predicate.max_arity; ++i) {
605  proof[i].generate_r1cs_witness(translation_step_proofs[i]);
606  verifier[i].generate_r1cs_witness();
607  }
608  }
609 
610  template<typename CurveType>
612  return typename CurveType::scalar_field_type::value_bits;
613  }
614 
615  template<typename CurveType>
617  return typename CurveType::scalar_field_type::capacity();
618  }
619 
620  template<typename CurveType>
622  const std::size_t digest_size = crh_with_field_out_component<FieldType>::get_digest_len();
623  return digest_size;
624  }
625 
626  template<typename CurveType>
628  return input_size_in_elts() * field_capacity();
629  }
630 
631  template<typename CurveType>
633  return input_size_in_elts() * field_logsize();
634  }
635 
636  template<typename CurveType>
638  const r1cs_ppzksnark_verification_key<other_curve<CurveType>> &compliance_step_vk) {
639  /* allocate input of the translation MP_PCD circuit */
640  mp_translation_step_pcd_circuit_input.allocate(bp, input_size_in_elts());
641 
642  /* unpack translation step MP_PCD circuit input */
643  unpacked_mp_translation_step_pcd_circuit_input.allocate(
644  bp, mp_compliance_step_pcd_circuit_maker<other_curve<CurveType>>::input_size_in_bits());
645  unpack_mp_translation_step_pcd_circuit_input.reset(
646  new multipacking_component<FieldType>(bp, unpacked_mp_translation_step_pcd_circuit_input,
647  mp_translation_step_pcd_circuit_input, field_capacity()));
648 
649  /* prepare arguments for the verifier */
650  hardcoded_compliance_step_vk.reset(
651  new r1cs_ppzksnark_preprocessed_r1cs_ppzksnark_verification_key_variable<CurveType>(
652  bp, compliance_step_vk));
653  proof.reset(new r1cs_ppzksnark_proof_variable<CurveType>(bp));
654 
655  /* verify previous proof */
656  online_verifier.reset(new r1cs_ppzksnark_online_verifier_component<CurveType>(
657  bp,
658  *hardcoded_compliance_step_vk,
659  unpacked_mp_translation_step_pcd_circuit_input,
660  mp_compliance_step_pcd_circuit_maker<other_curve<CurveType>>::field_logsize(),
661  *proof,
662  blueprint_variable<FieldType>(0)));
663 
664  bp.set_input_sizes(input_size_in_elts());
665  }
666 
667  template<typename CurveType>
669  unpack_mp_translation_step_pcd_circuit_input->generate_r1cs_constraints(true);
670 
671  proof->generate_r1cs_constraints();
672 
673  online_verifier->generate_r1cs_constraints();
674  }
675 
676  template<typename CurveType>
679  return bp.get_constraint_system();
680  }
681 
682  template<typename CurveType>
685  translation_step_input,
686  const r1cs_ppzksnark_proof<other_curve<CurveType>> &prev_proof) {
687  this->bp.clear_values();
688  mp_translation_step_pcd_circuit_input.fill_with_field_elements(bp, translation_step_input);
689  unpack_mp_translation_step_pcd_circuit_input->generate_r1cs_witness_from_packed();
690 
691  proof->generate_r1cs_witness(prev_proof);
692  online_verifier->generate_r1cs_witness();
693  }
694 
695  template<typename CurveType>
698  return bp.primary_input();
699  }
700 
701  template<typename CurveType>
704  return bp.auxiliary_input();
705  }
706 
707  template<typename CurveType>
709  return typename CurveType::scalar_field_type::value_bits;
710  }
711 
712  template<typename CurveType>
714  return typename CurveType::scalar_field_type::capacity();
715  }
716 
717  template<typename CurveType>
719  return algebra::div_ceil(
720  mp_compliance_step_pcd_circuit_maker<other_curve<CurveType>>::input_size_in_bits(),
722  }
723 
724  template<typename CurveType>
726  return input_size_in_elts() * field_capacity();
727  }
728 
729  template<typename CurveType>
731  return input_size_in_elts() * field_logsize();
732  }
733 
734  template<typename CurveType>
737  const set_commitment &commitment_to_translation_step_r1cs_vks,
739  &primary_input) {
740  typedef typename CurveType::scalar_field_type FieldType;
741 
742  const snark::r1cs_variable_assignment<FieldType> outgoing_message_as_va =
743  primary_input.outgoing_message->as_r1cs_variable_assignment();
744  std::vector<bool> msg_bits;
745  for (const typename FieldType::value_type &elt : outgoing_message_as_va) {
746  const std::vector<bool> elt_bits = algebra::convert_field_element_to_bit_vector(elt);
747  msg_bits.insert(msg_bits.end(), elt_bits.begin(), elt_bits.end());
748  }
749 
750  std::vector<bool> block;
751  block.insert(block.end(), commitment_to_translation_step_r1cs_vks.begin(),
752  commitment_to_translation_step_r1cs_vks.end());
753  block.insert(block.end(), msg_bits.begin(), msg_bits.end());
754 
755  crh_with_field_out_component<FieldType>::sample_randomness(block.size());
756 
757  const std::vector<typename FieldType::value_type> digest =
758  crh_with_field_out_component<FieldType>::get_hash(block);
759 
760  return digest;
761  }
762 
763  template<typename CurveType>
766  const set_commitment &commitment_to_translation_step_r1cs_vks,
768  other_curve<CurveType>::scalar_field_type::value_type &
769  primary_input) {
770  typedef typename CurveType::scalar_field_type FieldType;
771 
772  const std::vector <
773  other_curve<CurveType>::scalar_field_type::value_type mp_compliance_step_pcd_circuit_input =
774  get_mp_compliance_step_pcd_circuit_input<other_curve<CurveType>>(
775  commitment_to_translation_step_r1cs_vks, primary_input);
776  std::vector<bool> mp_compliance_step_pcd_circuit_input_bits;
777  for (const other_curve<CurveType>::scalar_field_type::value_type &elt :
778  mp_compliance_step_pcd_circuit_input) {
779  const std::vector<bool> elt_bits = algebra::convert_field_element_to_bit_vector <
780  other_curve<CurveType>::scalar_field_type::value_type(elt);
781  mp_compliance_step_pcd_circuit_input_bits.insert(
782  mp_compliance_step_pcd_circuit_input_bits.end(), elt_bits.begin(), elt_bits.end());
783  }
784 
785  mp_compliance_step_pcd_circuit_input_bits.resize(
787 
789  algebra::pack_bit_vector_into_field_element_vector<FieldType>(
790  mp_compliance_step_pcd_circuit_input_bits,
792  return result;
793  }
794  } // namespace snark
795  } // namespace zk
796  } // namespace crypto3
797 } // namespace nil
798 
799 #endif // CRYPTO3_ZK_BLUEPRINT_MP_PCD_CIRCUITS_HPP
blueprint_variable_vector< FieldType > mp_compliance_step_pcd_circuit_input
Definition: mp_pcd_circuits.hpp:115
std::vector< blueprint_variable_vector< FieldType > > verifier_input
Definition: mp_pcd_circuits.hpp:129
snark::r1cs_auxiliary_input< FieldType > get_auxiliary_input() const
Definition: mp_pcd_circuits.hpp:524
std::vector< r1cs_ppzksnark_verifier_component< CurveType > > verifier
Definition: mp_pcd_circuits.hpp:132
std::vector< blueprint_variable_vector< FieldType > > incoming_messages_bits
Definition: mp_pcd_circuits.hpp:112
std::shared_ptr< block_variable< FieldType > > block_for_outgoing_message
Definition: mp_pcd_circuits.hpp:84
static std::size_t input_size_in_bits()
Definition: mp_pcd_circuits.hpp:632
void generate_r1cs_constraints()
Definition: mp_pcd_circuits.hpp:428
blueprint_variable< FieldType > arity
Definition: mp_pcd_circuits.hpp:100
snark::r1cs_primary_input< FieldType > get_primary_input() const
Definition: mp_pcd_circuits.hpp:518
blueprint_variable< FieldType > common_type
Definition: mp_pcd_circuits.hpp:126
mp_compliance_step_pcd_circuit_maker(const r1cs_pcd_compliance_predicate< FieldType > &compliance_predicate, const std::size_t max_number_of_predicates)
Definition: mp_pcd_circuits.hpp:225
blueprint_variable_vector< FieldType > outgoing_message_bits
Definition: mp_pcd_circuits.hpp:109
blueprint_variable_vector< FieldType > padded_translation_step_vk_and_outgoing_message_digest
Definition: mp_pcd_circuits.hpp:116
std::vector< multipacking_component< FieldType > > unpack_commitment_and_incoming_message_digests
Definition: mp_pcd_circuits.hpp:89
std::vector< blueprint_variable_vector< FieldType > > padded_commitment_and_incoming_messages_digest
Definition: mp_pcd_circuits.hpp:117
std::vector< blueprint_variable< FieldType > > incoming_message_types
Definition: mp_pcd_circuits.hpp:101
static std::size_t field_logsize()
Definition: mp_pcd_circuits.hpp:611
std::vector< block_variable< FieldType > > block_for_incoming_messages
Definition: mp_pcd_circuits.hpp:87
std::vector< set_membership_proof_variable< FieldType, crh_with_bit_out_component< FieldType > > > membership_proofs
Definition: mp_pcd_circuits.hpp:122
static std::size_t field_capacity()
Definition: mp_pcd_circuits.hpp:616
blueprint_variable_vector< FieldType > local_data
Definition: mp_pcd_circuits.hpp:105
void generate_r1cs_witness(const set_commitment &commitment_to_translation_step_r1cs_vks, const std::vector< r1cs_ppzksnark_verification_key< other_curve< CurveType >>> &mp_translation_step_pcd_circuit_vks, const std::vector< set_membership_proof > &vk_membership_proofs, const r1cs_pcd_compliance_predicate_primary_input< FieldType > &compliance_predicate_primary_input, const r1cs_pcd_compliance_predicate_auxiliary_input< FieldType > &compliance_predicate_auxiliary_input, const std::vector< r1cs_ppzksnark_proof< other_curve< CurveType >>> &translation_step_proofs)
Definition: mp_pcd_circuits.hpp:529
std::shared_ptr< component_from_r1cs< FieldType > > compliance_predicate_as_component
Definition: mp_pcd_circuits.hpp:107
static std::size_t input_size_in_elts()
Definition: mp_pcd_circuits.hpp:621
std::vector< blueprint_variable_vector< FieldType > > translation_step_vks_bits
Definition: mp_pcd_circuits.hpp:94
blueprint_variable< FieldType > outgoing_message_type
Definition: mp_pcd_circuits.hpp:96
std::vector< blueprint_variable_vector< FieldType > > commitment_and_incoming_messages_digest_bits
Definition: mp_pcd_circuits.hpp:90
std::vector< blueprint_variable_vector< FieldType > > incoming_message_vars
Definition: mp_pcd_circuits.hpp:103
std::vector< crh_with_field_out_component< FieldType > > hash_incoming_messages
Definition: mp_pcd_circuits.hpp:91
std::vector< blueprint_variable_vector< FieldType > > commitment_and_incoming_message_digests
Definition: mp_pcd_circuits.hpp:88
blueprint_variable_vector< FieldType > verification_results
Definition: mp_pcd_circuits.hpp:131
CurveType::scalar_field_type FieldType
Definition: mp_pcd_circuits.hpp:76
blueprint_variable_vector< FieldType > cp_witness
Definition: mp_pcd_circuits.hpp:106
blueprint_variable_vector< FieldType > common_type_check_aux
Definition: mp_pcd_circuits.hpp:127
blueprint_variable< FieldType > zero
Definition: mp_pcd_circuits.hpp:82
std::vector< r1cs_ppzksnark_verification_key_variable< CurveType > > translation_step_vks
Definition: mp_pcd_circuits.hpp:93
r1cs_pcd_compliance_predicate< FieldType > compliance_predicate
Definition: mp_pcd_circuits.hpp:78
std::vector< set_commitment_component< FieldType, crh_with_bit_out_component< FieldType > > > membership_checkers
Definition: mp_pcd_circuits.hpp:124
std::shared_ptr< set_commitment_variable< FieldType, crh_with_bit_out_component< FieldType > > > commitment
Definition: mp_pcd_circuits.hpp:120
static std::size_t input_capacity_in_bits()
Definition: mp_pcd_circuits.hpp:627
blueprint_variable_vector< FieldType > outgoing_message_payload
Definition: mp_pcd_circuits.hpp:97
std::vector< r1cs_ppzksnark_proof_variable< CurveType > > proof
Definition: mp_pcd_circuits.hpp:130
std::vector< blueprint_variable_vector< FieldType > > incoming_message_payloads
Definition: mp_pcd_circuits.hpp:102
std::shared_ptr< crh_with_field_out_component< FieldType > > hash_outgoing_message
Definition: mp_pcd_circuits.hpp:85
std::shared_ptr< multipacking_component< FieldType > > unpack_outgoing_message
Definition: mp_pcd_circuits.hpp:110
blueprint< FieldType > bp
Definition: mp_pcd_circuits.hpp:80
blueprint_variable_vector< FieldType > outgoing_message_vars
Definition: mp_pcd_circuits.hpp:98
snark::r1cs_constraint_system< FieldType > get_circuit() const
Definition: mp_pcd_circuits.hpp:512
std::vector< multipacking_component< FieldType > > unpack_incoming_messages
Definition: mp_pcd_circuits.hpp:113
blueprint_variable_vector< FieldType > membership_check_results
Definition: mp_pcd_circuits.hpp:125
static std::size_t input_size_in_elts()
Definition: mp_pcd_circuits.hpp:718
static std::size_t input_size_in_bits()
Definition: mp_pcd_circuits.hpp:730
blueprint_variable_vector< FieldType > mp_translation_step_pcd_circuit_input
Definition: mp_pcd_circuits.hpp:174
static std::size_t input_capacity_in_bits()
Definition: mp_pcd_circuits.hpp:725
snark::r1cs_auxiliary_input< FieldType > get_auxiliary_input() const
Definition: mp_pcd_circuits.hpp:703
snark::r1cs_primary_input< FieldType > get_primary_input() const
Definition: mp_pcd_circuits.hpp:697
CurveType::scalar_field_type FieldType
Definition: mp_pcd_circuits.hpp:170
static std::size_t field_capacity()
Definition: mp_pcd_circuits.hpp:713
blueprint< FieldType > bp
Definition: mp_pcd_circuits.hpp:172
blueprint_variable_vector< FieldType > verifier_input
Definition: mp_pcd_circuits.hpp:176
static std::size_t field_logsize()
Definition: mp_pcd_circuits.hpp:708
void generate_r1cs_witness(const snark::r1cs_primary_input< typename CurveType::scalar_field_type > translation_step_input, const r1cs_ppzksnark_proof< other_curve< CurveType >> &prev_proof)
Definition: mp_pcd_circuits.hpp:683
std::shared_ptr< r1cs_ppzksnark_online_verifier_component< CurveType > > online_verifier
Definition: mp_pcd_circuits.hpp:182
void generate_r1cs_constraints()
Definition: mp_pcd_circuits.hpp:668
std::shared_ptr< r1cs_ppzksnark_proof_variable< CurveType > > proof
Definition: mp_pcd_circuits.hpp:181
blueprint_variable_vector< FieldType > unpacked_mp_translation_step_pcd_circuit_input
Definition: mp_pcd_circuits.hpp:175
mp_translation_step_pcd_circuit_maker(const r1cs_ppzksnark_verification_key< other_curve< CurveType >> &compliance_step_vk)
Definition: mp_pcd_circuits.hpp:637
snark::r1cs_constraint_system< FieldType > get_circuit() const
Definition: mp_pcd_circuits.hpp:678
std::shared_ptr< multipacking_component< FieldType > > unpack_mp_translation_step_pcd_circuit_input
Definition: mp_pcd_circuits.hpp:177
std::shared_ptr< r1cs_ppzksnark_preprocessed_r1cs_ppzksnark_verification_key_variable< CurveType > > hardcoded_compliance_step_vk
Definition: mp_pcd_circuits.hpp:180
Definition: snark/proof.hpp:37
r1cs_auxiliary_input< FieldType > as_r1cs_auxiliary_input(const std::vector< std::size_t > &incoming_message_payload_lengths) const
Definition: r1cs_pcd_params.hpp:68
std::shared_ptr< r1cs_pcd_message< FieldType > > outgoing_message
Definition: r1cs_pcd_params.hpp:42
r1cs_primary_input< FieldType > as_r1cs_primary_input() const
Definition: r1cs_pcd_params.hpp:48
Definition: compliance_predicate.hpp:123
Definition: snark/systems/ppzksnark/r1cs_ppzksnark/proof.hpp:43
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_ppzksnark/verification_key.hpp:42
vector(T, U...) -> vector< std::enable_if_t<(std::is_same_v< T, U > &&...), T >, 1+sizeof...(U)>
deduction guide for uniform initialization
constexpr T max(const vector< T, N > &v)
computes the maximum valued element
Definition: algebra/include/nil/crypto3/algebra/vector/math.hpp:146
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
digest_variable< FieldType > set_commitment_variable
Definition: set_commitment_component.hpp:41
std::vector< typename FieldType::value_type > r1cs_auxiliary_input
Definition: r1cs.hpp:104
snark::r1cs_primary_input< typename CurveType::scalar_field_type > get_mp_compliance_step_pcd_circuit_input(const set_commitment &commitment_to_translation_step_r1cs_vks, const r1cs_pcd_compliance_predicate_primary_input< typename CurveType::scalar_field_type > &primary_input)
Definition: mp_pcd_circuits.hpp:736
std::vector< typename FieldType::value_type > r1cs_primary_input
Definition: r1cs.hpp:101
std::vector< bool > set_commitment
Definition: blueprint/include/nil/crypto3/zk/components/schemes/snark/set_commitment.hpp:37
std::vector< typename FieldType::value_type > r1cs_variable_assignment
Definition: r1cs.hpp:107
snark::r1cs_primary_input< typename CurveType::scalar_field_type > get_mp_translation_step_pcd_circuit_input(const set_commitment &commitment_to_translation_step_r1cs_vks, const r1cs_pcd_compliance_predicate_primary_input< other_curve< CurveType >::scalar_field_type > &primary_input)
boost::container::small_vector< octet_type, DigestBits/octet_bits > digest
Definition: codec/include/nil/crypto3/detail/digest.hpp:71
Definition: pair.hpp:31
Definition: block/include/nil/crypto3/detail/digest.hpp:72