Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
qap.tcc
Go to the documentation of this file.
1 /** @file
2 *****************************************************************************
3 
4 Implementation of interfaces for a QAP ("Quadratic Arithmetic Program").
5 
6 See qap.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 QAP_TCC_
15 #define QAP_TCC_
16 
17 #include <libff/algebra/scalar_multiplication/multiexp.hpp>
18 #include <libff/common/profiling.hpp>
19 #include <libff/common/utils.hpp>
20 #include <libfqfft/evaluation_domain/evaluation_domain.hpp>
21 
22 namespace libsnark
23 {
24 
25 template<typename FieldT>
26 qap_instance<FieldT>::qap_instance(
27  const std::shared_ptr<libfqfft::evaluation_domain<FieldT>> &domain,
28  const size_t num_variables,
29  const size_t degree,
30  const size_t num_inputs,
31  const std::vector<std::map<size_t, FieldT>> &A_in_Lagrange_basis,
32  const std::vector<std::map<size_t, FieldT>> &B_in_Lagrange_basis,
33  const std::vector<std::map<size_t, FieldT>> &C_in_Lagrange_basis)
34  : num_variables_(num_variables)
35  , degree_(degree)
36  , num_inputs_(num_inputs)
37  , domain(domain)
38  , A_in_Lagrange_basis(A_in_Lagrange_basis)
39  , B_in_Lagrange_basis(B_in_Lagrange_basis)
40  , C_in_Lagrange_basis(C_in_Lagrange_basis)
41 {
42 }
43 
44 template<typename FieldT>
45 qap_instance<FieldT>::qap_instance(
46  const std::shared_ptr<libfqfft::evaluation_domain<FieldT>> &domain,
47  const size_t num_variables,
48  const size_t degree,
49  const size_t num_inputs,
50  std::vector<std::map<size_t, FieldT>> &&A_in_Lagrange_basis,
51  std::vector<std::map<size_t, FieldT>> &&B_in_Lagrange_basis,
52  std::vector<std::map<size_t, FieldT>> &&C_in_Lagrange_basis)
53  : num_variables_(num_variables)
54  , degree_(degree)
55  , num_inputs_(num_inputs)
56  , domain(domain)
57  , A_in_Lagrange_basis(std::move(A_in_Lagrange_basis))
58  , B_in_Lagrange_basis(std::move(B_in_Lagrange_basis))
59  , C_in_Lagrange_basis(std::move(C_in_Lagrange_basis))
60 {
61 }
62 
63 template<typename FieldT> size_t qap_instance<FieldT>::num_variables() const
64 {
65  return num_variables_;
66 }
67 
68 template<typename FieldT> size_t qap_instance<FieldT>::degree() const
69 {
70  return degree_;
71 }
72 
73 template<typename FieldT> size_t qap_instance<FieldT>::num_inputs() const
74 {
75  return num_inputs_;
76 }
77 
78 template<typename FieldT>
79 bool qap_instance<FieldT>::is_satisfied(
80  const qap_witness<FieldT> &witness) const
81 {
82  const FieldT t = FieldT::random_element();
83 
84  std::vector<FieldT> At(this->num_variables() + 1, FieldT::zero());
85  std::vector<FieldT> Bt(this->num_variables() + 1, FieldT::zero());
86  std::vector<FieldT> Ct(this->num_variables() + 1, FieldT::zero());
87  std::vector<FieldT> Ht(this->degree() + 1);
88 
89  const FieldT Zt = this->domain->compute_vanishing_polynomial(t);
90 
91  const std::vector<FieldT> u =
92  this->domain->evaluate_all_lagrange_polynomials(t);
93 
94  for (size_t i = 0; i < this->num_variables() + 1; ++i) {
95  for (auto &el : A_in_Lagrange_basis[i]) {
96  At[i] += u[el.first] * el.second;
97  }
98 
99  for (auto &el : B_in_Lagrange_basis[i]) {
100  Bt[i] += u[el.first] * el.second;
101  }
102 
103  for (auto &el : C_in_Lagrange_basis[i]) {
104  Ct[i] += u[el.first] * el.second;
105  }
106  }
107 
108  FieldT ti = FieldT::one();
109  for (size_t i = 0; i < this->degree() + 1; ++i) {
110  Ht[i] = ti;
111  ti *= t;
112  }
113 
114  const qap_instance_evaluation<FieldT> eval_qap_inst(
115  this->domain,
116  this->num_variables(),
117  this->degree(),
118  this->num_inputs(),
119  t,
120  std::move(At),
121  std::move(Bt),
122  std::move(Ct),
123  std::move(Ht),
124  Zt);
125  return eval_qap_inst.is_satisfied(witness);
126 }
127 
128 template<typename FieldT>
129 qap_instance_evaluation<FieldT>::qap_instance_evaluation(
130  const std::shared_ptr<libfqfft::evaluation_domain<FieldT>> &domain,
131  const size_t num_variables,
132  const size_t degree,
133  const size_t num_inputs,
134  const FieldT &t,
135  const std::vector<FieldT> &At,
136  const std::vector<FieldT> &Bt,
137  const std::vector<FieldT> &Ct,
138  const std::vector<FieldT> &Ht,
139  const FieldT &Zt)
140  : num_variables_(num_variables)
141  , degree_(degree)
142  , num_inputs_(num_inputs)
143  , domain(domain)
144  , t(t)
145  , At(At)
146  , Bt(Bt)
147  , Ct(Ct)
148  , Ht(Ht)
149  , Zt(Zt)
150 {
151 }
152 
153 template<typename FieldT>
154 qap_instance_evaluation<FieldT>::qap_instance_evaluation(
155  const std::shared_ptr<libfqfft::evaluation_domain<FieldT>> &domain,
156  const size_t num_variables,
157  const size_t degree,
158  const size_t num_inputs,
159  const FieldT &t,
160  std::vector<FieldT> &&At,
161  std::vector<FieldT> &&Bt,
162  std::vector<FieldT> &&Ct,
163  std::vector<FieldT> &&Ht,
164  const FieldT &Zt)
165  : num_variables_(num_variables)
166  , degree_(degree)
167  , num_inputs_(num_inputs)
168  , domain(domain)
169  , t(t)
170  , At(std::move(At))
171  , Bt(std::move(Bt))
172  , Ct(std::move(Ct))
173  , Ht(std::move(Ht))
174  , Zt(Zt)
175 {
176 }
177 
178 template<typename FieldT>
179 size_t qap_instance_evaluation<FieldT>::num_variables() const
180 {
181  return num_variables_;
182 }
183 
184 template<typename FieldT> size_t qap_instance_evaluation<FieldT>::degree() const
185 {
186  return degree_;
187 }
188 
189 template<typename FieldT>
190 size_t qap_instance_evaluation<FieldT>::num_inputs() const
191 {
192  return num_inputs_;
193 }
194 
195 template<typename FieldT>
196 bool qap_instance_evaluation<FieldT>::is_satisfied(
197  const qap_witness<FieldT> &witness) const
198 {
199 
200  if (this->num_variables() != witness.num_variables()) {
201  return false;
202  }
203 
204  if (this->degree() != witness.degree()) {
205  return false;
206  }
207 
208  if (this->num_inputs() != witness.num_inputs()) {
209  return false;
210  }
211 
212  if (this->num_variables() != witness.coefficients_for_ABCs.size()) {
213  return false;
214  }
215 
216  if (this->degree() + 1 != witness.coefficients_for_H.size()) {
217  return false;
218  }
219 
220  if (this->At.size() != this->num_variables() + 1 ||
221  this->Bt.size() != this->num_variables() + 1 ||
222  this->Ct.size() != this->num_variables() + 1) {
223  return false;
224  }
225 
226  if (this->Ht.size() != this->degree() + 1) {
227  return false;
228  }
229 
230  if (this->Zt != this->domain->compute_vanishing_polynomial(this->t)) {
231  return false;
232  }
233 
234  FieldT ans_A = this->At[0] + witness.d1 * this->Zt;
235  FieldT ans_B = this->Bt[0] + witness.d2 * this->Zt;
236  FieldT ans_C = this->Ct[0] + witness.d3 * this->Zt;
237  FieldT ans_H = FieldT::zero();
238 
239  ans_A = ans_A +
240  libff::inner_product<FieldT>(
241  this->At.begin() + 1,
242  this->At.begin() + 1 + this->num_variables(),
243  witness.coefficients_for_ABCs.begin(),
244  witness.coefficients_for_ABCs.begin() + this->num_variables());
245  ans_B = ans_B +
246  libff::inner_product<FieldT>(
247  this->Bt.begin() + 1,
248  this->Bt.begin() + 1 + this->num_variables(),
249  witness.coefficients_for_ABCs.begin(),
250  witness.coefficients_for_ABCs.begin() + this->num_variables());
251  ans_C = ans_C +
252  libff::inner_product<FieldT>(
253  this->Ct.begin() + 1,
254  this->Ct.begin() + 1 + this->num_variables(),
255  witness.coefficients_for_ABCs.begin(),
256  witness.coefficients_for_ABCs.begin() + this->num_variables());
257  ans_H =
258  ans_H + libff::inner_product<FieldT>(
259  this->Ht.begin(),
260  this->Ht.begin() + this->degree() + 1,
261  witness.coefficients_for_H.begin(),
262  witness.coefficients_for_H.begin() + this->degree() + 1);
263 
264  if (ans_A * ans_B - ans_C != ans_H * this->Zt) {
265  return false;
266  }
267 
268  return true;
269 }
270 
271 template<typename FieldT>
272 qap_witness<FieldT>::qap_witness(
273  const size_t num_variables,
274  const size_t degree,
275  const size_t num_inputs,
276  const FieldT &d1,
277  const FieldT &d2,
278  const FieldT &d3,
279  const std::vector<FieldT> &coefficients_for_ABCs,
280  const std::vector<FieldT> &coefficients_for_H)
281  : num_variables_(num_variables)
282  , degree_(degree)
283  , num_inputs_(num_inputs)
284  , d1(d1)
285  , d2(d2)
286  , d3(d3)
287  , coefficients_for_ABCs(coefficients_for_ABCs)
288  , coefficients_for_H(coefficients_for_H)
289 {
290 }
291 
292 template<typename FieldT>
293 qap_witness<FieldT>::qap_witness(
294  const size_t num_variables,
295  const size_t degree,
296  const size_t num_inputs,
297  const FieldT &d1,
298  const FieldT &d2,
299  const FieldT &d3,
300  const std::vector<FieldT> &coefficients_for_ABCs,
301  std::vector<FieldT> &&coefficients_for_H)
302  : num_variables_(num_variables)
303  , degree_(degree)
304  , num_inputs_(num_inputs)
305  , d1(d1)
306  , d2(d2)
307  , d3(d3)
308  , coefficients_for_ABCs(coefficients_for_ABCs)
309  , coefficients_for_H(std::move(coefficients_for_H))
310 {
311 }
312 
313 template<typename FieldT> size_t qap_witness<FieldT>::num_variables() const
314 {
315  return num_variables_;
316 }
317 
318 template<typename FieldT> size_t qap_witness<FieldT>::degree() const
319 {
320  return degree_;
321 }
322 
323 template<typename FieldT> size_t qap_witness<FieldT>::num_inputs() const
324 {
325  return num_inputs_;
326 }
327 
328 } // namespace libsnark
329 
330 #endif // QAP_TCC_