2 *****************************************************************************
4 Implementation of interfaces for a SAP ("Square Arithmetic Program").
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 *****************************************************************************/
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>
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,
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)
35 , num_inputs_(num_inputs)
37 , A_in_Lagrange_basis(A_in_Lagrange_basis)
38 , C_in_Lagrange_basis(C_in_Lagrange_basis)
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,
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)
52 , num_inputs_(num_inputs)
54 , A_in_Lagrange_basis(std::move(A_in_Lagrange_basis))
55 , C_in_Lagrange_basis(std::move(C_in_Lagrange_basis))
59 template<typename FieldT> size_t sap_instance<FieldT>::num_variables() const
61 return num_variables_;
64 template<typename FieldT> size_t sap_instance<FieldT>::degree() const
69 template<typename FieldT> size_t sap_instance<FieldT>::num_inputs() const
74 template<typename FieldT>
75 bool sap_instance<FieldT>::is_satisfied(
76 const sap_witness<FieldT> &witness) const
78 const FieldT t = FieldT::random_element();
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);
84 const FieldT Zt = this->domain->compute_vanishing_polynomial(t);
86 const std::vector<FieldT> u =
87 this->domain->evaluate_all_lagrange_polynomials(t);
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;
94 for (auto &el : C_in_Lagrange_basis[i]) {
95 Ct[i] += u[el.first] * el.second;
99 FieldT ti = FieldT::one();
100 for (size_t i = 0; i < this->degree() + 1; ++i) {
105 const sap_instance_evaluation<FieldT> eval_sap_inst(
107 this->num_variables(),
115 return eval_sap_inst.is_satisfied(witness);
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,
123 const size_t num_inputs,
125 const std::vector<FieldT> &At,
126 const std::vector<FieldT> &Ct,
127 const std::vector<FieldT> &Ht,
129 : num_variables_(num_variables)
131 , num_inputs_(num_inputs)
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,
146 const size_t num_inputs,
148 std::vector<FieldT> &&At,
149 std::vector<FieldT> &&Ct,
150 std::vector<FieldT> &&Ht,
152 : num_variables_(num_variables)
154 , num_inputs_(num_inputs)
164 template<typename FieldT>
165 size_t sap_instance_evaluation<FieldT>::num_variables() const
167 return num_variables_;
170 template<typename FieldT> size_t sap_instance_evaluation<FieldT>::degree() const
175 template<typename FieldT>
176 size_t sap_instance_evaluation<FieldT>::num_inputs() const
181 template<typename FieldT>
182 bool sap_instance_evaluation<FieldT>::is_satisfied(
183 const sap_witness<FieldT> &witness) const
185 if (this->num_variables() != witness.num_variables()) {
189 if (this->degree() != witness.degree()) {
193 if (this->num_inputs() != witness.num_inputs()) {
197 if (this->num_variables() != witness.coefficients_for_ACs.size()) {
201 if (this->degree() + 1 != witness.coefficients_for_H.size()) {
205 if (this->At.size() != this->num_variables() + 1 ||
206 this->Ct.size() != this->num_variables() + 1) {
210 if (this->Ht.size() != this->degree() + 1) {
214 if (this->Zt != this->domain->compute_vanishing_polynomial(this->t)) {
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();
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());
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());
235 ans_H + libff::inner_product<FieldT>(
237 this->Ht.begin() + this->degree() + 1,
238 witness.coefficients_for_H.begin(),
239 witness.coefficients_for_H.begin() + this->degree() + 1);
241 if (ans_A * ans_A - ans_C != ans_H * this->Zt) {
248 template<typename FieldT>
249 sap_witness<FieldT>::sap_witness(
250 const size_t num_variables,
252 const size_t num_inputs,
255 const std::vector<FieldT> &coefficients_for_ACs,
256 const std::vector<FieldT> &coefficients_for_H)
257 : num_variables_(num_variables)
259 , num_inputs_(num_inputs)
262 , coefficients_for_ACs(coefficients_for_ACs)
263 , coefficients_for_H(coefficients_for_H)
267 template<typename FieldT>
268 sap_witness<FieldT>::sap_witness(
269 const size_t num_variables,
271 const size_t num_inputs,
274 const std::vector<FieldT> &coefficients_for_ACs,
275 std::vector<FieldT> &&coefficients_for_H)
276 : num_variables_(num_variables)
278 , num_inputs_(num_inputs)
281 , coefficients_for_ACs(coefficients_for_ACs)
282 , coefficients_for_H(std::move(coefficients_for_H))
286 template<typename FieldT> size_t sap_witness<FieldT>::num_variables() const
288 return num_variables_;
291 template<typename FieldT> size_t sap_witness<FieldT>::degree() const
296 template<typename FieldT> size_t sap_witness<FieldT>::num_inputs() const
301 } // namespace libsnark