49 #ifndef CRYPTO3_ZK_R1CS_TO_SAP_BASIC_POLICY_HPP
50 #define CRYPTO3_ZK_R1CS_TO_SAP_BASIC_POLICY_HPP
53 #include <nil/crypto3/math/evaluation_domain.hpp>
62 namespace reductions {
63 template<
typename FieldType>
65 typedef FieldType field_type;
70 static typename FieldType::value_type times_four(
typename FieldType::value_type x) {
71 typename FieldType::value_type times_two = x + x;
72 return times_two + times_two;
80 static std::shared_ptr<math::evaluation_domain<FieldType>>
90 return math::make_evaluation_domain<FieldType>(2 * cs.
num_constraints() +
98 const std::shared_ptr<math::evaluation_domain<FieldType>> domain =
get_domain(cs);
102 std::vector<std::map<std::size_t, typename FieldType::value_type>> A_in_Lagrange_basis(sap_num_variables + 1);
103 std::vector<std::map<std::size_t, typename FieldType::value_type>> C_in_Lagrange_basis(sap_num_variables + 1);
121 for (std::size_t j = 0; j < cs.
constraints[i].a.terms.size(); ++j) {
122 A_in_Lagrange_basis[cs.
constraints[i].a.terms[j].index][2 * i] +=
124 A_in_Lagrange_basis[cs.
constraints[i].a.terms[j].index][2 * i + 1] +=
128 for (std::size_t j = 0; j < cs.
constraints[i].b.terms.size(); ++j) {
129 A_in_Lagrange_basis[cs.
constraints[i].b.terms[j].index][2 * i] +=
131 A_in_Lagrange_basis[cs.
constraints[i].b.terms[j].index][2 * i + 1] -=
135 for (std::size_t j = 0; j < cs.
constraints[i].c.terms.size(); ++j) {
136 C_in_Lagrange_basis[cs.
constraints[i].c.terms[j].index][2 * i] +=
140 C_in_Lagrange_basis[extra_var_offset + i][2 * i] += FieldType::value_type::one();
141 C_in_Lagrange_basis[extra_var_offset + i][2 * i + 1] += FieldType::value_type::one();
172 A_in_Lagrange_basis[0][extra_constr_offset] = FieldType::value_type::one();
173 C_in_Lagrange_basis[0][extra_constr_offset] = FieldType::value_type::one();
175 for (std::size_t i = 1; i <= cs.
num_inputs(); ++i) {
176 A_in_Lagrange_basis[i][extra_constr_offset + 2 * i - 1] +=
177 FieldType::value_type::one();
178 A_in_Lagrange_basis[0][extra_constr_offset + 2 * i - 1] +=
179 FieldType::value_type::one();
180 C_in_Lagrange_basis[i][extra_constr_offset + 2 * i - 1] +=
181 times_four(FieldType::value_type::one());
182 C_in_Lagrange_basis[extra_var_offset2 + i][extra_constr_offset + 2 * i - 1] +=
183 FieldType::value_type::one();
185 A_in_Lagrange_basis[i][extra_constr_offset + 2 * i] += FieldType::value_type::one();
186 A_in_Lagrange_basis[0][extra_constr_offset + 2 * i] -= FieldType::value_type::one();
187 C_in_Lagrange_basis[extra_var_offset2 + i][2 * cs.
num_constraints() + 2 * i] +=
188 FieldType::value_type::one();
205 const typename FieldType::value_type &t) {
207 const std::shared_ptr<math::evaluation_domain<FieldType>> domain =
get_domain(cs);
211 std::vector<typename FieldType::value_type> At, Ct, Ht;
213 At.resize(sap_num_variables + 1, FieldType::value_type::zero());
214 Ct.resize(sap_num_variables + 1, FieldType::value_type::zero());
215 Ht.reserve(domain->m + 1);
217 const typename FieldType::value_type Zt = domain->compute_vanishing_polynomial(t);
219 const std::vector<typename FieldType::value_type> u =
220 domain->evaluate_all_lagrange_polynomials(t);
226 for (std::size_t j = 0; j < cs.
constraints[i].a.terms.size(); ++j) {
233 for (std::size_t j = 0; j < cs.
constraints[i].b.terms.size(); ++j) {
240 for (std::size_t j = 0; j < cs.
constraints[i].c.terms.size(); ++j) {
242 times_four(u[2 * i] * cs.
constraints[i].c.terms[j].coeff);
245 Ct[extra_var_offset + i] += u[2 * i];
246 Ct[extra_var_offset + i] += u[2 * i + 1];
252 At[0] += u[extra_constr_offset];
253 Ct[0] += u[extra_constr_offset];
255 for (std::size_t i = 1; i <= cs.
num_inputs(); ++i) {
256 At[i] += u[extra_constr_offset + 2 * i - 1];
257 At[0] += u[extra_constr_offset + 2 * i - 1];
258 Ct[i] += times_four(u[extra_constr_offset + 2 * i - 1]);
259 Ct[extra_var_offset2 + i] += u[extra_constr_offset + 2 * i - 1];
261 At[i] += u[extra_constr_offset + 2 * i];
262 At[0] -= u[extra_constr_offset + 2 * i];
263 Ct[extra_var_offset2 + i] += u[extra_constr_offset + 2 * i];
266 typename FieldType::value_type ti = FieldType::value_type::one();
267 for (std::size_t i = 0; i < domain->m + 1; ++i) {
316 const typename FieldType::value_type &d1,
317 const typename FieldType::value_type &d2) {
319 assert(cs.
is_satisfied(primary_input, auxiliary_input));
321 const std::shared_ptr<math::evaluation_domain<FieldType>> domain =
get_domain(cs);
326 full_variable_assignment.insert(
327 full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end());
343 typename FieldType::value_type extra_var =
344 cs.
constraints[i].a.evaluate(full_variable_assignment) -
345 cs.
constraints[i].b.evaluate(full_variable_assignment);
346 extra_var = extra_var * extra_var;
347 full_variable_assignment.push_back(extra_var);
349 for (std::size_t i = 1; i <= cs.
num_inputs(); ++i) {
355 typename FieldType::value_type extra_var =
356 full_variable_assignment[i - 1] - FieldType::value_type::one();
357 extra_var = extra_var * extra_var;
358 full_variable_assignment.push_back(extra_var);
361 std::vector<typename FieldType::value_type> aA(domain->m, FieldType::value_type::zero());
365 aA[2 * i] += cs.
constraints[i].a.evaluate(full_variable_assignment);
366 aA[2 * i] += cs.
constraints[i].b.evaluate(full_variable_assignment);
368 aA[2 * i + 1] += cs.
constraints[i].a.evaluate(full_variable_assignment);
369 aA[2 * i + 1] -= cs.
constraints[i].b.evaluate(full_variable_assignment);
374 aA[extra_constr_offset] += FieldType::value_type::one();
376 for (std::size_t i = 1; i <= cs.
num_inputs(); ++i) {
377 aA[extra_constr_offset + 2 * i - 1] += full_variable_assignment[i - 1];
378 aA[extra_constr_offset + 2 * i - 1] += FieldType::value_type::one();
380 aA[extra_constr_offset + 2 * i] += full_variable_assignment[i - 1];
381 aA[extra_constr_offset + 2 * i] -= FieldType::value_type::one();
384 domain->inverse_fft(aA);
386 std::vector<typename FieldType::value_type> coefficients_for_H(
387 domain->m + 1, FieldType::value_type::zero());
389 #pragma omp parallel for
392 for (std::size_t i = 0; i < domain->m; ++i) {
393 coefficients_for_H[i] = (d1 * aA[i]) + (d1 * aA[i]);
395 coefficients_for_H[0] -= d2;
396 domain->add_poly_z(d1 * d1, coefficients_for_H);
399 typename FieldType::value_type(
403 std::vector<typename FieldType::value_type> &H_tmp =
406 #pragma omp parallel for
408 for (std::size_t i = 0; i < domain->m; ++i) {
409 H_tmp[i] = aA[i] * aA[i];
412 std::vector<typename FieldType::value_type> aC(domain->m, FieldType::value_type::zero());
416 aC[2 * i] += times_four(cs.
constraints[i].c.evaluate(full_variable_assignment));
418 aC[2 * i] += full_variable_assignment[extra_var_offset + i - 1];
419 aC[2 * i + 1] += full_variable_assignment[extra_var_offset + i - 1];
423 aC[extra_constr_offset] += FieldType::value_type::one();
425 for (std::size_t i = 1; i <= cs.
num_inputs(); ++i) {
426 aC[extra_constr_offset + 2 * i - 1] += times_four(full_variable_assignment[i - 1]);
428 aC[extra_constr_offset + 2 * i - 1] +=
429 full_variable_assignment[extra_var_offset2 + i - 1];
430 aC[extra_constr_offset + 2 * i] += full_variable_assignment[extra_var_offset2 + i - 1];
433 domain->inverse_fft(aC);
436 typename FieldType::value_type(
441 #pragma omp parallel for
443 for (std::size_t i = 0; i < domain->m; ++i) {
444 H_tmp[i] = (H_tmp[i] - aC[i]);
447 domain->divide_by_z_on_coset(H_tmp);
449 domain->inverse_fft(H_tmp);
451 typename FieldType::value_type(
456 #pragma omp parallel for
458 for (std::size_t i = 0; i < domain->m; ++i) {
459 coefficients_for_H[i] += H_tmp[i];
467 full_variable_assignment,
Definition: r1cs_to_sap.hpp:64
static sap_instance< FieldType > instance_map(const r1cs_constraint_system< FieldType > &cs)
Definition: r1cs_to_sap.hpp:97
static sap_witness< FieldType > witness_map(const r1cs_constraint_system< FieldType > &cs, const r1cs_primary_input< FieldType > &primary_input, const r1cs_auxiliary_input< FieldType > &auxiliary_input, const typename FieldType::value_type &d1, const typename FieldType::value_type &d2)
Definition: r1cs_to_sap.hpp:313
static sap_instance_evaluation< FieldType > instance_map_with_evaluation(const r1cs_constraint_system< FieldType > &cs, const typename FieldType::value_type &t)
Definition: r1cs_to_sap.hpp:204
static std::shared_ptr< math::evaluation_domain< FieldType > > get_domain(const r1cs_constraint_system< FieldType > &cs)
Definition: r1cs_to_sap.hpp:81
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
void multiply_by_coset(Range &a, const FieldValueType &g)
Definition: coset.hpp:37
std::vector< typename FieldType::value_type > r1cs_auxiliary_input
Definition: r1cs.hpp:104
std::vector< typename FieldType::value_type > r1cs_primary_input
Definition: r1cs.hpp:101
std::vector< typename FieldType::value_type > r1cs_variable_assignment
Definition: r1cs.hpp:107
Definition: fields/params.hpp:58
bool is_satisfied(const r1cs_primary_input< FieldType > &primary_input, const r1cs_auxiliary_input< FieldType > &auxiliary_input) const
Definition: r1cs.hpp:162
std::vector< r1cs_constraint< FieldType > > constraints
Definition: r1cs.hpp:130
std::size_t num_constraints() const
Definition: r1cs.hpp:143
std::size_t num_inputs() const
Definition: r1cs.hpp:135
std::size_t num_variables() const
Definition: r1cs.hpp:139