Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
run_r1cs_sp_ppzkpcd.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of functionality that runs the R1CS single-predicate ppzkPCD
5  for a compliance predicate example.
6 
7  See run_r1cs_sp_ppzkpcd.hpp .
8 
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  *****************************************************************************/
14 
15 #ifndef RUN_R1CS_SP_PPZKPCD_TCC_
16 #define RUN_R1CS_SP_PPZKPCD_TCC_
17 
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>
20 
21 namespace libsnark
22 {
23 
24 template<typename PCD_ppT>
25 bool run_r1cs_sp_ppzkpcd_tally_example(
26  const size_t wordsize,
27  const size_t arity,
28  const size_t depth,
29  const bool test_serialization)
30 {
31  libff::enter_block("Call to run_r1cs_sp_ppzkpcd_tally_example");
32 
33  typedef libff::Fr<typename PCD_ppT::curve_A_pp> FieldT;
34 
35  bool all_accept = true;
36 
37  libff::enter_block("Generate all messages");
38  size_t tree_size = 0;
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;
43  }
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]);
48  }
49  libff::leave_block("Generate all messages");
50 
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(
53  tree_size);
54 
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");
62 
63  libff::print_header("R1CS ppzkPCD Generator");
64  r1cs_sp_ppzkpcd_keypair<PCD_ppT> keypair =
65  r1cs_sp_ppzkpcd_generator<PCD_ppT>(tally_cp);
66 
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);
70 
71  if (test_serialization) {
72  libff::enter_block("Test serialization of keys");
73  keypair.pk = libff::reserialize<r1cs_sp_ppzkpcd_proving_key<PCD_ppT>>(
74  keypair.pk);
75  keypair.vk =
76  libff::reserialize<r1cs_sp_ppzkpcd_verification_key<PCD_ppT>>(
77  keypair.vk);
78  pvk = libff::reserialize<
79  r1cs_sp_ppzkpcd_processed_verification_key<PCD_ppT>>(pvk);
80  libff::leave_block("Test serialization of keys");
81  }
82 
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;
89 
90  std::vector<std::shared_ptr<r1cs_pcd_message<FieldT>>> msgs(
91  arity, base_msg);
92  std::vector<r1cs_sp_ppzkpcd_proof<PCD_ppT>> proofs(arity);
93 
94  const bool base_case = (arity * cur_idx + arity >= tree_size);
95 
96  if (!base_case) {
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];
100  }
101  }
102 
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);
106 
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());
111 
112  libff::print_header("R1CS ppzkPCD Prover");
113  r1cs_sp_ppzkpcd_proof<PCD_ppT> proof =
114  r1cs_sp_ppzkpcd_prover<PCD_ppT>(
115  keypair.pk,
116  tally_primary_input,
117  tally_auxiliary_input,
118  proofs);
119 
120  if (test_serialization) {
121  libff::enter_block("Test serialization of proof");
122  proof =
123  libff::reserialize<r1cs_sp_ppzkpcd_proof<PCD_ppT>>(proof);
124  libff::leave_block("Test serialization of proof");
125  }
126 
127  tree_proofs[cur_idx] = proof;
128  tree_messages[cur_idx] = tally.get_outgoing_message();
129 
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]);
135 
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]);
139  assert(ans == ans2);
140 
141  all_accept = all_accept && ans;
142 
143  printf("\n");
144  for (size_t i = 0; i < arity; ++i) {
145  printf("Message %zu was:\n", i);
146  msgs[i]->print();
147  }
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();
151  printf("\n");
152  printf(
153  "Current node = %zu. Current proof verifies = %s\n",
154  cur_idx,
155  ans ? "YES" : "NO");
156  printf("\n\n\n "
157  "==========================================================="
158  "=====================\n\n\n");
159  }
160  }
161 
162  libff::leave_block("Call to run_r1cs_sp_ppzkpcd_tally_example");
163 
164  return all_accept;
165 }
166 
167 } // namespace libsnark
168 
169 #endif // RUN_R1CS_SP_PPZKPCD_TCC_