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_