Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
basic_gadgets.hpp
Go to the documentation of this file.
1 
8 #ifndef BASIC_GADGETS_HPP_
9 #define BASIC_GADGETS_HPP_
10 
11 #include <cassert>
13 #include <memory>
14 
15 namespace libsnark
16 {
17 
18 /* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */
19 template<typename FieldT>
21  protoboard<FieldT> &pb,
22  const pb_linear_combination<FieldT> &lc,
23  const std::string &annotation_prefix = "");
24 
25 template<typename FieldT>
27  protoboard<FieldT> &pb,
28  const pb_linear_combination<FieldT> &lc,
29  const FieldT &c,
30  const std::string &annotation_prefix = "");
31 
36 template<typename FieldT> class packing_gadget : public gadget<FieldT>
37 {
38 private:
39  /* no internal variables */
40 public:
43 
48  const std::string &annotation_prefix = "")
50  {
51  }
52 
53  void generate_r1cs_constraints(const bool enforce_bitness);
54  /* adds constraint result = \sum bits[i] * 2^i */
55 
58 };
59 
60 template<typename FieldT> class multipacking_gadget : public gadget<FieldT>
61 {
62 private:
63  std::vector<packing_gadget<FieldT>> packers;
64 
65 public:
68 
69  const size_t chunk_size;
70  const size_t num_chunks;
71  // const size_t last_chunk_size;
72 
77  const size_t chunk_size,
78  const std::string &annotation_prefix = "");
79  void generate_r1cs_constraints(const bool enforce_bitness);
82 };
83 
84 template<typename FieldT> class field_vector_copy_gadget : public gadget<FieldT>
85 {
86 public:
90 
96  const std::string &annotation_prefix = "");
98  void generate_r1cs_witness();
99 };
100 
101 template<typename FieldT> class bit_vector_copy_gadget : public gadget<FieldT>
102 {
103 public:
107 
110 
111  std::shared_ptr<multipacking_gadget<FieldT>> pack_source;
112  std::shared_ptr<multipacking_gadget<FieldT>> pack_target;
113  std::shared_ptr<field_vector_copy_gadget<FieldT>> copier;
114 
115  const size_t chunk_size;
116  const size_t num_chunks;
117 
123  const size_t chunk_size,
124  const std::string &annotation_prefix = "");
126  const bool enforce_source_bitness, const bool enforce_target_bitness);
127  void generate_r1cs_witness();
128 };
129 
130 template<typename FieldT> class dual_variable_gadget : public gadget<FieldT>
131 {
132 private:
133  std::shared_ptr<packing_gadget<FieldT>> consistency_check;
134 
135 public:
138 
141  const size_t width,
142  const std::string &annotation_prefix = "")
143  : gadget<FieldT>(pb, annotation_prefix)
144  {
145  packed.allocate(pb, FMT(this->annotation_prefix, " packed"));
146  bits.allocate(pb, width, FMT(this->annotation_prefix, " bits"));
147  consistency_check.reset(new packing_gadget<FieldT>(
148  pb,
149  bits,
150  packed,
151  FMT(this->annotation_prefix, " consistency_check")));
152  }
153 
157  const std::string &annotation_prefix = "")
158  : gadget<FieldT>(pb, annotation_prefix), bits(bits)
159  {
160  packed.allocate(pb, FMT(this->annotation_prefix, " packed"));
161  consistency_check.reset(new packing_gadget<FieldT>(
162  pb,
163  bits,
164  packed,
165  FMT(this->annotation_prefix, " consistency_check")));
166  }
167 
171  const size_t width,
172  const std::string &annotation_prefix = "")
173  : gadget<FieldT>(pb, annotation_prefix), packed(packed)
174  {
175  bits.allocate(pb, width, FMT(this->annotation_prefix, " bits"));
176  consistency_check.reset(new packing_gadget<FieldT>(
177  pb,
178  bits,
179  packed,
180  FMT(this->annotation_prefix, " consistency_check")));
181  }
182 
183  void generate_r1cs_constraints(const bool enforce_bitness);
186 };
187 
188 /*
189  the gadgets below are Fp specific:
190  I * X = R
191  (1-R) * X = 0
192 
193  if X = 0 then R = 0
194  if X != 0 then R = 1 and I = X^{-1}
195 */
196 
198 template<typename FieldT> class disjunction_gadget : public gadget<FieldT>
199 {
200 private:
202 
203 public:
206 
211  const std::string &annotation_prefix = "")
213  {
214  assert(inputs.size() >= 1);
215  inv.allocate(pb, FMT(this->annotation_prefix, " inv"));
216  }
217 
219  void generate_r1cs_witness();
220 };
221 
222 template<typename FieldT> class conjunction_gadget : public gadget<FieldT>
223 {
224 private:
226 
227 public:
230 
235  const std::string &annotation_prefix = "")
237  {
238  assert(inputs.size() >= 1);
239  inv.allocate(pb, FMT(this->annotation_prefix, " inv"));
240  }
241 
243  void generate_r1cs_witness();
244 };
245 
246 template<typename FieldT> class comparison_gadget : public gadget<FieldT>
247 {
248 private:
250  pb_variable<FieldT> alpha_packed;
251  std::shared_ptr<packing_gadget<FieldT>> pack_alpha;
252 
253  std::shared_ptr<disjunction_gadget<FieldT>> all_zeros_test;
254  pb_variable<FieldT> not_all_zeros;
255 
256 public:
257  const size_t n;
262 
265  const size_t n,
268  const pb_variable<FieldT> &less,
270  const std::string &annotation_prefix = "")
271  : gadget<FieldT>(pb, annotation_prefix)
272  , n(n)
273  , A(A)
274  , B(B)
275  , less(less)
277  {
278  alpha.allocate(pb, n, FMT(this->annotation_prefix, " alpha"));
279  alpha.emplace_back(less_or_eq); // alpha[n] is less_or_eq
280 
281  alpha_packed.allocate(
282  pb, FMT(this->annotation_prefix, " alpha_packed"));
283  not_all_zeros.allocate(
284  pb, FMT(this->annotation_prefix, " not_all_zeros"));
285 
286  pack_alpha.reset(new packing_gadget<FieldT>(
287  pb,
288  alpha,
289  alpha_packed,
290  FMT(this->annotation_prefix, " pack_alpha")));
291 
292  all_zeros_test.reset(new disjunction_gadget<FieldT>(
293  pb,
294  pb_variable_array<FieldT>(alpha.begin(), alpha.begin() + n),
295  not_all_zeros,
296  FMT(this->annotation_prefix, " all_zeros_test")));
297  };
298 
300  void generate_r1cs_witness();
301 };
302 
303 template<typename FieldT> class inner_product_gadget : public gadget<FieldT>
304 {
305 private:
306  /* S_i = \sum_{k=0}^{i+1} A[i] * B[i] */
308 
309 public:
313 
319  const std::string &annotation_prefix = "")
320  : gadget<FieldT>(pb, annotation_prefix), A(A), B(B), result(result)
321  {
322  assert(A.size() >= 1);
323  assert(A.size() == B.size());
324 
325  S.allocate(pb, A.size() - 1, FMT(this->annotation_prefix, " S"));
326  }
327 
329  void generate_r1cs_witness();
330 };
331 
332 template<typename FieldT>
333 class loose_multiplexing_gadget : public gadget<FieldT>
334 {
335  /*
336  this implements loose multiplexer:
337  index not in bounds -> success_flag = 0
338  index in bounds && success_flag = 1 -> result is correct
339  however if index is in bounds we can also set success_flag to 0 (and then
340  result will be forced to be 0)
341  */
342 public:
344 
345 private:
346  std::shared_ptr<inner_product_gadget<FieldT>> compute_result;
347 
348 public:
353 
357  const pb_variable<FieldT> &index,
360  const std::string &annotation_prefix = "")
361  : gadget<FieldT>(pb, annotation_prefix)
362  , arr(arr)
363  , index(index)
364  , result(result)
366  {
367  alpha.allocate(pb, arr.size(), FMT(this->annotation_prefix, " alpha"));
368  compute_result.reset(new inner_product_gadget<FieldT>(
369  pb,
370  alpha,
371  arr,
372  result,
373  FMT(this->annotation_prefix, " compute_result")));
374  };
375 
377  void generate_r1cs_witness();
378 };
379 
380 template<typename FieldT, typename VarT>
382  protoboard<FieldT> &pb,
383  const std::vector<FieldT> &base,
384  const std::vector<std::pair<VarT, FieldT>> &v,
385  const VarT &target,
386  const std::string &annotation_prefix);
387 
388 template<typename FieldT, typename VarT>
390  protoboard<FieldT> &pb,
391  const std::vector<FieldT> &base,
392  const std::vector<std::pair<VarT, FieldT>> &v,
393  const VarT &target);
394 
395 } // namespace libsnark
396 
398 
399 #endif // BASIC_GADGETS_HPP_
libsnark::dual_variable_gadget::dual_variable_gadget
dual_variable_gadget(protoboard< FieldT > &pb, const pb_variable< FieldT > &packed, const size_t width, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:168
libsnark::bit_vector_copy_gadget::packed_target
pb_variable_array< FieldT > packed_target
Definition: basic_gadgets.hpp:109
libsnark::disjunction_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::bit_vector_copy_gadget::copier
std::shared_ptr< field_vector_copy_gadget< FieldT > > copier
Definition: basic_gadgets.hpp:113
libsnark::pb_variable_array::allocate
void allocate(protoboard< FieldT > &pb, const size_t n, const std::string &annotation_prefix)
libsnark::dual_variable_gadget::packed
pb_variable< FieldT > packed
Definition: basic_gadgets.hpp:136
libsnark::multipacking_gadget::generate_r1cs_constraints
void generate_r1cs_constraints(const bool enforce_bitness)
libsnark::multipacking_gadget::bits
const pb_linear_combination_array< FieldT > bits
Definition: basic_gadgets.hpp:66
libsnark::comparison_gadget::B
const pb_linear_combination< FieldT > B
Definition: basic_gadgets.hpp:259
libsnark::dual_variable_gadget::dual_variable_gadget
dual_variable_gadget(protoboard< FieldT > &pb, const pb_variable_array< FieldT > &bits, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:154
libsnark::dual_variable_gadget
Definition: basic_gadgets.hpp:130
libsnark::loose_multiplexing_gadget::index
const pb_variable< FieldT > index
Definition: basic_gadgets.hpp:350
libsnark::gadget::annotation_prefix
const std::string annotation_prefix
Definition: gadget.hpp:20
libsnark::packing_gadget::packing_gadget
packing_gadget(protoboard< FieldT > &pb, const pb_linear_combination_array< FieldT > &bits, const pb_linear_combination< FieldT > &packed, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:44
libsnark::comparison_gadget::n
const size_t n
Definition: basic_gadgets.hpp:257
libsnark::loose_multiplexing_gadget::loose_multiplexing_gadget
loose_multiplexing_gadget(protoboard< FieldT > &pb, const pb_linear_combination_array< FieldT > &arr, const pb_variable< FieldT > &index, const pb_variable< FieldT > &result, const pb_variable< FieldT > &success_flag, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:354
libsnark::generate_r1cs_equals_const_constraint
void generate_r1cs_equals_const_constraint(protoboard< FieldT > &pb, const pb_linear_combination< FieldT > &lc, const FieldT &c, const std::string &annotation_prefix="")
libsnark::dual_variable_gadget::bits
pb_variable_array< FieldT > bits
Definition: basic_gadgets.hpp:137
libsnark
Definition: accumulation_vector.hpp:18
libsnark::pb_variable::allocate
void allocate(protoboard< FieldT > &pb, const std::string &annotation)
libsnark::bit_vector_copy_gadget::bit_vector_copy_gadget
bit_vector_copy_gadget(protoboard< FieldT > &pb, const pb_variable_array< FieldT > &source_bits, const pb_variable_array< FieldT > &target_bits, const pb_linear_combination< FieldT > &do_copy, const size_t chunk_size, const std::string &annotation_prefix="")
libsnark::disjunction_gadget::output
const pb_variable< FieldT > output
Definition: basic_gadgets.hpp:205
libsnark::bit_vector_copy_gadget::generate_r1cs_constraints
void generate_r1cs_constraints(const bool enforce_source_bitness, const bool enforce_target_bitness)
libsnark::gadget::pb
protoboard< FieldT > & pb
Definition: gadget.hpp:19
libsnark::disjunction_gadget::disjunction_gadget
disjunction_gadget(protoboard< FieldT > &pb, const pb_linear_combination_array< FieldT > &inputs, const pb_variable< FieldT > &output, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:207
libsnark::comparison_gadget::A
const pb_linear_combination< FieldT > A
Definition: basic_gadgets.hpp:258
libsnark::packing_gadget::generate_r1cs_witness_from_bits
void generate_r1cs_witness_from_bits()
libsnark::multipacking_gadget::generate_r1cs_witness_from_bits
void generate_r1cs_witness_from_bits()
libsnark::dual_variable_gadget::generate_r1cs_witness_from_packed
void generate_r1cs_witness_from_packed()
libsnark::field_vector_copy_gadget::field_vector_copy_gadget
field_vector_copy_gadget(protoboard< FieldT > &pb, const pb_variable_array< FieldT > &source, const pb_variable_array< FieldT > &target, const pb_linear_combination< FieldT > &do_copy, const std::string &annotation_prefix="")
libsnark::loose_multiplexing_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::conjunction_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
gadget.hpp
libsnark::inner_product_gadget::result
const pb_variable< FieldT > result
Definition: basic_gadgets.hpp:312
libsnark::disjunction_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::packing_gadget::packed
const pb_linear_combination< FieldT > packed
Definition: basic_gadgets.hpp:42
libsnark::comparison_gadget
Definition: basic_gadgets.hpp:246
libsnark::gadget
Definition: gadget.hpp:16
libsnark::generate_boolean_r1cs_constraint
void generate_boolean_r1cs_constraint(protoboard< FieldT > &pb, const pb_linear_combination< FieldT > &lc, const std::string &annotation_prefix="")
libsnark::multipacking_gadget::multipacking_gadget
multipacking_gadget(protoboard< FieldT > &pb, const pb_linear_combination_array< FieldT > &bits, const pb_linear_combination_array< FieldT > &packed_vars, const size_t chunk_size, const std::string &annotation_prefix="")
libsnark::inner_product_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::loose_multiplexing_gadget::success_flag
const pb_variable< FieldT > success_flag
Definition: basic_gadgets.hpp:352
libsnark::multipacking_gadget
Definition: basic_gadgets.hpp:60
libsnark::bit_vector_copy_gadget::chunk_size
const size_t chunk_size
Definition: basic_gadgets.hpp:115
libsnark::packing_gadget::generate_r1cs_witness_from_packed
void generate_r1cs_witness_from_packed()
libsnark::dual_variable_gadget::generate_r1cs_constraints
void generate_r1cs_constraints(const bool enforce_bitness)
libsnark::inner_product_gadget::B
const pb_linear_combination_array< FieldT > B
Definition: basic_gadgets.hpp:311
libsnark::dual_variable_gadget::dual_variable_gadget
dual_variable_gadget(protoboard< FieldT > &pb, const size_t width, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:139
libsnark::field_vector_copy_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::bit_vector_copy_gadget::packed_source
pb_variable_array< FieldT > packed_source
Definition: basic_gadgets.hpp:108
libsnark::loose_multiplexing_gadget::result
const pb_variable< FieldT > result
Definition: basic_gadgets.hpp:351
libsnark::inner_product_gadget::A
const pb_linear_combination_array< FieldT > A
Definition: basic_gadgets.hpp:310
libsnark::comparison_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::bit_vector_copy_gadget::pack_target
std::shared_ptr< multipacking_gadget< FieldT > > pack_target
Definition: basic_gadgets.hpp:112
libsnark::create_linear_combination_witness
void create_linear_combination_witness(protoboard< FieldT > &pb, const std::vector< FieldT > &base, const std::vector< std::pair< VarT, FieldT >> &v, const VarT &target)
libsnark::field_vector_copy_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::conjunction_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::pb_linear_combination_array
Definition: pb_variable.hpp:118
libsnark::inner_product_gadget::inner_product_gadget
inner_product_gadget(protoboard< FieldT > &pb, const pb_linear_combination_array< FieldT > &A, const pb_linear_combination_array< FieldT > &B, const pb_variable< FieldT > &result, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:314
libsnark::field_vector_copy_gadget::source
const pb_variable_array< FieldT > source
Definition: basic_gadgets.hpp:87
libsnark::loose_multiplexing_gadget::alpha
pb_variable_array< FieldT > alpha
Definition: basic_gadgets.hpp:343
libsnark::pb_linear_combination
Definition: pb_variable.hpp:101
libsnark::field_vector_copy_gadget::target
const pb_variable_array< FieldT > target
Definition: basic_gadgets.hpp:88
libsnark::create_linear_combination_constraints
void create_linear_combination_constraints(protoboard< FieldT > &pb, const std::vector< FieldT > &base, const std::vector< std::pair< VarT, FieldT >> &v, const VarT &target, const std::string &annotation_prefix)
basic_gadgets.tcc
libsnark::disjunction_gadget::inputs
const pb_linear_combination_array< FieldT > inputs
Definition: basic_gadgets.hpp:204
libsnark::conjunction_gadget::conjunction_gadget
conjunction_gadget(protoboard< FieldT > &pb, const pb_variable_array< FieldT > &inputs, const pb_variable< FieldT > &output, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:231
libsnark::comparison_gadget::comparison_gadget
comparison_gadget(protoboard< FieldT > &pb, const size_t n, const pb_linear_combination< FieldT > &A, const pb_linear_combination< FieldT > &B, const pb_variable< FieldT > &less, const pb_variable< FieldT > &less_or_eq, const std::string &annotation_prefix="")
Definition: basic_gadgets.hpp:263
libsnark::pb_variable
Definition: pb_variable.hpp:24
libsnark::field_vector_copy_gadget
Definition: basic_gadgets.hpp:84
libsnark::multipacking_gadget::num_chunks
const size_t num_chunks
Definition: basic_gadgets.hpp:70
libsnark::packing_gadget
Definition: basic_gadgets.hpp:36
libsnark::conjunction_gadget::inputs
const pb_variable_array< FieldT > inputs
Definition: basic_gadgets.hpp:228
libsnark::conjunction_gadget::output
const pb_variable< FieldT > output
Definition: basic_gadgets.hpp:229
libsnark::bit_vector_copy_gadget::source_bits
const pb_variable_array< FieldT > source_bits
Definition: basic_gadgets.hpp:104
libsnark::loose_multiplexing_gadget
Definition: basic_gadgets.hpp:333
libsnark::pb_variable_array
Definition: pb_variable.hpp:44
libsnark::multipacking_gadget::generate_r1cs_witness_from_packed
void generate_r1cs_witness_from_packed()
libsnark::loose_multiplexing_gadget::arr
const pb_linear_combination_array< FieldT > arr
Definition: basic_gadgets.hpp:349
libsnark::conjunction_gadget
Definition: basic_gadgets.hpp:222
libsnark::comparison_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::dual_variable_gadget::generate_r1cs_witness_from_bits
void generate_r1cs_witness_from_bits()
libsnark::inner_product_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::multipacking_gadget::chunk_size
const size_t chunk_size
Definition: basic_gadgets.hpp:69
libsnark::disjunction_gadget
Output is 0 iff the sum of inputs is 0. Output is 1 otherwise.
Definition: basic_gadgets.hpp:198
libsnark::bit_vector_copy_gadget
Definition: basic_gadgets.hpp:101
libsnark::bit_vector_copy_gadget::do_copy
const pb_linear_combination< FieldT > do_copy
Definition: basic_gadgets.hpp:106
libsnark::loose_multiplexing_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::comparison_gadget::less
const pb_variable< FieldT > less
Definition: basic_gadgets.hpp:260
libsnark::comparison_gadget::less_or_eq
const pb_variable< FieldT > less_or_eq
Definition: basic_gadgets.hpp:261
libsnark::field_vector_copy_gadget::do_copy
const pb_linear_combination< FieldT > do_copy
Definition: basic_gadgets.hpp:89
libsnark::packing_gadget::generate_r1cs_constraints
void generate_r1cs_constraints(const bool enforce_bitness)
libsnark::inner_product_gadget
Definition: basic_gadgets.hpp:303
libsnark::bit_vector_copy_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::bit_vector_copy_gadget::num_chunks
const size_t num_chunks
Definition: basic_gadgets.hpp:116
libsnark::multipacking_gadget::packed_vars
const pb_linear_combination_array< FieldT > packed_vars
Definition: basic_gadgets.hpp:67
libsnark::bit_vector_copy_gadget::pack_source
std::shared_ptr< multipacking_gadget< FieldT > > pack_source
Definition: basic_gadgets.hpp:111
libsnark::packing_gadget::bits
const pb_linear_combination_array< FieldT > bits
Definition: basic_gadgets.hpp:41
libsnark::bit_vector_copy_gadget::target_bits
const pb_variable_array< FieldT > target_bits
Definition: basic_gadgets.hpp:105
libsnark::protoboard
Definition: pb_variable.hpp:22