sap.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 // @file Declaration of interfaces for a SAP ("Square Arithmetic Program").
26 //
27 // SAPs are defined in \[GM17].
28 //
29 // References:
30 //
31 // \[GM17]:
32 // "Snarky Signatures: Minimal Signatures of Knowledge from
33 // Simulation-Extractable SNARKs",
34 // Jens Groth and Mary Maller,
35 // IACR-CRYPTO-2017,
36 // <https://eprint.iacr.org/2017/540>
37 //---------------------------------------------------------------------------//
38 
39 #ifndef CRYPTO3_ZK_SAP_HPP
40 #define CRYPTO3_ZK_SAP_HPP
41 
42 #include <map>
43 #include <vector>
44 
47 
48 #include <nil/crypto3/math/evaluation_domain.hpp>
49 
50 namespace nil {
51  namespace crypto3 {
52  namespace zk {
53  namespace snark {
54 
55  using namespace nil::crypto3::math;
56 
57  template<typename FieldType>
58  struct sap_witness;
59 
60  template<typename FieldType>
61  struct sap_instance_evaluation;
62 
63  /************************* INSTATNCE ***********************************/
64 
76  template<typename FieldType>
77  struct sap_instance {
78  std::size_t num_variables;
79  std::size_t degree;
80  std::size_t num_inputs;
81 
82  std::shared_ptr<evaluation_domain<FieldType>> domain;
83 
84  std::vector<std::map<std::size_t, typename FieldType::value_type>> A_in_Lagrange_basis;
85  std::vector<std::map<std::size_t, typename FieldType::value_type>> C_in_Lagrange_basis;
86 
88  const std::shared_ptr<evaluation_domain<FieldType>> &domain,
89  const std::size_t num_variables,
90  const std::size_t degree,
91  const std::size_t num_inputs,
92  const std::vector<std::map<std::size_t, typename FieldType::value_type>> &A_in_Lagrange_basis,
93  const std::vector<std::map<std::size_t, typename FieldType::value_type>> &C_in_Lagrange_basis) :
94  num_variables(num_variables),
95  degree(degree), num_inputs(num_inputs), domain(domain),
96  A_in_Lagrange_basis(A_in_Lagrange_basis), C_in_Lagrange_basis(C_in_Lagrange_basis) {
97  }
98 
100  const std::shared_ptr<evaluation_domain<FieldType>> &domain,
101  const std::size_t num_variables,
102  const std::size_t degree,
103  const std::size_t num_inputs,
104  std::vector<std::map<std::size_t, typename FieldType::value_type>> &&A_in_Lagrange_basis,
105  std::vector<std::map<std::size_t, typename FieldType::value_type>> &&C_in_Lagrange_basis) :
106  num_variables(num_variables),
107  degree(degree), num_inputs(num_inputs), domain(domain),
108  A_in_Lagrange_basis(std::move(A_in_Lagrange_basis)),
109  C_in_Lagrange_basis(std::move(C_in_Lagrange_basis)) {
110  }
111 
112  sap_instance(const sap_instance<FieldType> &other) = default;
116 
117  bool is_satisfied(const sap_witness<FieldType> &witness) const {
118  const typename FieldType::value_type t = algebra::random_element<FieldType>();
119 
120  std::vector<typename FieldType::value_type> At(this->num_variables + 1,
121  FieldType::value_type::zero());
122  std::vector<typename FieldType::value_type> Ct(this->num_variables + 1,
123  FieldType::value_type::zero());
124  std::vector<typename FieldType::value_type> Ht(this->degree + 1);
125 
126  const typename FieldType::value_type Zt = this->domain->compute_vanishing_polynomial(t);
127 
128  const std::vector<typename FieldType::value_type> u =
129  this->domain->evaluate_all_lagrange_polynomials(t);
130 
131  for (std::size_t i = 0; i < this->num_variables + 1; ++i) {
132  for (auto &el : A_in_Lagrange_basis[i]) {
133  At[i] += u[el.first] * el.second;
134  }
135 
136  for (auto &el : C_in_Lagrange_basis[i]) {
137  Ct[i] += u[el.first] * el.second;
138  }
139  }
140 
141  typename FieldType::value_type ti = FieldType::value_type::one();
142  for (std::size_t i = 0; i < this->degree + 1; ++i) {
143  Ht[i] = ti;
144  ti *= t;
145  }
146 
147  const sap_instance_evaluation<FieldType> eval_sap_inst(this->domain,
148  this->num_variables,
149  this->degree,
150  this->num_inputs,
151  t,
152  std::move(At),
153  std::move(Ct),
154  std::move(Ht),
155  Zt);
156  return eval_sap_inst.is_satisfied(witness);
157  }
158  };
159 
160  /************************* INSTATNCE EVALUATION ***********************************/
161 
173  template<typename FieldType>
175  std::size_t num_variables;
176  std::size_t degree;
177  std::size_t num_inputs;
178 
179  std::shared_ptr<evaluation_domain<FieldType>> domain;
180 
181  typename FieldType::value_type t;
182 
183  std::vector<typename FieldType::value_type> At, Ct, Ht;
184 
185  typename FieldType::value_type Zt;
186 
188  const std::size_t num_variables,
189  const std::size_t degree,
190  const std::size_t num_inputs,
191  const typename FieldType::value_type &t,
192  const std::vector<typename FieldType::value_type> &At,
193  const std::vector<typename FieldType::value_type> &Ct,
194  const std::vector<typename FieldType::value_type> &Ht,
195  const typename FieldType::value_type &Zt) :
196  num_variables(num_variables),
197  degree(degree), num_inputs(num_inputs), domain(domain), t(t), At(At), Ct(Ct), Ht(Ht), Zt(Zt) {
198  }
199 
201  const std::size_t num_variables,
202  const std::size_t degree,
203  const std::size_t num_inputs,
204  const typename FieldType::value_type &t,
205  std::vector<typename FieldType::value_type> &&At,
206  std::vector<typename FieldType::value_type> &&Ct,
207  std::vector<typename FieldType::value_type> &&Ht,
208  const typename FieldType::value_type &Zt) :
209  num_variables(num_variables),
210  degree(degree), num_inputs(num_inputs), domain(domain), t(t), At(std::move(At)),
211  Ct(std::move(Ct)), Ht(std::move(Ht)), Zt(Zt) {
212  }
213 
218 
219  bool is_satisfied(const sap_witness<FieldType> &witness) const {
220  if (this->num_variables != witness.num_variables) {
221  return false;
222  }
223 
224  if (this->degree != witness.degree) {
225  return false;
226  }
227 
228  if (this->num_inputs != witness.num_inputs) {
229  return false;
230  }
231 
232  if (this->num_variables != witness.coefficients_for_ACs.size()) {
233  return false;
234  }
235 
236  if (this->degree + 1 != witness.coefficients_for_H.size()) {
237  return false;
238  }
239 
240  if (this->At.size() != this->num_variables + 1 || this->Ct.size() != this->num_variables + 1) {
241  return false;
242  }
243 
244  if (this->Ht.size() != this->degree + 1) {
245  return false;
246  }
247 
248  if (this->Zt != this->domain->compute_vanishing_polynomial(this->t)) {
249  return false;
250  }
251 
252  typename FieldType::value_type ans_A = this->At[0] + witness.d1 * this->Zt;
253  typename FieldType::value_type ans_C = this->Ct[0] + witness.d2 * this->Zt;
254  typename FieldType::value_type ans_H = FieldType::value_type::zero();
255 
256  ans_A = ans_A + algebra::inner_product(this->At.begin() + 1,
257  this->At.begin() + 1 + this->num_variables,
258  witness.coefficients_for_ACs.begin(),
259  witness.coefficients_for_ACs.begin() +
260  this->num_variables);
261  ans_C = ans_C + algebra::inner_product(this->Ct.begin() + 1,
262  this->Ct.begin() + 1 + this->num_variables,
263  witness.coefficients_for_ACs.begin(),
264  witness.coefficients_for_ACs.begin() +
265  this->num_variables);
266  ans_H = ans_H + algebra::inner_product(this->Ht.begin(),
267  this->Ht.begin() + this->degree + 1,
268  witness.coefficients_for_H.begin(),
269  witness.coefficients_for_H.begin() +
270  this->degree + 1);
271 
272  if (ans_A * ans_A - ans_C != ans_H * this->Zt) {
273  return false;
274  }
275 
276  return true;
277  }
278  };
279 
280  /************************* WITNESS ***********************************/
281 
285  template<typename FieldType>
286  struct sap_witness {
287  std::size_t num_variables;
288  std::size_t degree;
289  std::size_t num_inputs;
290 
291  typename FieldType::value_type d1, d2;
292 
293  std::vector<typename FieldType::value_type> coefficients_for_ACs;
294  std::vector<typename FieldType::value_type> coefficients_for_H;
295 
296  sap_witness(const std::size_t num_variables,
297  const std::size_t degree,
298  const std::size_t num_inputs,
299  const typename FieldType::value_type &d1,
300  const typename FieldType::value_type &d2,
301  const std::vector<typename FieldType::value_type> &coefficients_for_ACs,
302  const std::vector<typename FieldType::value_type> &coefficients_for_H) :
303  num_variables(num_variables),
304  degree(degree), num_inputs(num_inputs), d1(d1), d2(d2),
305  coefficients_for_ACs(coefficients_for_ACs), coefficients_for_H(coefficients_for_H) {
306  }
307 
308  sap_witness(const std::size_t num_variables,
309  const std::size_t degree,
310  const std::size_t num_inputs,
311  const typename FieldType::value_type &d1,
312  const typename FieldType::value_type &d2,
313  const std::vector<typename FieldType::value_type> &coefficients_for_ACs,
314  std::vector<typename FieldType::value_type> &&coefficients_for_H) :
315  num_variables(num_variables),
316  degree(degree), num_inputs(num_inputs), d1(d1), d2(d2),
317  coefficients_for_ACs(coefficients_for_ACs), coefficients_for_H(std::move(coefficients_for_H)) {
318  }
319 
320  sap_witness(const sap_witness<FieldType> &other) = default;
322  sap_witness &operator=(const sap_witness<FieldType> &other) = default;
324  };
325  } // namespace snark
326  } // namespace zk
327  } // namespace crypto3
328 } // namespace nil
329 
330 #endif // CRYPTO3_SAP_HPP
Definition: evaluation_domain.hpp:41
vector(T, U...) -> vector< std::enable_if_t<(std::is_same_v< T, U > &&...), T >, 1+sizeof...(U)>
deduction guide for uniform initialization
std::iterator_traits< InputBaseIterator >::value_type inner_product(InputBaseIterator a_begin, InputBaseIterator a_end, InputBaseIterator b_begin, InputBaseIterator b_end)
Definition: algebra/include/nil/crypto3/algebra/multiexp/inner_product.hpp:40
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
Definition: make_evaluation_domain.hpp:40
Definition: pair.hpp:31
sap_instance_evaluation & operator=(sap_instance_evaluation< FieldType > &&other)=default
FieldType::value_type t
Definition: sap.hpp:181
bool is_satisfied(const sap_witness< FieldType > &witness) const
Definition: sap.hpp:219
std::vector< typename FieldType::value_type > At
Definition: sap.hpp:183
sap_instance_evaluation(const std::shared_ptr< evaluation_domain< FieldType >> &domain, const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, const typename FieldType::value_type &t, const std::vector< typename FieldType::value_type > &At, const std::vector< typename FieldType::value_type > &Ct, const std::vector< typename FieldType::value_type > &Ht, const typename FieldType::value_type &Zt)
Definition: sap.hpp:187
sap_instance_evaluation(sap_instance_evaluation< FieldType > &&other)=default
std::size_t num_inputs
Definition: sap.hpp:177
std::shared_ptr< evaluation_domain< FieldType > > domain
Definition: sap.hpp:179
FieldType::value_type Zt
Definition: sap.hpp:185
std::size_t degree
Definition: sap.hpp:176
std::size_t num_variables
Definition: sap.hpp:175
sap_instance_evaluation(const sap_instance_evaluation< FieldType > &other)=default
sap_instance_evaluation(const std::shared_ptr< evaluation_domain< FieldType >> &domain, const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, const typename FieldType::value_type &t, std::vector< typename FieldType::value_type > &&At, std::vector< typename FieldType::value_type > &&Ct, std::vector< typename FieldType::value_type > &&Ht, const typename FieldType::value_type &Zt)
Definition: sap.hpp:200
sap_instance_evaluation & operator=(const sap_instance_evaluation< FieldType > &other)=default
sap_instance(sap_instance< FieldType > &&other)=default
sap_instance(const std::shared_ptr< evaluation_domain< FieldType >> &domain, const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, std::vector< std::map< std::size_t, typename FieldType::value_type >> &&A_in_Lagrange_basis, std::vector< std::map< std::size_t, typename FieldType::value_type >> &&C_in_Lagrange_basis)
Definition: sap.hpp:99
sap_instance(const std::shared_ptr< evaluation_domain< FieldType >> &domain, const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, const std::vector< std::map< std::size_t, typename FieldType::value_type >> &A_in_Lagrange_basis, const std::vector< std::map< std::size_t, typename FieldType::value_type >> &C_in_Lagrange_basis)
Definition: sap.hpp:87
std::size_t degree
Definition: sap.hpp:79
bool is_satisfied(const sap_witness< FieldType > &witness) const
Definition: sap.hpp:117
std::vector< std::map< std::size_t, typename FieldType::value_type > > C_in_Lagrange_basis
Definition: sap.hpp:85
sap_instance(const sap_instance< FieldType > &other)=default
std::size_t num_inputs
Definition: sap.hpp:80
std::shared_ptr< evaluation_domain< FieldType > > domain
Definition: sap.hpp:82
sap_instance & operator=(sap_instance< FieldType > &&other)=default
sap_instance & operator=(const sap_instance< FieldType > &other)=default
std::size_t num_variables
Definition: sap.hpp:78
std::vector< std::map< std::size_t, typename FieldType::value_type > > A_in_Lagrange_basis
Definition: sap.hpp:84
sap_witness(sap_witness< FieldType > &&other)=default
FieldType::value_type d2
Definition: sap.hpp:291
std::vector< typename FieldType::value_type > coefficients_for_ACs
Definition: sap.hpp:293
sap_witness & operator=(const sap_witness< FieldType > &other)=default
sap_witness(const sap_witness< FieldType > &other)=default
std::size_t num_inputs
Definition: sap.hpp:289
sap_witness & operator=(sap_witness< FieldType > &&other)=default
sap_witness(const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, const typename FieldType::value_type &d1, const typename FieldType::value_type &d2, const std::vector< typename FieldType::value_type > &coefficients_for_ACs, const std::vector< typename FieldType::value_type > &coefficients_for_H)
Definition: sap.hpp:296
sap_witness(const std::size_t num_variables, const std::size_t degree, const std::size_t num_inputs, const typename FieldType::value_type &d1, const typename FieldType::value_type &d2, const std::vector< typename FieldType::value_type > &coefficients_for_ACs, std::vector< typename FieldType::value_type > &&coefficients_for_H)
Definition: sap.hpp:308
FieldType::value_type d1
Definition: sap.hpp:291
std::size_t degree
Definition: sap.hpp:288
std::vector< typename FieldType::value_type > coefficients_for_H
Definition: sap.hpp:294
std::size_t num_variables
Definition: sap.hpp:287