2 *****************************************************************************
4 Implementation of interfaces for a *single-predicate* ppzkPCD for R1CS.
6 See r1cs_sp_ppzkpcd.hpp .
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 *****************************************************************************/
14 #ifndef R1CS_SP_PPZKPCD_TCC_
15 #define R1CS_SP_PPZKPCD_TCC_
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>
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
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);
39 template<typename PCD_ppT>
40 std::ostream &operator<<(
41 std::ostream &out, const r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &pk)
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;
52 template<typename PCD_ppT>
53 std::istream &operator>>(
54 std::istream &in, r1cs_sp_ppzkpcd_proving_key<PCD_ppT> &pk)
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;
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
70 this->compliance_step_r1cs_vk == other.compliance_step_r1cs_vk &&
71 this->translation_step_r1cs_vk == other.translation_step_r1cs_vk);
74 template<typename PCD_ppT>
75 std::ostream &operator<<(
76 std::ostream &out, const r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk)
78 out << vk.compliance_step_r1cs_vk;
79 out << vk.translation_step_r1cs_vk;
84 template<typename PCD_ppT>
85 std::istream &operator>>(
86 std::istream &in, r1cs_sp_ppzkpcd_verification_key<PCD_ppT> &vk)
88 in >> vk.compliance_step_r1cs_vk;
89 in >> vk.translation_step_r1cs_vk;
94 template<typename PCD_ppT>
95 r1cs_sp_ppzkpcd_verification_key<PCD_ppT> r1cs_sp_ppzkpcd_verification_key<
96 PCD_ppT>::dummy_verification_key()
98 typedef typename PCD_ppT::curve_A_pp curve_A_pp;
99 typedef typename PCD_ppT::curve_B_pp curve_B_pp;
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());
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
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);
125 template<typename PCD_ppT>
126 std::ostream &operator<<(
128 const r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
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);
137 template<typename PCD_ppT>
138 std::istream &operator>>(
139 std::istream &in, r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> &pvk)
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);
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)
153 libff::Fr<typename PCD_ppT::curve_A_pp>::mod ==
154 libff::Fq<typename PCD_ppT::curve_B_pp>::mod);
156 libff::Fq<typename PCD_ppT::curve_A_pp>::mod ==
157 libff::Fr<typename PCD_ppT::curve_B_pp>::mod);
159 typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT_A;
160 typedef libff::Fr<typename PCD_ppT::curve_B_pp> FieldT_B;
162 typedef typename PCD_ppT::curve_A_pp curve_A_pp;
163 typedef typename PCD_ppT::curve_B_pp curve_B_pp;
165 libff::enter_block("Call to r1cs_sp_ppzkpcd_generator");
167 assert(compliance_predicate.is_well_formed());
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");
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");
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");
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");
197 libff::print_indent();
198 libff::print_mem("in generator");
199 libff::leave_block("Call to r1cs_sp_ppzkpcd_generator");
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));
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)
219 typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT_A;
220 typedef libff::Fr<typename PCD_ppT::curve_B_pp> FieldT_B;
222 typedef typename PCD_ppT::curve_A_pp curve_A_pp;
223 typedef typename PCD_ppT::curve_B_pp curve_B_pp;
225 libff::enter_block("Call to r1cs_sp_ppzkpcd_prover");
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);
231 printf("Outgoing message:\n");
232 primary_input.outgoing_message->print();
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,
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();
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");
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);
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);
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
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");
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);
297 libff::print_indent();
298 libff::print_mem("in prover");
299 libff::leave_block("Call to r1cs_sp_ppzkpcd_prover");
301 return translation_step_proof;
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)
311 typedef typename PCD_ppT::curve_B_pp curve_B_pp;
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");
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)
330 typedef typename PCD_ppT::curve_A_pp curve_A_pp;
331 typedef typename PCD_ppT::curve_B_pp curve_B_pp;
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");
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);
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)
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);
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");
371 } // namespace libsnark
373 #endif // R1CS_SP_PPZKPCD_TCC_