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_