Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
gadget_from_r1cs.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  Implementation of interfaces for a gadget that can be created from an R1CS
5  constraint system.
6 
7  See gadget_from_r1cs.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 GADGET_FROM_R1CS_TCC_
16 #define GADGET_FROM_R1CS_TCC_
17 
18 namespace libsnark
19 {
20 
21 template<typename FieldT>
22 gadget_from_r1cs<FieldT>::gadget_from_r1cs(
23  protoboard<FieldT> &pb,
24  const std::vector<pb_variable_array<FieldT>> &vars,
25  const r1cs_constraint_system<FieldT> &cs,
26  const std::string &annotation_prefix)
27  : gadget<FieldT>(pb, annotation_prefix), vars(vars), cs(cs)
28 {
29  cs_to_vars[0] = 0; /* constant term maps to constant term */
30 
31  size_t cs_var_idx = 1;
32  for (auto va : vars) {
33 #ifdef DEBUG
34  printf(
35  "gadget_from_r1cs: translating a block of variables with length "
36  "%zu\n",
37  va.size());
38 #endif
39  for (auto v : va) {
40  cs_to_vars[cs_var_idx] = v.index;
41 
42 #ifdef DEBUG
43  if (v.index != 0) {
44  // handle annotations, except for re-annotating constant term
45  const std::map<size_t, std::string>::const_iterator it =
46  cs.variable_annotations.find(cs_var_idx);
47 
48  std::string annotation =
49  FMT(annotation_prefix, " variable_%zu", cs_var_idx);
50  if (it != cs.variable_annotations.end()) {
51  annotation = annotation_prefix + " " + it->second;
52  }
53 
54  pb.augment_variable_annotation(v, annotation);
55  }
56 #endif
57  ++cs_var_idx;
58  }
59  }
60 
61 #ifdef DEBUG
62  printf("gadget_from_r1cs: sum of all block lengths: %zu\n", cs_var_idx - 1);
63  printf("gadget_from_r1cs: cs.num_variables(): %zu\n", cs.num_variables());
64 #endif
65 
66  assert(cs_var_idx - 1 == cs.num_variables());
67 }
68 
69 template<typename FieldT>
70 void gadget_from_r1cs<FieldT>::generate_r1cs_constraints()
71 {
72  for (size_t i = 0; i < cs.num_constraints(); ++i) {
73  const r1cs_constraint<FieldT> &constr = cs.constraints[i];
74  r1cs_constraint<FieldT> translated_constr;
75 
76  for (const linear_term<FieldT> &t : constr.a.terms) {
77  translated_constr.a.terms.emplace_back(linear_term<FieldT>(
78  pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
79  }
80 
81  for (const linear_term<FieldT> &t : constr.b.terms) {
82  translated_constr.b.terms.emplace_back(linear_term<FieldT>(
83  pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
84  }
85 
86  for (const linear_term<FieldT> &t : constr.c.terms) {
87  translated_constr.c.terms.emplace_back(linear_term<FieldT>(
88  pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
89  }
90 
91  std::string annotation =
92  FMT(this->annotation_prefix, " constraint_%zu", i);
93 
94 #ifdef DEBUG
95  auto it = cs.constraint_annotations.find(i);
96  if (it != cs.constraint_annotations.end()) {
97  annotation = this->annotation_prefix + " " + it->second;
98  }
99 #endif
100  this->pb.add_r1cs_constraint(translated_constr, annotation);
101  }
102 }
103 
104 template<typename FieldT>
105 void gadget_from_r1cs<FieldT>::generate_r1cs_witness(
106  const r1cs_primary_input<FieldT> &primary_input,
107  const r1cs_auxiliary_input<FieldT> &auxiliary_input)
108 {
109  assert(cs.num_inputs() == primary_input.size());
110  assert(cs.num_variables() == primary_input.size() + auxiliary_input.size());
111 
112  for (size_t i = 0; i < primary_input.size(); ++i) {
113  this->pb.val(pb_variable<FieldT>(cs_to_vars[i + 1])) = primary_input[i];
114  }
115 
116  for (size_t i = 0; i < auxiliary_input.size(); ++i) {
117  this->pb.val(pb_variable<FieldT>(
118  cs_to_vars[primary_input.size() + i + 1])) = auxiliary_input[i];
119  }
120 }
121 
122 } // namespace libsnark
123 
124 #endif // GADGET_FROM_R1CS_TCC_