Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
ram_zksnark.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a zkSNARK for RAM.
5 
6  See ram_zksnark.hpp .
7 
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  *****************************************************************************/
13 
14 #ifndef RAM_ZKSNARK_TCC_
15 #define RAM_ZKSNARK_TCC_
16 
17 #include <libff/common/profiling.hpp>
18 
19 namespace libsnark
20 {
21 
22 template<typename ram_zksnark_ppT>
23 bool ram_zksnark_proving_key<ram_zksnark_ppT>::operator==(
24  const ram_zksnark_proving_key<ram_zksnark_ppT> &other) const
25 {
26  return (this->ap == other.ap && this->pcd_pk == other.pcd_pk);
27 }
28 
29 template<typename ram_zksnark_ppT>
30 std::ostream &operator<<(
31  std::ostream &out, const ram_zksnark_proving_key<ram_zksnark_ppT> &pk)
32 {
33  out << pk.ap;
34  out << pk.pcd_pk;
35 
36  return out;
37 }
38 
39 template<typename ram_zksnark_ppT>
40 std::istream &operator>>(
41  std::istream &in, ram_zksnark_proving_key<ram_zksnark_ppT> &pk)
42 {
43  in >> pk.ap;
44  in >> pk.pcd_pk;
45 
46  return in;
47 }
48 
49 template<typename ram_zksnark_ppT>
50 bool ram_zksnark_verification_key<ram_zksnark_ppT>::operator==(
51  const ram_zksnark_verification_key<ram_zksnark_ppT> &other) const
52 {
53  return (this->ap == other.ap && this->pcd_vk == other.pcd_vk);
54 }
55 
56 template<typename ram_zksnark_ppT>
57 std::ostream &operator<<(
58  std::ostream &out, const ram_zksnark_verification_key<ram_zksnark_ppT> &vk)
59 {
60  out << vk.ap;
61  out << vk.pcd_vk;
62 
63  return out;
64 }
65 
66 template<typename ram_zksnark_ppT>
67 std::istream &operator>>(
68  std::istream &in, ram_zksnark_verification_key<ram_zksnark_ppT> &vk)
69 {
70  in >> vk.ap;
71  in >> vk.pcd_vk;
72 
73  return in;
74 }
75 
76 template<typename ram_zksnark_ppT>
77 bool ram_zksnark_proof<ram_zksnark_ppT>::operator==(
78  const ram_zksnark_proof<ram_zksnark_ppT> &other) const
79 {
80  return (this->PCD_proof == other.PCD_proof);
81 }
82 
83 template<typename ram_zksnark_ppT>
84 std::ostream &operator<<(
85  std::ostream &out, const ram_zksnark_proof<ram_zksnark_ppT> &proof)
86 {
87  out << proof.PCD_proof;
88  return out;
89 }
90 
91 template<typename ram_zksnark_ppT>
92 std::istream &operator>>(
93  std::istream &in, ram_zksnark_proof<ram_zksnark_ppT> &proof)
94 {
95  in >> proof.PCD_proof;
96  return in;
97 }
98 
99 template<typename ram_zksnark_ppT>
100 ram_zksnark_verification_key<ram_zksnark_ppT> ram_zksnark_verification_key<
101  ram_zksnark_ppT>::
102  dummy_verification_key(
103  const ram_zksnark_architecture_params<ram_zksnark_ppT> &ap)
104 {
105  typedef ram_zksnark_PCD_pp<ram_zksnark_ppT> pcdT;
106 
107  return ram_zksnark_verification_key<ram_zksnark_ppT>(
108  ap, r1cs_sp_ppzkpcd_verification_key<pcdT>::dummy_verification_key());
109 }
110 
111 template<typename ram_zksnark_ppT>
112 ram_zksnark_keypair<ram_zksnark_ppT> ram_zksnark_generator(
113  const ram_zksnark_architecture_params<ram_zksnark_ppT> &ap)
114 {
115  typedef ram_zksnark_machine_pp<ram_zksnark_ppT> ramT;
116  typedef ram_zksnark_PCD_pp<ram_zksnark_ppT> pcdT;
117  libff::enter_block("Call to ram_zksnark_generator");
118 
119  libff::enter_block("Generate compliance predicate for RAM");
120  ram_compliance_predicate_handler<ramT> cp_handler(ap);
121  cp_handler.generate_r1cs_constraints();
122  r1cs_sp_ppzkpcd_compliance_predicate<pcdT> ram_compliance_predicate =
123  cp_handler.get_compliance_predicate();
124  libff::leave_block("Generate compliance predicate for RAM");
125 
126  libff::enter_block("Generate PCD key pair");
127  r1cs_sp_ppzkpcd_keypair<pcdT> kp =
128  r1cs_sp_ppzkpcd_generator<pcdT>(ram_compliance_predicate);
129  libff::leave_block("Generate PCD key pair");
130 
131  libff::leave_block("Call to ram_zksnark_generator");
132 
133  ram_zksnark_proving_key<ram_zksnark_ppT> pk =
134  ram_zksnark_proving_key<ram_zksnark_ppT>(ap, std::move(kp.pk));
135  ram_zksnark_verification_key<ram_zksnark_ppT> vk =
136  ram_zksnark_verification_key<ram_zksnark_ppT>(ap, std::move(kp.vk));
137 
138  return ram_zksnark_keypair<ram_zksnark_ppT>(std::move(pk), std::move(vk));
139 }
140 
141 template<typename ram_zksnark_ppT>
142 ram_zksnark_proof<ram_zksnark_ppT> ram_zksnark_prover(
143  const ram_zksnark_proving_key<ram_zksnark_ppT> &pk,
144  const ram_zksnark_primary_input<ram_zksnark_ppT> &primary_input,
145  const size_t time_bound,
146  const ram_zksnark_auxiliary_input<ram_zksnark_ppT> &auxiliary_input)
147 {
148  typedef ram_zksnark_machine_pp<ram_zksnark_ppT> ramT;
149  typedef ram_zksnark_PCD_pp<ram_zksnark_ppT> pcdT;
150  typedef libff::Fr<typename pcdT::curve_A_pp> FieldT; // XXX
151 
152  assert(libff::log2(time_bound) <= ramT::timestamp_length);
153 
154  libff::enter_block("Call to ram_zksnark_prover");
155  libff::enter_block("Generate compliance predicate for RAM");
156  ram_compliance_predicate_handler<ramT> cp_handler(pk.ap);
157  libff::leave_block("Generate compliance predicate for RAM");
158 
159  libff::enter_block("Initialize the RAM computation");
160  r1cs_sp_ppzkpcd_proof<pcdT> cur_proof; // start out with an empty proof
161 
162  /* initialize memory with the correct values */
163  const size_t num_addresses = 1ul << pk.ap.address_size();
164  const size_t value_size = pk.ap.value_size();
165 
166  delegated_ra_memory<CRH_with_bit_out_gadget<FieldT>> mem(
167  num_addresses, value_size, primary_input.as_memory_contents());
168  std::shared_ptr<r1cs_pcd_message<FieldT>> msg =
169  ram_compliance_predicate_handler<ramT>::get_base_case_message(
170  pk.ap, primary_input);
171 
172  typename ram_input_tape<ramT>::const_iterator aux_it =
173  auxiliary_input.begin();
174  libff::leave_block("Initialize the RAM computation");
175 
176  libff::enter_block("Execute and prove the computation");
177  bool want_halt = false;
178  for (size_t step = 1; step <= time_bound; ++step) {
179  libff::enter_block(
180  FMT("", "Prove step %zu out of %zu", step, time_bound));
181 
182  libff::enter_block("Execute witness map");
183 
184  std::shared_ptr<r1cs_pcd_local_data<FieldT>> local_data;
185  local_data.reset(new ram_pcd_local_data<ramT>(
186  want_halt, mem, aux_it, auxiliary_input.end()));
187 
188  cp_handler.generate_r1cs_witness({msg}, local_data);
189 
190  const r1cs_pcd_compliance_predicate_primary_input<FieldT>
191  cp_primary_input(cp_handler.get_outgoing_message());
192  const r1cs_pcd_compliance_predicate_auxiliary_input<FieldT>
193  cp_auxiliary_input({msg}, local_data, cp_handler.get_witness());
194 
195 #ifdef DEBUG
196  printf("Current state:\n");
197  msg->print();
198 #endif
199 
200  msg = cp_handler.get_outgoing_message();
201 
202 #ifdef DEBUG
203  printf("Next state:\n");
204  msg->print();
205 #endif
206  libff::leave_block("Execute witness map");
207 
208  cur_proof = r1cs_sp_ppzkpcd_prover<pcdT>(
209  pk.pcd_pk, cp_primary_input, cp_auxiliary_input, {cur_proof});
210  libff::leave_block(
211  FMT("", "Prove step %zu out of %zu", step, time_bound));
212  }
213  libff::leave_block("Execute and prove the computation");
214 
215  libff::enter_block("Finalize the computation");
216  want_halt = true;
217 
218  libff::enter_block("Execute witness map");
219 
220  std::shared_ptr<r1cs_pcd_local_data<FieldT>> local_data;
221  local_data.reset(new ram_pcd_local_data<ramT>(
222  want_halt, mem, aux_it, auxiliary_input.end()));
223 
224  cp_handler.generate_r1cs_witness({msg}, local_data);
225 
226  const r1cs_pcd_compliance_predicate_primary_input<FieldT> cp_primary_input(
227  cp_handler.get_outgoing_message());
228  const r1cs_pcd_compliance_predicate_auxiliary_input<FieldT>
229  cp_auxiliary_input({msg}, local_data, cp_handler.get_witness());
230  libff::leave_block("Execute witness map");
231 
232  cur_proof = r1cs_sp_ppzkpcd_prover<pcdT>(
233  pk.pcd_pk, cp_primary_input, cp_auxiliary_input, {cur_proof});
234  libff::leave_block("Finalize the computation");
235 
236  libff::leave_block("Call to ram_zksnark_prover");
237 
238  return cur_proof;
239 }
240 
241 template<typename ram_zksnark_ppT>
242 bool ram_zksnark_verifier(
243  const ram_zksnark_verification_key<ram_zksnark_ppT> &vk,
244  const ram_zksnark_primary_input<ram_zksnark_ppT> &primary_input,
245  const size_t time_bound,
246  const ram_zksnark_proof<ram_zksnark_ppT> &proof)
247 {
248  typedef ram_zksnark_machine_pp<ram_zksnark_ppT> ramT;
249  typedef ram_zksnark_PCD_pp<ram_zksnark_ppT> pcdT;
250  typedef libff::Fr<typename pcdT::curve_A_pp> FieldT; // XXX
251 
252  libff::enter_block("Call to ram_zksnark_verifier");
253  const r1cs_pcd_compliance_predicate_primary_input<FieldT> cp_primary_input(
254  ram_compliance_predicate_handler<ramT>::get_final_case_msg(
255  vk.ap, primary_input, time_bound));
256  bool ans = r1cs_sp_ppzkpcd_verifier<pcdT>(
257  vk.pcd_vk, cp_primary_input, proof.PCD_proof);
258  libff::leave_block("Call to ram_zksnark_verifier");
259 
260  return ans;
261 }
262 
263 } // namespace libsnark
264 
265 #endif // RAM_ZKSNARK_TCC_