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