Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
ram_ppzksnark.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a ppzkSNARK for RAM.
5 
6  See ram_ppzksnark.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_PPZKSNARK_TCC_
15 #define RAM_PPZKSNARK_TCC_
16 
17 #include <libff/common/profiling.hpp>
18 #include <libsnark/reductions/ram_to_r1cs/ram_to_r1cs.hpp>
19 
20 namespace libsnark
21 {
22 
23 template<typename ram_ppzksnark_ppT>
24 bool ram_ppzksnark_proving_key<ram_ppzksnark_ppT>::operator==(
25  const ram_ppzksnark_proving_key<ram_ppzksnark_ppT> &other) const
26 {
27  return (
28  this->r1cs_pk == other.r1cs_pk && this->ap == other.ap &&
29  this->primary_input_size_bound == other.primary_input_size_bound &&
30  this->time_bound == other.time_bound);
31 }
32 
33 template<typename ram_ppzksnark_ppT>
34 std::ostream &operator<<(
35  std::ostream &out, const ram_ppzksnark_proving_key<ram_ppzksnark_ppT> &pk)
36 {
37  out << pk.r1cs_pk;
38  out << pk.ap;
39  out << pk.primary_input_size_bound << "\n";
40  out << pk.time_bound << "\n";
41 
42  return out;
43 }
44 
45 template<typename ram_ppzksnark_ppT>
46 std::istream &operator>>(
47  std::istream &in, ram_ppzksnark_proving_key<ram_ppzksnark_ppT> &pk)
48 {
49  in >> pk.r1cs_pk;
50  in >> pk.ap;
51  in >> pk.primary_input_size_bound;
52  libff::consume_newline(in);
53  in >> pk.time_bound;
54  libff::consume_newline(in);
55 
56  return in;
57 }
58 
59 template<typename ram_ppzksnark_ppT>
60 ram_ppzksnark_verification_key<ram_ppzksnark_ppT> ram_ppzksnark_verification_key<
61  ram_ppzksnark_ppT>::
62  bind_primary_input(const ram_ppzksnark_primary_input<ram_ppzksnark_ppT>
63  &primary_input) const
64 {
65  typedef ram_ppzksnark_machine_pp<ram_ppzksnark_ppT> ram_ppT;
66  typedef ram_base_field<ram_ppT> FieldT;
67 
68  libff::enter_block(
69  "Call to ram_ppzksnark_verification_key::bind_primary_input");
70  ram_ppzksnark_verification_key<ram_ppzksnark_ppT> result(*this);
71 
72  const size_t packed_input_element_size =
73  ram_universal_gadget<ram_ppT>::packed_input_element_size(ap);
74 
75  for (auto it : primary_input.get_all_trace_entries()) {
76  const size_t input_pos = it.first;
77  const address_and_value av = it.second;
78 
79  assert(input_pos < primary_input_size_bound);
80  assert(
81  result.bound_primary_input_locations.find(input_pos) ==
82  result.bound_primary_input_locations.end());
83 
84  const std::vector<FieldT> packed_input_element =
85  ram_to_r1cs<ram_ppT>::pack_primary_input_address_and_value(ap, av);
86  result.r1cs_vk.encoded_IC_query =
87  result.r1cs_vk.encoded_IC_query.template accumulate_chunk<FieldT>(
88  packed_input_element.begin(),
89  packed_input_element.end(),
90  packed_input_element_size *
91  (primary_input_size_bound - 1 - input_pos));
92 
93  result.bound_primary_input_locations.insert(input_pos);
94  }
95 
96  libff::leave_block(
97  "Call to ram_ppzksnark_verification_key::bind_primary_input");
98  return result;
99 }
100 
101 template<typename ram_ppzksnark_ppT>
102 bool ram_ppzksnark_verification_key<ram_ppzksnark_ppT>::operator==(
103  const ram_ppzksnark_verification_key<ram_ppzksnark_ppT> &other) const
104 {
105  return (
106  this->r1cs_vk == other.r1cs_vk && this->ap == other.ap &&
107  this->primary_input_size_bound == other.primary_input_size_bound &&
108  this->time_bound == other.time_bound);
109 }
110 
111 template<typename ram_ppzksnark_ppT>
112 std::ostream &operator<<(
113  std::ostream &out,
114  const ram_ppzksnark_verification_key<ram_ppzksnark_ppT> &vk)
115 {
116  out << vk.r1cs_vk;
117  out << vk.ap;
118  out << vk.primary_input_size_bound << "\n";
119  out << vk.time_bound << "\n";
120 
121  return out;
122 }
123 
124 template<typename ram_ppzksnark_ppT>
125 std::istream &operator>>(
126  std::istream &in, ram_ppzksnark_verification_key<ram_ppzksnark_ppT> &vk)
127 {
128  in >> vk.r1cs_vk;
129  in >> vk.ap;
130  in >> vk.primary_input_size_bound;
131  libff::consume_newline(in);
132  in >> vk.time_bound;
133  libff::consume_newline(in);
134 
135  return in;
136 }
137 
138 template<typename ram_ppzksnark_ppT>
139 ram_ppzksnark_keypair<ram_ppzksnark_ppT> ram_ppzksnark_generator(
140  const ram_ppzksnark_architecture_params<ram_ppzksnark_ppT> &ap,
141  const size_t primary_input_size_bound,
142  const size_t time_bound)
143 {
144  typedef ram_ppzksnark_machine_pp<ram_ppzksnark_ppT> ram_ppT;
145  typedef ram_ppzksnark_snark_pp<ram_ppzksnark_ppT> snark_ppT;
146 
147  libff::enter_block("Call to ram_ppzksnark_generator");
148  ram_to_r1cs<ram_ppT> universal_r1cs(
149  ap, primary_input_size_bound, time_bound);
150  universal_r1cs.instance_map();
151  r1cs_ppzksnark_keypair<snark_ppT> ppzksnark_keypair =
152  r1cs_ppzksnark_generator<snark_ppT>(
153  universal_r1cs.get_constraint_system());
154  libff::leave_block("Call to ram_ppzksnark_generator");
155 
156  ram_ppzksnark_proving_key<ram_ppzksnark_ppT> pk =
157  ram_ppzksnark_proving_key<ram_ppzksnark_ppT>(
158  std::move(ppzksnark_keypair.pk),
159  ap,
160  primary_input_size_bound,
161  time_bound);
162  ram_ppzksnark_verification_key<ram_ppzksnark_ppT> vk =
163  ram_ppzksnark_verification_key<ram_ppzksnark_ppT>(
164  std::move(ppzksnark_keypair.vk),
165  ap,
166  primary_input_size_bound,
167  time_bound);
168 
169  return ram_ppzksnark_keypair<ram_ppzksnark_ppT>(
170  std::move(pk), std::move(vk));
171 }
172 
173 template<typename ram_ppzksnark_ppT>
174 ram_ppzksnark_proof<ram_ppzksnark_ppT> ram_ppzksnark_prover(
175  const ram_ppzksnark_proving_key<ram_ppzksnark_ppT> &pk,
176  const ram_ppzksnark_primary_input<ram_ppzksnark_ppT> &primary_input,
177  const ram_ppzksnark_auxiliary_input<ram_ppzksnark_ppT> &auxiliary_input)
178 {
179  typedef ram_ppzksnark_machine_pp<ram_ppzksnark_ppT> ram_ppT;
180  typedef ram_ppzksnark_snark_pp<ram_ppzksnark_ppT> snark_ppT;
181  typedef libff::Fr<snark_ppT> FieldT;
182 
183  libff::enter_block("Call to ram_ppzksnark_prover");
184  ram_to_r1cs<ram_ppT> universal_r1cs(
185  pk.ap, pk.primary_input_size_bound, pk.time_bound);
186  const r1cs_primary_input<FieldT> r1cs_primary_input =
187  ram_to_r1cs<ram_ppT>::primary_input_map(
188  pk.ap, pk.primary_input_size_bound, primary_input);
189 
190  const r1cs_auxiliary_input<FieldT> r1cs_auxiliary_input =
191  universal_r1cs.auxiliary_input_map(primary_input, auxiliary_input);
192 #if DEBUG
193  universal_r1cs.print_execution_trace();
194  universal_r1cs.print_memory_trace();
195 #endif
196  const r1cs_ppzksnark_proof<snark_ppT> proof =
197  r1cs_ppzksnark_prover<snark_ppT>(
198  pk.r1cs_pk, r1cs_primary_input, r1cs_auxiliary_input);
199  libff::leave_block("Call to ram_ppzksnark_prover");
200 
201  return proof;
202 }
203 
204 template<typename ram_ppzksnark_ppT>
205 bool ram_ppzksnark_verifier(
206  const ram_ppzksnark_verification_key<ram_ppzksnark_ppT> &vk,
207  const ram_ppzksnark_primary_input<ram_ppzksnark_ppT> &primary_input,
208  const ram_ppzksnark_proof<ram_ppzksnark_ppT> &proof)
209 {
210  typedef ram_ppzksnark_snark_pp<ram_ppzksnark_ppT> snark_ppT;
211 
212  libff::enter_block("Call to ram_ppzksnark_verifier");
213  const ram_ppzksnark_verification_key<ram_ppzksnark_ppT> input_specific_vk =
214  vk.bind_primary_input(primary_input);
215  const bool ans = r1cs_ppzksnark_verifier_weak_IC<snark_ppT>(
216  input_specific_vk.r1cs_vk,
217  r1cs_primary_input<libff::Fr<snark_ppT>>(),
218  proof);
219  libff::leave_block("Call to ram_ppzksnark_verifier");
220 
221  return ans;
222 }
223 
224 } // namespace libsnark
225 
226 #endif // RAM_PPZKSNARK_TCC_