2 *****************************************************************************
4 Implementation of interfaces for a zkSNARK for RAM.
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 RAM_ZKSNARK_TCC_
15 #define RAM_ZKSNARK_TCC_
17 #include <libff/common/profiling.hpp>
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
26 return (this->ap == other.ap && this->pcd_pk == other.pcd_pk);
29 template<typename ram_zksnark_ppT>
30 std::ostream &operator<<(
31 std::ostream &out, const ram_zksnark_proving_key<ram_zksnark_ppT> &pk)
39 template<typename ram_zksnark_ppT>
40 std::istream &operator>>(
41 std::istream &in, ram_zksnark_proving_key<ram_zksnark_ppT> &pk)
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
53 return (this->ap == other.ap && this->pcd_vk == other.pcd_vk);
56 template<typename ram_zksnark_ppT>
57 std::ostream &operator<<(
58 std::ostream &out, const ram_zksnark_verification_key<ram_zksnark_ppT> &vk)
66 template<typename ram_zksnark_ppT>
67 std::istream &operator>>(
68 std::istream &in, ram_zksnark_verification_key<ram_zksnark_ppT> &vk)
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
80 return (this->PCD_proof == other.PCD_proof);
83 template<typename ram_zksnark_ppT>
84 std::ostream &operator<<(
85 std::ostream &out, const ram_zksnark_proof<ram_zksnark_ppT> &proof)
87 out << proof.PCD_proof;
91 template<typename ram_zksnark_ppT>
92 std::istream &operator>>(
93 std::istream &in, ram_zksnark_proof<ram_zksnark_ppT> &proof)
95 in >> proof.PCD_proof;
99 template<typename ram_zksnark_ppT>
100 ram_zksnark_verification_key<ram_zksnark_ppT> ram_zksnark_verification_key<
102 dummy_verification_key(
103 const ram_zksnark_architecture_params<ram_zksnark_ppT> &ap)
105 typedef ram_zksnark_PCD_pp<ram_zksnark_ppT> pcdT;
107 return ram_zksnark_verification_key<ram_zksnark_ppT>(
108 ap, r1cs_sp_ppzkpcd_verification_key<pcdT>::dummy_verification_key());
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)
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");
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");
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");
131 libff::leave_block("Call to ram_zksnark_generator");
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));
138 return ram_zksnark_keypair<ram_zksnark_ppT>(std::move(pk), std::move(vk));
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)
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
152 assert(libff::log2(time_bound) <= ramT::timestamp_length);
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");
159 libff::enter_block("Initialize the RAM computation");
160 r1cs_sp_ppzkpcd_proof<pcdT> cur_proof; // start out with an empty proof
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();
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);
172 typename ram_input_tape<ramT>::const_iterator aux_it =
173 auxiliary_input.begin();
174 libff::leave_block("Initialize the RAM computation");
176 libff::enter_block("Execute and prove the computation");
177 bool want_halt = false;
178 for (size_t step = 1; step <= time_bound; ++step) {
180 FMT("", "Prove step %zu out of %zu", step, time_bound));
182 libff::enter_block("Execute witness map");
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()));
188 cp_handler.generate_r1cs_witness({msg}, local_data);
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());
196 printf("Current state:\n");
200 msg = cp_handler.get_outgoing_message();
203 printf("Next state:\n");
206 libff::leave_block("Execute witness map");
208 cur_proof = r1cs_sp_ppzkpcd_prover<pcdT>(
209 pk.pcd_pk, cp_primary_input, cp_auxiliary_input, {cur_proof});
211 FMT("", "Prove step %zu out of %zu", step, time_bound));
213 libff::leave_block("Execute and prove the computation");
215 libff::enter_block("Finalize the computation");
218 libff::enter_block("Execute witness map");
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()));
224 cp_handler.generate_r1cs_witness({msg}, local_data);
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");
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");
236 libff::leave_block("Call to ram_zksnark_prover");
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)
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
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");
263 } // namespace libsnark
265 #endif // RAM_ZKSNARK_TCC_