Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
r1cs_mp_ppzkpcd.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a *multi-predicate* ppzkPCD for R1CS.
5 
6  See r1cs_mp_ppzkpcd.hpp .
7 
8  *****************************************************************************
9  * @author This file is part of libsnark, developed by SCIPR Lab
10  * and contributors (see AUTHORS).
11  * @copyright MIT license (see LICENSE file)
12  *****************************************************************************/
13 
14 #ifndef R1CS_MP_PPZKPCD_TCC_
15 #define R1CS_MP_PPZKPCD_TCC_
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <iostream>
20 #include <libff/common/profiling.hpp>
21 #include <libff/common/utils.hpp>
22 #include <libsnark/common/libsnark_serialization.hpp>
23 #include <libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/mp_pcd_circuits.hpp>
24 
25 namespace libsnark
26 {
27 
28 template<typename PCD_ppT>
29 size_t r1cs_mp_ppzkpcd_proving_key<PCD_ppT>::size_in_bits() const
30 {
31  const size_t num_predicates = compliance_predicates.size();
32 
33  size_t result = 0;
34  for (size_t i = 0; i < num_predicates; ++i) {
35  result +=
36  (compliance_predicates[i].size_in_bits() +
37  compliance_step_r1cs_pks[i].size_in_bits() +
38  translation_step_r1cs_pks[i].size_in_bits() +
39  compliance_step_r1cs_vks[i].size_in_bits() +
40  translation_step_r1cs_vks[i].size_in_bits() +
41  compliance_step_r1cs_vk_membership_proofs[i].size_in_bits());
42  }
43  result += commitment_to_translation_step_r1cs_vks.size();
44 
45  return result;
46 }
47 
48 template<typename PCD_ppT>
49 bool r1cs_mp_ppzkpcd_proving_key<PCD_ppT>::is_well_formed() const
50 {
51  const size_t num_predicates = compliance_predicates.size();
52 
53  bool result;
54  result = result && (compliance_step_r1cs_pks.size() == num_predicates);
55  result = result && (translation_step_r1cs_pks.size() == num_predicates);
56  result = result && (compliance_step_r1cs_vks.size() == num_predicates);
57  result = result && (translation_step_r1cs_vks.size() == num_predicates);
58  result = result && (compliance_step_r1cs_vk_membership_proofs.size() ==
59  num_predicates);
60 
61  return result;
62 }
63 
64 template<typename PCD_ppT>
65 bool r1cs_mp_ppzkpcd_proving_key<PCD_ppT>::operator==(
66  const r1cs_mp_ppzkpcd_proving_key<PCD_ppT> &other) const
67 {
68  return (
69  this->compliance_predicates == other.compliance_predicates &&
70  this->compliance_step_r1cs_pks == other.compliance_step_r1cs_pks &&
71  this->translation_step_r1cs_pks == other.translation_step_r1cs_pks &&
72  this->compliance_step_r1cs_vks == other.compliance_step_r1cs_vks &&
73  this->translation_step_r1cs_vks == other.translation_step_r1cs_vks &&
74  this->commitment_to_translation_step_r1cs_vks ==
75  other.commitment_to_translation_step_r1cs_vks &&
76  this->compliance_step_r1cs_vk_membership_proofs ==
77  other.compliance_step_r1cs_vk_membership_proofs &&
78  this->compliance_predicate_name_to_idx ==
79  other.compliance_predicate_name_to_idx);
80 }
81 
82 template<typename PCD_ppT>
83 std::ostream &operator<<(
84  std::ostream &out, const r1cs_mp_ppzkpcd_proving_key<PCD_ppT> &pk)
85 {
86  out << pk.compliance_predicates;
87  out << pk.compliance_step_r1cs_pks;
88  out << pk.translation_step_r1cs_pks;
89  out << pk.compliance_step_r1cs_vks;
90  out << pk.translation_step_r1cs_vks;
91  output_bool_vector(out, pk.commitment_to_translation_step_r1cs_vks);
92  out << pk.compliance_step_r1cs_vk_membership_proofs;
93  out << pk.compliance_predicate_name_to_idx;
94 
95  return out;
96 }
97 
98 template<typename PCD_ppT>
99 std::istream &operator>>(
100  std::istream &in, r1cs_mp_ppzkpcd_proving_key<PCD_ppT> &pk)
101 {
102  in >> pk.compliance_predicates;
103  in >> pk.compliance_step_r1cs_pks;
104  in >> pk.translation_step_r1cs_pks;
105  in >> pk.compliance_step_r1cs_vks;
106  in >> pk.translation_step_r1cs_vks;
107  input_bool_vector(in, pk.commitment_to_translation_step_r1cs_vks);
108  in >> pk.compliance_step_r1cs_vk_membership_proofs;
109  in >> pk.compliance_predicate_name_to_idx;
110 
111  return in;
112 }
113 
114 template<typename PCD_ppT>
115 size_t r1cs_mp_ppzkpcd_verification_key<PCD_ppT>::size_in_bits() const
116 {
117  const size_t num_predicates = compliance_step_r1cs_vks.size();
118 
119  size_t result = 0;
120  for (size_t i = 0; i < num_predicates; ++i) {
121  result +=
122  (compliance_step_r1cs_vks[i].size_in_bits() +
123  translation_step_r1cs_vks[i].size_in_bits());
124  }
125 
126  result += commitment_to_translation_step_r1cs_vks.size();
127 
128  return result;
129 }
130 
131 template<typename PCD_ppT>
132 bool r1cs_mp_ppzkpcd_verification_key<PCD_ppT>::operator==(
133  const r1cs_mp_ppzkpcd_verification_key<PCD_ppT> &other) const
134 {
135  return (
136  this->compliance_step_r1cs_vks == other.compliance_step_r1cs_vks &&
137  this->translation_step_r1cs_vks == other.translation_step_r1cs_vks &&
138  this->commitment_to_translation_step_r1cs_vks ==
139  other.commitment_to_translation_step_r1cs_vks);
140 }
141 
142 template<typename PCD_ppT>
143 std::ostream &operator<<(
144  std::ostream &out, const r1cs_mp_ppzkpcd_verification_key<PCD_ppT> &vk)
145 {
146  out << vk.compliance_step_r1cs_vks;
147  out << vk.translation_step_r1cs_vks;
148  libff::output_bool_vector(out, vk.commitment_to_translation_step_r1cs_vks);
149 
150  return out;
151 }
152 
153 template<typename PCD_ppT>
154 std::istream &operator>>(
155  std::istream &in, r1cs_mp_ppzkpcd_verification_key<PCD_ppT> &vk)
156 {
157  in >> vk.compliance_step_r1cs_vks;
158  in >> vk.translation_step_r1cs_vks;
159  libff::input_bool_vector(in, vk.commitment_to_translation_step_r1cs_vks);
160 
161  return in;
162 }
163 
164 template<typename PCD_ppT>
165 size_t r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT>::size_in_bits() const
166 {
167  const size_t num_predicates = compliance_step_r1cs_pvks.size();
168 
169  size_t result = 0;
170  for (size_t i = 0; i < num_predicates; ++i) {
171  result +=
172  (compliance_step_r1cs_pvks[i].size_in_bits() +
173  translation_step_r1cs_pvks[i].size_in_bits());
174  }
175 
176  result += commitment_to_translation_step_r1cs_vks.size();
177 
178  return result;
179 }
180 
181 template<typename PCD_ppT>
182 bool r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT>::operator==(
183  const r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> &other) const
184 {
185  return (
186  this->compliance_step_r1cs_pvks == other.compliance_step_r1cs_pvks &&
187  this->translation_step_r1cs_pvks == other.translation_step_r1cs_pvks &&
188  this->commitment_to_translation_step_r1cs_vks ==
189  other.commitment_to_translation_step_r1cs_vks);
190 }
191 
192 template<typename PCD_ppT>
193 std::ostream &operator<<(
194  std::ostream &out,
195  const r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
196 {
197  out << pvk.compliance_step_r1cs_pvks;
198  out << pvk.translation_step_r1cs_pvks;
199  libff::output_bool_vector(out, pvk.commitment_to_translation_step_r1cs_vks);
200 
201  return out;
202 }
203 
204 template<typename PCD_ppT>
205 std::istream &operator>>(
206  std::istream &in, r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
207 {
208  in >> pvk.compliance_step_r1cs_pvks;
209  in >> pvk.translation_step_r1cs_pvks;
210  libff::input_bool_vector(in, pvk.commitment_to_translation_step_r1cs_vks);
211 
212  return in;
213 }
214 
215 template<typename PCD_ppT>
216 bool r1cs_mp_ppzkpcd_proof<PCD_ppT>::operator==(
217  const r1cs_mp_ppzkpcd_proof<PCD_ppT> &other) const
218 {
219  return (
220  this->compliance_predicate_idx == other.compliance_predicate_idx &&
221  this->r1cs_proof == other.r1cs_proof);
222 }
223 
224 template<typename PCD_ppT>
225 std::ostream &operator<<(
226  std::ostream &out, const r1cs_mp_ppzkpcd_proof<PCD_ppT> &proof)
227 {
228  out << proof.compliance_predicate_idx << "\n";
229  out << proof.r1cs_proof;
230 
231  return out;
232 }
233 
234 template<typename PCD_ppT>
235 std::istream &operator>>(
236  std::istream &in, r1cs_mp_ppzkpcd_proof<PCD_ppT> &proof)
237 {
238  in >> proof.compliance_predicate_idx;
239  libff::consume_newline(in);
240  in >> proof.r1cs_proof;
241 
242  return in;
243 }
244 
245 template<typename PCD_ppT>
246 r1cs_mp_ppzkpcd_keypair<PCD_ppT> r1cs_mp_ppzkpcd_generator(
247  const std::vector<r1cs_mp_ppzkpcd_compliance_predicate<PCD_ppT>>
248  &compliance_predicates)
249 {
250  assert(
251  libff::Fr<typename PCD_ppT::curve_A_pp>::mod ==
252  libff::Fq<typename PCD_ppT::curve_B_pp>::mod);
253  assert(
254  libff::Fq<typename PCD_ppT::curve_A_pp>::mod ==
255  libff::Fr<typename PCD_ppT::curve_B_pp>::mod);
256 
257  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
258  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
259 
260  typedef libff::Fr<curve_A_pp> FieldT_A;
261  typedef libff::Fr<curve_B_pp> FieldT_B;
262 
263  libff::enter_block("Call to r1cs_mp_ppzkpcd_generator");
264 
265  r1cs_mp_ppzkpcd_keypair<PCD_ppT> keypair;
266  const size_t translation_input_size =
267  mp_translation_step_pcd_circuit_maker<curve_B_pp>::input_size_in_elts();
268  const size_t vk_size_in_bits =
269  r1cs_ppzksnark_verification_key_variable<curve_A_pp>::size_in_bits(
270  translation_input_size);
271  printf("%zu %zu\n", translation_input_size, vk_size_in_bits);
272 
273  set_commitment_accumulator<CRH_with_bit_out_gadget<FieldT_A>>
274  all_translation_vks(compliance_predicates.size(), vk_size_in_bits);
275 
276  libff::enter_block("Perform type checks");
277  std::map<size_t, size_t> type_counts;
278 
279  for (auto &cp : compliance_predicates) {
280  type_counts[cp.type] += 1;
281  }
282 
283  for (auto &cp : compliance_predicates) {
284  if (cp.relies_on_same_type_inputs) {
285  for (size_t type : cp.accepted_input_types) {
286  assert(
287  type_counts[type] ==
288  1); /* each of accepted_input_types must be unique */
289  }
290  } else {
291  assert(cp.accepted_input_types.empty());
292  }
293  }
294  libff::leave_block("Perform type checks");
295 
296  for (size_t i = 0; i < compliance_predicates.size(); ++i) {
297  libff::enter_block(
298  FMT("",
299  "Process predicate %zu (with name %zu and type %zu)",
300  i,
301  compliance_predicates[i].name,
302  compliance_predicates[i].type));
303  assert(compliance_predicates[i].is_well_formed());
304 
305  libff::enter_block("Construct compliance step PCD circuit");
306  mp_compliance_step_pcd_circuit_maker<curve_A_pp>
307  mp_compliance_step_pcd_circuit(
308  compliance_predicates[i], compliance_predicates.size());
309  mp_compliance_step_pcd_circuit.generate_r1cs_constraints();
310  r1cs_constraint_system<FieldT_A> mp_compliance_step_pcd_circuit_cs =
311  mp_compliance_step_pcd_circuit.get_circuit();
312  libff::leave_block("Construct compliance step PCD circuit");
313 
314  libff::enter_block("Generate key pair for compliance step PCD circuit");
315  r1cs_ppzksnark_keypair<curve_A_pp> mp_compliance_step_keypair =
316  r1cs_ppzksnark_generator<curve_A_pp>(
317  mp_compliance_step_pcd_circuit_cs);
318  libff::leave_block("Generate key pair for compliance step PCD circuit");
319 
320  libff::enter_block("Construct translation step PCD circuit");
321  mp_translation_step_pcd_circuit_maker<curve_B_pp>
322  mp_translation_step_pcd_circuit(mp_compliance_step_keypair.vk);
323  mp_translation_step_pcd_circuit.generate_r1cs_constraints();
324  r1cs_constraint_system<FieldT_B> mp_translation_step_pcd_circuit_cs =
325  mp_translation_step_pcd_circuit.get_circuit();
326  libff::leave_block("Construct translation step PCD circuit");
327 
328  libff::enter_block(
329  "Generate key pair for translation step PCD circuit");
330  r1cs_ppzksnark_keypair<curve_B_pp> mp_translation_step_keypair =
331  r1cs_ppzksnark_generator<curve_B_pp>(
332  mp_translation_step_pcd_circuit_cs);
333  libff::leave_block(
334  "Generate key pair for translation step PCD circuit");
335 
336  libff::enter_block("Augment set of translation step verification keys");
337  const libff::bit_vector vk_bits =
338  r1cs_ppzksnark_verification_key_variable<curve_A_pp>::
339  get_verification_key_bits(mp_translation_step_keypair.vk);
340  all_translation_vks.add(vk_bits);
341  libff::leave_block("Augment set of translation step verification keys");
342 
343  libff::enter_block("Update r1cs_mp_ppzkpcd keypair");
344  keypair.pk.compliance_predicates.emplace_back(compliance_predicates[i]);
345  keypair.pk.compliance_step_r1cs_pks.emplace_back(
346  mp_compliance_step_keypair.pk);
347  keypair.pk.translation_step_r1cs_pks.emplace_back(
348  mp_translation_step_keypair.pk);
349  keypair.pk.compliance_step_r1cs_vks.emplace_back(
350  mp_compliance_step_keypair.vk);
351  keypair.pk.translation_step_r1cs_vks.emplace_back(
352  mp_translation_step_keypair.vk);
353  const size_t cp_name = compliance_predicates[i].name;
354  assert(
355  keypair.pk.compliance_predicate_name_to_idx.find(cp_name) ==
356  keypair.pk.compliance_predicate_name_to_idx
357  .end()); // all names must be distinct
358  keypair.pk.compliance_predicate_name_to_idx[cp_name] = i;
359 
360  keypair.vk.compliance_step_r1cs_vks.emplace_back(
361  mp_compliance_step_keypair.vk);
362  keypair.vk.translation_step_r1cs_vks.emplace_back(
363  mp_translation_step_keypair.vk);
364  libff::leave_block("Update r1cs_mp_ppzkpcd keypair");
365 
366  libff::leave_block(
367  FMT("",
368  "Process predicate %zu (with name %zu and type %zu)",
369  i,
370  compliance_predicates[i].name,
371  compliance_predicates[i].type));
372  }
373 
374  libff::enter_block(
375  "Compute set commitment and corresponding membership proofs");
376  const set_commitment cm = all_translation_vks.get_commitment();
377  keypair.pk.commitment_to_translation_step_r1cs_vks = cm;
378  keypair.vk.commitment_to_translation_step_r1cs_vks = cm;
379  for (size_t i = 0; i < compliance_predicates.size(); ++i) {
380  const libff::bit_vector vk_bits =
381  r1cs_ppzksnark_verification_key_variable<curve_A_pp>::
382  get_verification_key_bits(
383  keypair.vk.translation_step_r1cs_vks[i]);
384  const set_membership_proof proof =
385  all_translation_vks.get_membership_proof(vk_bits);
386 
387  keypair.pk.compliance_step_r1cs_vk_membership_proofs.emplace_back(
388  proof);
389  }
390  libff::leave_block(
391  "Compute set commitment and corresponding membership proofs");
392 
393  libff::print_indent();
394  libff::print_mem("in generator");
395  libff::leave_block("Call to r1cs_mp_ppzkpcd_generator");
396 
397  return keypair;
398 }
399 
400 template<typename PCD_ppT>
401 r1cs_mp_ppzkpcd_proof<PCD_ppT> r1cs_mp_ppzkpcd_prover(
402  const r1cs_mp_ppzkpcd_proving_key<PCD_ppT> &pk,
403  const size_t compliance_predicate_name,
404  const r1cs_mp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
405  const r1cs_mp_ppzkpcd_auxiliary_input<PCD_ppT> &auxiliary_input,
406  const std::vector<r1cs_mp_ppzkpcd_proof<PCD_ppT>> &prev_proofs)
407 {
408  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
409  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
410 
411  typedef libff::Fr<curve_A_pp> FieldT_A;
412  typedef libff::Fr<curve_B_pp> FieldT_B;
413 
414  libff::enter_block("Call to r1cs_mp_ppzkpcd_prover");
415 
416 #ifdef DEBUG
417  printf("Compliance predicate name: %zu\n", compliance_predicate_name);
418 #endif
419  auto it =
420  pk.compliance_predicate_name_to_idx.find(compliance_predicate_name);
421  assert(it != pk.compliance_predicate_name_to_idx.end());
422  const size_t compliance_predicate_idx = it->second;
423 
424 #ifdef DEBUG
425  printf("Outgoing message:\n");
426  primary_input.outgoing_message->print();
427 #endif
428 
429  libff::enter_block("Prove compliance step");
430  assert(compliance_predicate_idx < pk.compliance_predicates.size());
431  assert(
432  prev_proofs.size() <=
433  pk.compliance_predicates[compliance_predicate_idx].max_arity);
434 
435  const size_t arity = prev_proofs.size();
436  const size_t max_arity =
437  pk.compliance_predicates[compliance_predicate_idx].max_arity;
438 
439  if (pk.compliance_predicates[compliance_predicate_idx]
440  .relies_on_same_type_inputs) {
441  const size_t input_predicate_idx =
442  prev_proofs[0].compliance_predicate_idx;
443  for (size_t i = 1; i < arity; ++i) {
444  assert(
445  prev_proofs[i].compliance_predicate_idx == input_predicate_idx);
446  }
447  }
448 
449  std::vector<r1cs_ppzksnark_proof<curve_B_pp>> padded_proofs(max_arity);
450  for (size_t i = 0; i < arity; ++i) {
451  padded_proofs[i] = prev_proofs[i].r1cs_proof;
452  }
453 
454  std::vector<r1cs_ppzksnark_verification_key<curve_B_pp>>
455  translation_step_vks;
456  std::vector<set_membership_proof> membership_proofs;
457 
458  for (size_t i = 0; i < arity; ++i) {
459  const size_t input_predicate_idx =
460  prev_proofs[i].compliance_predicate_idx;
461  translation_step_vks.emplace_back(
462  pk.translation_step_r1cs_vks[input_predicate_idx]);
463  membership_proofs.emplace_back(
464  pk.compliance_step_r1cs_vk_membership_proofs[input_predicate_idx]);
465 
466 #ifdef DEBUG
467  if (auxiliary_input.incoming_messages[i]->type != 0) {
468  printf("check proof for message %zu\n", i);
469  const r1cs_primary_input<FieldT_B> translated_msg =
470  get_mp_translation_step_pcd_circuit_input<curve_B_pp>(
471  pk.commitment_to_translation_step_r1cs_vks,
472  auxiliary_input.incoming_messages[i]);
473  const bool bit = r1cs_ppzksnark_verifier_strong_IC<curve_B_pp>(
474  translation_step_vks[i], translated_msg, padded_proofs[i]);
475  assert(bit);
476  } else {
477  printf("message %zu is base case\n", i);
478  }
479 #endif
480  }
481 
482  /* pad with dummy vks/membership proofs */
483  for (size_t i = arity; i < max_arity; ++i) {
484  printf("proof %zu will be a dummy\n", arity);
485  translation_step_vks.emplace_back(pk.translation_step_r1cs_vks[0]);
486  membership_proofs.emplace_back(
487  pk.compliance_step_r1cs_vk_membership_proofs[0]);
488  }
489 
490  mp_compliance_step_pcd_circuit_maker<curve_A_pp>
491  mp_compliance_step_pcd_circuit(
492  pk.compliance_predicates[compliance_predicate_idx],
493  pk.compliance_predicates.size());
494 
495  mp_compliance_step_pcd_circuit.generate_r1cs_witness(
496  pk.commitment_to_translation_step_r1cs_vks,
497  translation_step_vks,
498  membership_proofs,
499  primary_input,
500  auxiliary_input,
501  padded_proofs);
502 
503  const r1cs_primary_input<FieldT_A> compliance_step_primary_input =
504  mp_compliance_step_pcd_circuit.get_primary_input();
505  const r1cs_auxiliary_input<FieldT_A> compliance_step_auxiliary_input =
506  mp_compliance_step_pcd_circuit.get_auxiliary_input();
507  const r1cs_ppzksnark_proof<curve_A_pp> compliance_step_proof =
508  r1cs_ppzksnark_prover<curve_A_pp>(
509  pk.compliance_step_r1cs_pks[compliance_predicate_idx],
510  compliance_step_primary_input,
511  compliance_step_auxiliary_input);
512  libff::leave_block("Prove compliance step");
513 
514 #ifdef DEBUG
515  const r1cs_primary_input<FieldT_A> compliance_step_input =
516  get_mp_compliance_step_pcd_circuit_input<curve_A_pp>(
517  pk.commitment_to_translation_step_r1cs_vks,
518  primary_input.outgoing_message);
519  const bool compliance_step_ok =
520  r1cs_ppzksnark_verifier_strong_IC<curve_A_pp>(
521  pk.compliance_step_r1cs_vks[compliance_predicate_idx],
522  compliance_step_input,
523  compliance_step_proof);
524  assert(compliance_step_ok);
525 #endif
526 
527  libff::enter_block("Prove translation step");
528  mp_translation_step_pcd_circuit_maker<curve_B_pp>
529  mp_translation_step_pcd_circuit(
530  pk.compliance_step_r1cs_vks[compliance_predicate_idx]);
531 
532  const r1cs_primary_input<FieldT_B> translation_step_primary_input =
533  get_mp_translation_step_pcd_circuit_input<curve_B_pp>(
534  pk.commitment_to_translation_step_r1cs_vks, primary_input);
535  mp_translation_step_pcd_circuit.generate_r1cs_witness(
536  translation_step_primary_input, compliance_step_proof);
537  const r1cs_auxiliary_input<FieldT_B> translation_step_auxiliary_input =
538  mp_translation_step_pcd_circuit.get_auxiliary_input();
539 
540  const r1cs_ppzksnark_proof<curve_B_pp> translation_step_proof =
541  r1cs_ppzksnark_prover<curve_B_pp>(
542  pk.translation_step_r1cs_pks[compliance_predicate_idx],
543  translation_step_primary_input,
544  translation_step_auxiliary_input);
545 
546  libff::leave_block("Prove translation step");
547 
548 #ifdef DEBUG
549  const bool translation_step_ok =
550  r1cs_ppzksnark_verifier_strong_IC<curve_B_pp>(
551  pk.translation_step_r1cs_vks[compliance_predicate_idx],
552  translation_step_primary_input,
553  translation_step_proof);
554  assert(translation_step_ok);
555 #endif
556 
557  libff::print_indent();
558  libff::print_mem("in prover");
559  libff::leave_block("Call to r1cs_mp_ppzkpcd_prover");
560 
561  r1cs_mp_ppzkpcd_proof<PCD_ppT> result;
562  result.compliance_predicate_idx = compliance_predicate_idx;
563  result.r1cs_proof = translation_step_proof;
564  return result;
565 }
566 
567 template<typename PCD_ppT>
568 bool r1cs_mp_ppzkpcd_online_verifier(
569  const r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk,
570  const r1cs_mp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
571  const r1cs_mp_ppzkpcd_proof<PCD_ppT> &proof)
572 {
573  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
574 
575  libff::enter_block("Call to r1cs_mp_ppzkpcd_online_verifier");
576  const r1cs_primary_input<libff::Fr<curve_B_pp>> r1cs_input =
577  get_mp_translation_step_pcd_circuit_input<curve_B_pp>(
578  pvk.commitment_to_translation_step_r1cs_vks, primary_input);
579  const bool result = r1cs_ppzksnark_online_verifier_strong_IC(
580  pvk.translation_step_r1cs_pvks[proof.compliance_predicate_idx],
581  r1cs_input,
582  proof.r1cs_proof);
583 
584  libff::print_indent();
585  libff::print_mem("in online verifier");
586  libff::leave_block("Call to r1cs_mp_ppzkpcd_online_verifier");
587  return result;
588 }
589 
590 template<typename PCD_ppT>
591 r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> r1cs_mp_ppzkpcd_process_vk(
592  const r1cs_mp_ppzkpcd_verification_key<PCD_ppT> &vk)
593 {
594  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
595  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
596 
597  libff::enter_block("Call to r1cs_mp_ppzkpcd_processed_verification_key");
598 
599  r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> result;
600  result.commitment_to_translation_step_r1cs_vks =
601  vk.commitment_to_translation_step_r1cs_vks;
602 
603  for (size_t i = 0; i < vk.compliance_step_r1cs_vks.size(); ++i) {
604  const r1cs_ppzksnark_processed_verification_key<curve_A_pp>
605  compliance_step_r1cs_pvk =
606  r1cs_ppzksnark_verifier_process_vk<curve_A_pp>(
607  vk.compliance_step_r1cs_vks[i]);
608  const r1cs_ppzksnark_processed_verification_key<curve_B_pp>
609  translation_step_r1cs_pvk =
610  r1cs_ppzksnark_verifier_process_vk<curve_B_pp>(
611  vk.translation_step_r1cs_vks[i]);
612 
613  result.compliance_step_r1cs_pvks.emplace_back(compliance_step_r1cs_pvk);
614  result.translation_step_r1cs_pvks.emplace_back(
615  translation_step_r1cs_pvk);
616  }
617  libff::leave_block("Call to r1cs_mp_ppzkpcd_processed_verification_key");
618 
619  return result;
620 }
621 
622 template<typename PCD_ppT>
623 bool r1cs_mp_ppzkpcd_verifier(
624  const r1cs_mp_ppzkpcd_verification_key<PCD_ppT> &vk,
625  const r1cs_mp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
626  const r1cs_mp_ppzkpcd_proof<PCD_ppT> &proof)
627 {
628  libff::enter_block("Call to r1cs_mp_ppzkpcd_verifier");
629  r1cs_mp_ppzkpcd_processed_verification_key<PCD_ppT> pvk =
630  r1cs_mp_ppzkpcd_process_vk(vk);
631  const bool result =
632  r1cs_mp_ppzkpcd_online_verifier(pvk, primary_input, proof);
633 
634  libff::print_indent();
635  libff::print_mem("in verifier");
636  libff::leave_block("Call to r1cs_mp_ppzkpcd_verifier");
637  return result;
638 }
639 
640 } // namespace libsnark
641 
642 #endif // R1CS_MP_PPZKPCD_TCC_