Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
r1cs_sp_ppzkpcd.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a *single-predicate* ppzkPCD for R1CS.
5 
6  See r1cs_sp_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_SP_PPZKPCD_TCC_
15 #define R1CS_SP_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/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/sp_pcd_circuits.hpp>
23 
24 namespace libsnark
25 {
26 
27 template<typename PCD_ppT>
28 bool r1cs_sp_ppzkpcd_proving_key<PCD_ppT>::operator==(
29  const r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &other) const
30 {
31  return (
32  this->compliance_predicate == other.compliance_predicate &&
33  this->compliance_step_r1cs_pk == other.compliance_step_r1cs_pk &&
34  this->translation_step_r1cs_pk == other.translation_step_r1cs_pk &&
35  this->compliance_step_r1cs_vk == other.compliance_step_r1cs_vk &&
36  this->translation_step_r1cs_vk == other.translation_step_r1cs_vk);
37 }
38 
39 template<typename PCD_ppT>
40 std::ostream &operator<<(
41  std::ostream &out, const r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &pk)
42 {
43  out << pk.compliance_predicate;
44  out << pk.compliance_step_r1cs_pk;
45  out << pk.translation_step_r1cs_pk;
46  out << pk.compliance_step_r1cs_vk;
47  out << pk.translation_step_r1cs_vk;
48 
49  return out;
50 }
51 
52 template<typename PCD_ppT>
53 std::istream &operator>>(
54  std::istream &in, r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &pk)
55 {
56  in >> pk.compliance_predicate;
57  in >> pk.compliance_step_r1cs_pk;
58  in >> pk.translation_step_r1cs_pk;
59  in >> pk.compliance_step_r1cs_vk;
60  in >> pk.translation_step_r1cs_vk;
61 
62  return in;
63 }
64 
65 template<typename PCD_ppT>
66 bool r1cs_sp_ppzkpcd_verification_key<PCD_ppT>::operator==(
67  const r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &other) const
68 {
69  return (
70  this->compliance_step_r1cs_vk == other.compliance_step_r1cs_vk &&
71  this->translation_step_r1cs_vk == other.translation_step_r1cs_vk);
72 }
73 
74 template<typename PCD_ppT>
75 std::ostream &operator<<(
76  std::ostream &out, const r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk)
77 {
78  out << vk.compliance_step_r1cs_vk;
79  out << vk.translation_step_r1cs_vk;
80 
81  return out;
82 }
83 
84 template<typename PCD_ppT>
85 std::istream &operator>>(
86  std::istream &in, r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk)
87 {
88  in >> vk.compliance_step_r1cs_vk;
89  in >> vk.translation_step_r1cs_vk;
90 
91  return in;
92 }
93 
94 template<typename PCD_ppT>
95 r1cs_sp_ppzkpcd_verification_key<PCD_ppT> r1cs_sp_ppzkpcd_verification_key<
96  PCD_ppT>::dummy_verification_key()
97 {
98  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
99  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
100 
101  r1cs_sp_ppzkpcd_verification_key<PCD_ppT> result;
102  result.compliance_step_r1cs_vk =
103  r1cs_ppzksnark_verification_key<typename PCD_ppT::curve_A_pp>::
104  dummy_verification_key(sp_compliance_step_pcd_circuit_maker<
105  curve_A_pp>::input_size_in_elts());
106  result.translation_step_r1cs_vk =
107  r1cs_ppzksnark_verification_key<typename PCD_ppT::curve_B_pp>::
108  dummy_verification_key(sp_translation_step_pcd_circuit_maker<
109  curve_B_pp>::input_size_in_elts());
110 
111  return result;
112 }
113 
114 template<typename PCD_ppT>
115 bool r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT>::operator==(
116  const r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &other) const
117 {
118  return (
119  this->compliance_step_r1cs_pvk == other.compliance_step_r1cs_pvk &&
120  this->translation_step_r1cs_pvk == other.translation_step_r1cs_pvk &&
121  this->translation_step_r1cs_vk_bits ==
122  other.translation_step_r1cs_vk_bits);
123 }
124 
125 template<typename PCD_ppT>
126 std::ostream &operator<<(
127  std::ostream &out,
128  const r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
129 {
130  out << pvk.compliance_step_r1cs_pvk;
131  out << pvk.translation_step_r1cs_pvk;
132  libff::serialize_bit_vector(out, pvk.translation_step_r1cs_vk_bits);
133 
134  return out;
135 }
136 
137 template<typename PCD_ppT>
138 std::istream &operator>>(
139  std::istream &in, r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
140 {
141  in >> pvk.compliance_step_r1cs_pvk;
142  in >> pvk.translation_step_r1cs_pvk;
143  libff::deserialize_bit_vector(in, pvk.translation_step_r1cs_vk_bits);
144 
145  return in;
146 }
147 
148 template<typename PCD_ppT>
149 r1cs_sp_ppzkpcd_keypair<PCD_ppT> r1cs_sp_ppzkpcd_generator(
150  const r1cs_sp_ppzkpcd_compliance_predicate<PCD_ppT> &compliance_predicate)
151 {
152  assert(
153  libff::Fr<typename PCD_ppT::curve_A_pp>::mod ==
154  libff::Fq<typename PCD_ppT::curve_B_pp>::mod);
155  assert(
156  libff::Fq<typename PCD_ppT::curve_A_pp>::mod ==
157  libff::Fr<typename PCD_ppT::curve_B_pp>::mod);
158 
159  typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT_A;
160  typedef libff::Fr<typename PCD_ppT::curve_B_pp> FieldT_B;
161 
162  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
163  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
164 
165  libff::enter_block("Call to r1cs_sp_ppzkpcd_generator");
166 
167  assert(compliance_predicate.is_well_formed());
168 
169  libff::enter_block("Construct compliance step PCD circuit");
170  sp_compliance_step_pcd_circuit_maker<curve_A_pp>
171  compliance_step_pcd_circuit(compliance_predicate);
172  compliance_step_pcd_circuit.generate_r1cs_constraints();
173  const r1cs_constraint_system<FieldT_A> compliance_step_pcd_circuit_cs =
174  compliance_step_pcd_circuit.get_circuit();
175  compliance_step_pcd_circuit_cs.report_linear_constraint_statistics();
176  libff::leave_block("Construct compliance step PCD circuit");
177 
178  libff::enter_block("Generate key pair for compliance step PCD circuit");
179  r1cs_ppzksnark_keypair<curve_A_pp> compliance_step_keypair =
180  r1cs_ppzksnark_generator<curve_A_pp>(compliance_step_pcd_circuit_cs);
181  libff::leave_block("Generate key pair for compliance step PCD circuit");
182 
183  libff::enter_block("Construct translation step PCD circuit");
184  sp_translation_step_pcd_circuit_maker<curve_B_pp>
185  translation_step_pcd_circuit(compliance_step_keypair.vk);
186  translation_step_pcd_circuit.generate_r1cs_constraints();
187  const r1cs_constraint_system<FieldT_B> translation_step_pcd_circuit_cs =
188  translation_step_pcd_circuit.get_circuit();
189  translation_step_pcd_circuit_cs.report_linear_constraint_statistics();
190  libff::leave_block("Construct translation step PCD circuit");
191 
192  libff::enter_block("Generate key pair for translation step PCD circuit");
193  r1cs_ppzksnark_keypair<curve_B_pp> translation_step_keypair =
194  r1cs_ppzksnark_generator<curve_B_pp>(translation_step_pcd_circuit_cs);
195  libff::leave_block("Generate key pair for translation step PCD circuit");
196 
197  libff::print_indent();
198  libff::print_mem("in generator");
199  libff::leave_block("Call to r1cs_sp_ppzkpcd_generator");
200 
201  return r1cs_sp_ppzkpcd_keypair<PCD_ppT>(
202  r1cs_sp_ppzkpcd_proving_key<PCD_ppT>(
203  compliance_predicate,
204  std::move(compliance_step_keypair.pk),
205  std::move(translation_step_keypair.pk),
206  compliance_step_keypair.vk,
207  translation_step_keypair.vk),
208  r1cs_sp_ppzkpcd_verification_key<PCD_ppT>(
209  compliance_step_keypair.vk, translation_step_keypair.vk));
210 }
211 
212 template<typename PCD_ppT>
213 r1cs_sp_ppzkpcd_proof<PCD_ppT> r1cs_sp_ppzkpcd_prover(
214  const r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &pk,
215  const r1cs_sp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
216  const r1cs_sp_ppzkpcd_auxiliary_input<PCD_ppT> &auxiliary_input,
217  const std::vector<r1cs_sp_ppzkpcd_proof<PCD_ppT>> &incoming_proofs)
218 {
219  typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT_A;
220  typedef libff::Fr<typename PCD_ppT::curve_B_pp> FieldT_B;
221 
222  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
223  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
224 
225  libff::enter_block("Call to r1cs_sp_ppzkpcd_prover");
226 
227  const libff::bit_vector translation_step_r1cs_vk_bits =
228  r1cs_ppzksnark_verification_key_variable<
229  curve_A_pp>::get_verification_key_bits(pk.translation_step_r1cs_vk);
230 #ifdef DEBUG
231  printf("Outgoing message:\n");
232  primary_input.outgoing_message->print();
233 #endif
234 
235  libff::enter_block("Prove compliance step");
236  sp_compliance_step_pcd_circuit_maker<curve_A_pp>
237  compliance_step_pcd_circuit(pk.compliance_predicate);
238  compliance_step_pcd_circuit.generate_r1cs_witness(
239  pk.translation_step_r1cs_vk,
240  primary_input,
241  auxiliary_input,
242  incoming_proofs);
243 
244  const r1cs_primary_input<FieldT_A> compliance_step_primary_input =
245  compliance_step_pcd_circuit.get_primary_input();
246  const r1cs_auxiliary_input<FieldT_A> compliance_step_auxiliary_input =
247  compliance_step_pcd_circuit.get_auxiliary_input();
248 
249  const r1cs_ppzksnark_proof<curve_A_pp> compliance_step_proof =
250  r1cs_ppzksnark_prover<curve_A_pp>(
251  pk.compliance_step_r1cs_pk,
252  compliance_step_primary_input,
253  compliance_step_auxiliary_input);
254  libff::leave_block("Prove compliance step");
255 
256 #ifdef DEBUG
257  const r1cs_primary_input<FieldT_A> compliance_step_input =
258  get_sp_compliance_step_pcd_circuit_input<curve_A_pp>(
259  translation_step_r1cs_vk_bits, primary_input);
260  const bool compliance_step_ok =
261  r1cs_ppzksnark_verifier_strong_IC<curve_A_pp>(
262  pk.compliance_step_r1cs_vk,
263  compliance_step_input,
264  compliance_step_proof);
265  assert(compliance_step_ok);
266 #endif
267 
268  libff::enter_block("Prove translation step");
269  sp_translation_step_pcd_circuit_maker<curve_B_pp>
270  translation_step_pcd_circuit(pk.compliance_step_r1cs_vk);
271 
272  const r1cs_primary_input<FieldT_B> translation_step_primary_input =
273  get_sp_translation_step_pcd_circuit_input<curve_B_pp>(
274  translation_step_r1cs_vk_bits, primary_input);
275  translation_step_pcd_circuit.generate_r1cs_witness(
276  translation_step_primary_input,
277  compliance_step_proof); // TODO: potential for better naming
278 
279  const r1cs_auxiliary_input<FieldT_B> translation_step_auxiliary_input =
280  translation_step_pcd_circuit.get_auxiliary_input();
281  const r1cs_ppzksnark_proof<curve_B_pp> translation_step_proof =
282  r1cs_ppzksnark_prover<curve_B_pp>(
283  pk.translation_step_r1cs_pk,
284  translation_step_primary_input,
285  translation_step_auxiliary_input);
286  libff::leave_block("Prove translation step");
287 
288 #ifdef DEBUG
289  const bool translation_step_ok =
290  r1cs_ppzksnark_verifier_strong_IC<curve_B_pp>(
291  pk.translation_step_r1cs_vk,
292  translation_step_primary_input,
293  translation_step_proof);
294  assert(translation_step_ok);
295 #endif
296 
297  libff::print_indent();
298  libff::print_mem("in prover");
299  libff::leave_block("Call to r1cs_sp_ppzkpcd_prover");
300 
301  return translation_step_proof;
302 }
303 
304 template<typename PCD_ppT>
305 bool r1cs_sp_ppzkpcd_online_verifier(
306  const r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk,
307  const r1cs_sp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
308  const r1cs_sp_ppzkpcd_proof<PCD_ppT> &proof)
309 
310 {
311  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
312 
313  libff::enter_block("Call to r1cs_sp_ppzkpcd_online_verifier");
314  const r1cs_primary_input<libff::Fr<curve_B_pp>> r1cs_input =
315  get_sp_translation_step_pcd_circuit_input<curve_B_pp>(
316  pvk.translation_step_r1cs_vk_bits, primary_input);
317  const bool result = r1cs_ppzksnark_online_verifier_strong_IC(
318  pvk.translation_step_r1cs_pvk, r1cs_input, proof);
319  libff::print_indent();
320  libff::print_mem("in online verifier");
321  libff::leave_block("Call to r1cs_sp_ppzkpcd_online_verifier");
322 
323  return result;
324 }
325 
326 template<typename PCD_ppT>
327 r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> r1cs_sp_ppzkpcd_process_vk(
328  const r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk)
329 {
330  typedef typename PCD_ppT::curve_A_pp curve_A_pp;
331  typedef typename PCD_ppT::curve_B_pp curve_B_pp;
332 
333  libff::enter_block("Call to r1cs_sp_ppzkpcd_processed_verification_key");
334  r1cs_ppzksnark_processed_verification_key<curve_A_pp>
335  compliance_step_r1cs_pvk =
336  r1cs_ppzksnark_verifier_process_vk<curve_A_pp>(
337  vk.compliance_step_r1cs_vk);
338  r1cs_ppzksnark_processed_verification_key<curve_B_pp>
339  translation_step_r1cs_pvk =
340  r1cs_ppzksnark_verifier_process_vk<curve_B_pp>(
341  vk.translation_step_r1cs_vk);
342  const libff::bit_vector translation_step_r1cs_vk_bits =
343  r1cs_ppzksnark_verification_key_variable<
344  curve_A_pp>::get_verification_key_bits(vk.translation_step_r1cs_vk);
345  libff::leave_block("Call to r1cs_sp_ppzkpcd_processed_verification_key");
346 
347  return r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT>(
348  std::move(compliance_step_r1cs_pvk),
349  std::move(translation_step_r1cs_pvk),
350  translation_step_r1cs_vk_bits);
351 }
352 
353 template<typename PCD_ppT>
354 bool r1cs_sp_ppzkpcd_verifier(
355  const r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk,
356  const r1cs_sp_ppzkpcd_primary_input<PCD_ppT> &primary_input,
357  const r1cs_sp_ppzkpcd_proof<PCD_ppT> &proof)
358 {
359  libff::enter_block("Call to r1cs_sp_ppzkpcd_verifier");
360  const r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> pvk =
361  r1cs_sp_ppzkpcd_process_vk(vk);
362  const bool result =
363  r1cs_sp_ppzkpcd_online_verifier(pvk, primary_input, proof);
364  libff::print_indent();
365  libff::print_mem("in verifier");
366  libff::leave_block("Call to r1cs_sp_ppzkpcd_verifier");
367 
368  return result;
369 }
370 
371 } // namespace libsnark
372 
373 #endif // R1CS_SP_PPZKPCD_TCC_