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