uscs_to_ssp.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 USCS-to-SSP reduction, that is, constructing
26 // a SSP ("Square Span Program") from a USCS ("boolean circuit with 2-input gates").
27 //
28 // SSPs are defined in \[DFGK14], and constructed for USCS also in \[DFGK14].
29 //
30 // The implementation of the reduction adapts to \[DFGK14], extends, and optimizes
31 // the efficient QAP-based approach described in Appendix E of \[BCGTV13].
32 //
33 // References:
34 //
35 // \[BCGTV13]
36 // "SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge",
37 // Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, Madars Virza,
38 // CRYPTO 2013,
39 // <http://eprint.iacr.org/2013/507>
40 //
41 // \[DFGK14]:
42 // "Square Span Programs with Applications to Succinct NIZK Arguments"
43 // George Danezis, Cedric Fournet, Jens Groth, Markulf Kohlweiss,
44 // ASIACRYPT 2014,
45 // <http://eprint.iacr.org/2014/718>
46 //---------------------------------------------------------------------------//
47 
48 #ifndef CRYPTO3_ZK_USCS_TO_SSP_REDUCTION_HPP
49 #define CRYPTO3_ZK_USCS_TO_SSP_REDUCTION_HPP
50 
52 #include <nil/crypto3/math/evaluation_domain.hpp>
53 
56 
57 namespace nil {
58  namespace crypto3 {
59  namespace zk {
60  namespace snark {
61  namespace reductions {
62  template<typename FieldType>
63  struct uscs_to_ssp {
64  typedef FieldType field_type;
65 
77  const std::shared_ptr<evaluation_domain<FieldType>> domain =
78  math::make_evaluation_domain<FieldType>(cs.num_constraints());
79  std::vector<std::map<std::size_t, typename FieldType::value_type>> V_in_Lagrange_basis(
80  cs.num_variables() + 1);
81  for (std::size_t i = 0; i < cs.num_constraints(); ++i) {
82  for (std::size_t j = 0; j < cs.constraints[i].terms.size(); ++j) {
83  V_in_Lagrange_basis[cs.constraints[i].terms[j].index][i] +=
84  cs.constraints[i].terms[j].coeff;
85  }
86  }
87  for (std::size_t i = cs.num_constraints(); i < domain->m; ++i) {
88  V_in_Lagrange_basis[0][i] += FieldType::value_type::one();
89  }
90 
92  domain, cs.num_variables(), domain->m, cs.num_inputs(), std::move(V_in_Lagrange_basis));
93  }
94 
110  const typename FieldType::value_type &t) {
111  const std::shared_ptr<evaluation_domain<FieldType>> domain =
112  math::make_evaluation_domain<FieldType>(cs.num_constraints());
113 
114  std::vector<typename FieldType::value_type> Vt(cs.num_variables() + 1,
115  FieldType::value_type::zero());
116  std::vector<typename FieldType::value_type> Ht(domain->m + 1);
117 
118  const typename FieldType::value_type Zt = domain->compute_vanishing_polynomial(t);
119 
120  const std::vector<typename FieldType::value_type> u =
121  domain->evaluate_all_lagrange_polynomials(t);
122  for (std::size_t i = 0; i < cs.num_constraints(); ++i) {
123  for (std::size_t j = 0; j < cs.constraints[i].terms.size(); ++j) {
124  Vt[cs.constraints[i].terms[j].index] += u[i] * cs.constraints[i].terms[j].coeff;
125  }
126  }
127  for (std::size_t i = cs.num_constraints(); i < domain->m; ++i) {
128  Vt[0] += u[i]; /* dummy constraint: 1^2 = 1 */
129  }
130  typename FieldType::value_type ti = FieldType::value_type::one();
131  for (std::size_t i = 0; i < domain->m + 1; ++i) {
132  Ht[i] = ti;
133  ti *= t;
134  }
135 
137  cs.num_variables(),
138  domain->m,
139  cs.num_inputs(),
140  t,
141  std::move(Vt),
142  std::move(Ht),
143  Zt);
144  }
145 
175  const uscs_primary_input<FieldType> &primary_input,
176  const uscs_auxiliary_input<FieldType> &auxiliary_input,
177  const typename FieldType::value_type &d) {
178  /* sanity check */
179 
180  assert(cs.is_satisfied(primary_input, auxiliary_input));
181 
182  uscs_variable_assignment<FieldType> full_variable_assignment = primary_input;
183  full_variable_assignment.insert(
184  full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end());
185 
186  const std::shared_ptr<evaluation_domain<FieldType>> domain =
187  make_evaluation_domain<FieldType>(cs.num_constraints());
188 
189  std::vector<typename FieldType::value_type> aA(domain->m, FieldType::value_type::zero());
190  assert(domain->m >= cs.num_constraints());
191  for (std::size_t i = 0; i < cs.num_constraints(); ++i) {
192  aA[i] += cs.constraints[i].evaluate(full_variable_assignment);
193  }
194  for (std::size_t i = cs.num_constraints(); i < domain->m; ++i) {
195  aA[i] += FieldType::value_type::one();
196  }
197 
198  domain->inverse_fft(aA);
199 
200  std::vector<typename FieldType::value_type> coefficients_for_H(
201  domain->m + 1, FieldType::value_type::zero());
202 #ifdef MULTICORE
203 #pragma omp parallel for
204 #endif
205  /* add coefficients of the polynomial 2*d*V(z) + d*d*Z(z) */
206  for (std::size_t i = 0; i < domain->m; ++i) {
207  coefficients_for_H[i] = typename FieldType::value_type(2) * d * aA[i];
208  }
209  domain->add_poly_z(d.squared(), coefficients_for_H);
210 
212  aA,
213  typename FieldType::value_type(
215  domain->fft(aA);
216 
217  std::vector<typename FieldType::value_type> &H_tmp =
218  aA; // can overwrite aA because it is not used later
219 #ifdef MULTICORE
220 #pragma omp parallel for
221 #endif
222  for (std::size_t i = 0; i < domain->m; ++i) {
223  H_tmp[i] = aA[i].squared() - FieldType::value_type::one();
224  }
225 
226  domain->divide_by_z_on_coset(H_tmp);
227 
228  domain->inverse_fft(H_tmp);
229  multiply_by_coset(H_tmp,
230  typename FieldType::value_type(
232  .inversed());
233 
234 #ifdef MULTICORE
235 #pragma omp parallel for
236 #endif
237  for (std::size_t i = 0; i < domain->m; ++i) {
238  coefficients_for_H[i] += H_tmp[i];
239  }
240 
242  domain->m,
243  cs.num_inputs(),
244  d,
245  full_variable_assignment,
246  std::move(coefficients_for_H));
247  }
248  };
249  } // namespace reductions
250  } // namespace snark
251  } // namespace zk
252  } // namespace crypto3
253 } // namespace nil
254 
255 #endif // CRYPTO3_ZK_USCS_TO_SSP_BASIC_POLICY_HPP
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 > uscs_auxiliary_input
Definition: uscs.hpp:70
std::vector< typename FieldType::value_type > uscs_variable_assignment
Definition: uscs.hpp:73
std::vector< typename FieldType::value_type > uscs_primary_input
Definition: uscs.hpp:67
Definition: pair.hpp:31
Definition: fields/params.hpp:58
static ssp_instance< FieldType > instance_map(const uscs_constraint_system< FieldType > &cs)
Definition: uscs_to_ssp.hpp:76
static ssp_instance_evaluation< FieldType > instance_map_with_evaluation(const uscs_constraint_system< FieldType > &cs, const typename FieldType::value_type &t)
Definition: uscs_to_ssp.hpp:109
FieldType field_type
Definition: uscs_to_ssp.hpp:64
static ssp_witness< FieldType > witness_map(const uscs_constraint_system< FieldType > &cs, const uscs_primary_input< FieldType > &primary_input, const uscs_auxiliary_input< FieldType > &auxiliary_input, const typename FieldType::value_type &d)
Definition: uscs_to_ssp.hpp:174
bool is_satisfied(const uscs_primary_input< FieldType > &primary_input, const uscs_auxiliary_input< FieldType > &auxiliary_input) const
Definition: uscs.hpp:124
std::size_t num_constraints() const
Definition: uscs.hpp:107
std::size_t num_variables() const
Definition: uscs.hpp:103
std::size_t num_inputs() const
Definition: uscs.hpp:99
std::vector< uscs_constraint< FieldType > > constraints
Definition: uscs.hpp:95