2  *****************************************************************************
 
    4  Implementation of functionality that runs the R1CS single-predicate ppzkPCD
 
    5  for a compliance predicate example.
 
    7  See run_r1cs_sp_ppzkpcd.hpp .
 
    9  *****************************************************************************
 
   10  * @author     This file is part of libsnark, developed by SCIPR Lab
 
   11  *             and contributors (see AUTHORS).
 
   12  * @copyright  MIT license (see LICENSE file)
 
   13  *****************************************************************************/
 
   15 #ifndef RUN_R1CS_SP_PPZKPCD_TCC_
 
   16 #define RUN_R1CS_SP_PPZKPCD_TCC_
 
   18 #include <libsnark/zk_proof_systems/pcd/r1cs_pcd/compliance_predicate/examples/tally_cp.hpp>
 
   19 #include <libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/r1cs_sp_ppzkpcd.hpp>
 
   24 template<typename PCD_ppT>
 
   25 bool run_r1cs_sp_ppzkpcd_tally_example(
 
   26     const size_t wordsize,
 
   29     const bool test_serialization)
 
   31     libff::enter_block("Call to run_r1cs_sp_ppzkpcd_tally_example");
 
   33     typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT;
 
   35     bool all_accept = true;
 
   37     libff::enter_block("Generate all messages");
 
   39     size_t nodes_in_layer = 1;
 
   40     for (size_t layer = 0; layer <= depth; ++layer) {
 
   41         tree_size += nodes_in_layer;
 
   42         nodes_in_layer *= arity;
 
   44     std::vector<size_t> tree_elems(tree_size);
 
   45     for (size_t i = 0; i < tree_size; ++i) {
 
   46         tree_elems[i] = std::rand() % 10;
 
   47         printf("tree_elems[%zu] = %zu\n", i, tree_elems[i]);
 
   49     libff::leave_block("Generate all messages");
 
   51     std::vector<r1cs_sp_ppzkpcd_proof<PCD_ppT>> tree_proofs(tree_size);
 
   52     std::vector<std::shared_ptr<r1cs_pcd_message<FieldT>>> tree_messages(
 
   55     libff::enter_block("Generate compliance predicate");
 
   56     const size_t type = 1;
 
   57     tally_cp_handler<FieldT> tally(type, arity, wordsize);
 
   58     tally.generate_r1cs_constraints();
 
   59     r1cs_pcd_compliance_predicate<FieldT> tally_cp =
 
   60         tally.get_compliance_predicate();
 
   61     libff::leave_block("Generate compliance predicate");
 
   63     libff::print_header("R1CS ppzkPCD Generator");
 
   64     r1cs_sp_ppzkpcd_keypair<PCD_ppT> keypair =
 
   65         r1cs_sp_ppzkpcd_generator<PCD_ppT>(tally_cp);
 
   67     libff::print_header("Process verification key");
 
   68     r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT> pvk =
 
   69         r1cs_sp_ppzkpcd_process_vk<PCD_ppT>(keypair.vk);
 
   71     if (test_serialization) {
 
   72         libff::enter_block("Test serialization of keys");
 
   73         keypair.pk = libff::reserialize<r1cs_sp_ppzkpcd_proving_key<PCD_ppT>>(
 
   76             libff::reserialize<r1cs_sp_ppzkpcd_verification_key<PCD_ppT>>(
 
   78         pvk = libff::reserialize<
 
   79             r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT>>(pvk);
 
   80         libff::leave_block("Test serialization of keys");
 
   83     std::shared_ptr<r1cs_pcd_message<FieldT>> base_msg =
 
   84         tally.get_base_case_message();
 
   85     nodes_in_layer /= arity;
 
   86     for (long layer = depth; layer >= 0; --layer, nodes_in_layer /= arity) {
 
   87         for (size_t i = 0; i < nodes_in_layer; ++i) {
 
   88             const size_t cur_idx = (nodes_in_layer - 1) / (arity - 1) + i;
 
   90             std::vector<std::shared_ptr<r1cs_pcd_message<FieldT>>> msgs(
 
   92             std::vector<r1cs_sp_ppzkpcd_proof<PCD_ppT>> proofs(arity);
 
   94             const bool base_case = (arity * cur_idx + arity >= tree_size);
 
   97                 for (size_t i = 0; i < arity; ++i) {
 
   98                     msgs[i] = tree_messages[arity * cur_idx + i + 1];
 
   99                     proofs[i] = tree_proofs[arity * cur_idx + i + 1];
 
  103             std::shared_ptr<r1cs_pcd_local_data<FieldT>> ld;
 
  104             ld.reset(new tally_pcd_local_data<FieldT>(tree_elems[cur_idx]));
 
  105             tally.generate_r1cs_witness(msgs, ld);
 
  107             const r1cs_pcd_compliance_predicate_primary_input<FieldT>
 
  108                 tally_primary_input(tally.get_outgoing_message());
 
  109             const r1cs_pcd_compliance_predicate_auxiliary_input<FieldT>
 
  110                 tally_auxiliary_input(msgs, ld, tally.get_witness());
 
  112             libff::print_header("R1CS ppzkPCD Prover");
 
  113             r1cs_sp_ppzkpcd_proof<PCD_ppT> proof =
 
  114                 r1cs_sp_ppzkpcd_prover<PCD_ppT>(
 
  117                     tally_auxiliary_input,
 
  120             if (test_serialization) {
 
  121                 libff::enter_block("Test serialization of proof");
 
  123                     libff::reserialize<r1cs_sp_ppzkpcd_proof<PCD_ppT>>(proof);
 
  124                 libff::leave_block("Test serialization of proof");
 
  127             tree_proofs[cur_idx] = proof;
 
  128             tree_messages[cur_idx] = tally.get_outgoing_message();
 
  130             libff::print_header("R1CS ppzkPCD Verifier");
 
  131             const r1cs_sp_ppzkpcd_primary_input<PCD_ppT> pcd_verifier_input(
 
  132                 tree_messages[cur_idx]);
 
  133             const bool ans = r1cs_sp_ppzkpcd_verifier<PCD_ppT>(
 
  134                 keypair.vk, pcd_verifier_input, tree_proofs[cur_idx]);
 
  136             libff::print_header("R1CS ppzkPCD Online Verifier");
 
  137             const bool ans2 = r1cs_sp_ppzkpcd_online_verifier<PCD_ppT>(
 
  138                 pvk, pcd_verifier_input, tree_proofs[cur_idx]);
 
  141             all_accept = all_accept && ans;
 
  144             for (size_t i = 0; i < arity; ++i) {
 
  145                 printf("Message %zu was:\n", i);
 
  148             printf("Summand at this node:\n%zu\n", tree_elems[cur_idx]);
 
  149             printf("Outgoing message is:\n");
 
  150             tree_messages[cur_idx]->print();
 
  153                 "Current node = %zu. Current proof verifies = %s\n",
 
  157                    "==========================================================="
 
  158                    "=====================\n\n\n");
 
  162     libff::leave_block("Call to run_r1cs_sp_ppzkpcd_tally_example");
 
  167 } // namespace libsnark
 
  169 #endif // RUN_R1CS_SP_PPZKPCD_TCC_