2 *****************************************************************************
4 Implementation of interfaces for a SSP ("Square Span 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 ssp_instance<FieldT>::ssp_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>> &V_in_Lagrange_basis)
32 : num_variables_(num_variables)
34 , num_inputs_(num_inputs)
36 , V_in_Lagrange_basis(V_in_Lagrange_basis)
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,
45 const size_t num_inputs,
46 std::vector<std::map<size_t, FieldT>> &&V_in_Lagrange_basis)
47 : num_variables_(num_variables)
49 , num_inputs_(num_inputs)
51 , V_in_Lagrange_basis(std::move(V_in_Lagrange_basis))
55 template<typename FieldT> size_t ssp_instance<FieldT>::num_variables() const
57 return num_variables_;
60 template<typename FieldT> size_t ssp_instance<FieldT>::degree() const
65 template<typename FieldT> size_t ssp_instance<FieldT>::num_inputs() const
70 template<typename FieldT>
71 bool ssp_instance<FieldT>::is_satisfied(
72 const ssp_witness<FieldT> &witness) const
74 const FieldT t = FieldT::random_element();
76 std::vector<FieldT> Vt(this->num_variables() + 1, FieldT::zero());
77 std::vector<FieldT> Ht(this->degree() + 1);
79 const FieldT Zt = this->domain->compute_vanishing_polynomial(t);
81 const std::vector<FieldT> u =
82 this->domain->evaluate_all_lagrange_polynomials(t);
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;
90 FieldT ti = FieldT::one();
91 for (size_t i = 0; i < this->degree() + 1; ++i) {
96 const ssp_instance_evaluation<FieldT> eval_ssp_inst(
98 this->num_variables(),
105 return eval_ssp_inst.is_satisfied(witness);
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,
113 const size_t num_inputs,
115 const std::vector<FieldT> &Vt,
116 const std::vector<FieldT> &Ht,
118 : num_variables_(num_variables)
120 , num_inputs_(num_inputs)
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,
134 const size_t num_inputs,
136 std::vector<FieldT> &&Vt,
137 std::vector<FieldT> &&Ht,
139 : num_variables_(num_variables)
141 , num_inputs_(num_inputs)
150 template<typename FieldT>
151 size_t ssp_instance_evaluation<FieldT>::num_variables() const
153 return num_variables_;
156 template<typename FieldT> size_t ssp_instance_evaluation<FieldT>::degree() const
161 template<typename FieldT>
162 size_t ssp_instance_evaluation<FieldT>::num_inputs() const
167 template<typename FieldT>
168 bool ssp_instance_evaluation<FieldT>::is_satisfied(
169 const ssp_witness<FieldT> &witness) const
172 if (this->num_variables() != witness.num_variables()) {
176 if (this->degree() != witness.degree()) {
180 if (this->num_inputs() != witness.num_inputs()) {
184 if (this->num_variables() != witness.coefficients_for_Vs.size()) {
188 if (this->degree() + 1 != witness.coefficients_for_H.size()) {
192 if (this->Vt.size() != this->num_variables() + 1) {
196 if (this->Ht.size() != this->degree() + 1) {
200 if (this->Zt != this->domain->compute_vanishing_polynomial(this->t)) {
204 FieldT ans_V = this->Vt[0] + witness.d * this->Zt;
205 FieldT ans_H = FieldT::zero();
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());
214 ans_H + libff::inner_product<FieldT>(
216 this->Ht.begin() + this->degree() + 1,
217 witness.coefficients_for_H.begin(),
218 witness.coefficients_for_H.begin() + this->degree() + 1);
220 if (ans_V.squared() - FieldT::one() != ans_H * this->Zt) {
227 template<typename FieldT>
228 ssp_witness<FieldT>::ssp_witness(
229 const size_t num_variables,
231 const size_t num_inputs,
233 const std::vector<FieldT> &coefficients_for_Vs,
234 const std::vector<FieldT> &coefficients_for_H)
235 : num_variables_(num_variables)
237 , num_inputs_(num_inputs)
239 , coefficients_for_Vs(coefficients_for_Vs)
240 , coefficients_for_H(coefficients_for_H)
244 template<typename FieldT>
245 ssp_witness<FieldT>::ssp_witness(
246 const size_t num_variables,
248 const size_t num_inputs,
250 const std::vector<FieldT> &coefficients_for_Vs,
251 std::vector<FieldT> &&coefficients_for_H)
252 : num_variables_(num_variables)
254 , num_inputs_(num_inputs)
256 , coefficients_for_Vs(coefficients_for_Vs)
257 , coefficients_for_H(std::move(coefficients_for_H))
261 template<typename FieldT> size_t ssp_witness<FieldT>::num_variables() const
263 return num_variables_;
266 template<typename FieldT> size_t ssp_witness<FieldT>::degree() const
271 template<typename FieldT> size_t ssp_witness<FieldT>::num_inputs() const
276 } // namespace libsnark