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