r1cs_gg_ppzksnark/generator.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 // Copyright (c) 2020-2021 Ilias Khairullin <ilias@nil.foundation>
5 //
6 // MIT License
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //---------------------------------------------------------------------------//
26 
27 #ifndef CRYPTO3_ZK_R1CS_GG_PPZKSNARK_BASIC_GENERATOR_HPP
28 #define CRYPTO3_ZK_R1CS_GG_PPZKSNARK_BASIC_GENERATOR_HPP
29 
30 #ifdef MULTICORE
31 #include <omp.h>
32 #endif
33 
37 
43 
44 namespace nil {
45  namespace crypto3 {
46  namespace zk {
47  namespace snark {
48  template<typename CurveType, ProvingMode Mode = ProvingMode::Basic, typename = void>
50 
57  template<typename CurveType>
59 
61 
62  typedef typename CurveType::scalar_field_type scalar_field_type;
63  typedef typename CurveType::template g1_type<> g1_type;
64  typedef typename CurveType::template g2_type<> g2_type;
65  typedef typename CurveType::gt_type gt_type;
66 
67  public:
71 
76 
81 
82  template<typename DistributionType =
83  boost::random::uniform_int_distribution<typename scalar_field_type::integral_type>,
84  typename GeneratorType = boost::random::mt19937>
85  static inline auto basic_process(const constraint_system_type &constraint_system) {
86 
87  /* Make the B_query "lighter" if possible */
88  constraint_system_type r1cs_copy(constraint_system);
89  r1cs_copy.swap_AB_if_beneficial();
90 
91  /* Generate secret randomness */
92  const typename scalar_field_type::value_type t =
93  algebra::random_element<scalar_field_type, DistributionType, GeneratorType>();
94  const typename scalar_field_type::value_type alpha =
95  algebra::random_element<scalar_field_type, DistributionType, GeneratorType>();
96  const typename scalar_field_type::value_type beta =
97  algebra::random_element<scalar_field_type, DistributionType, GeneratorType>();
98  const typename scalar_field_type::value_type gamma =
99  algebra::random_element<scalar_field_type, DistributionType, GeneratorType>();
100  const typename scalar_field_type::value_type delta =
101  algebra::random_element<scalar_field_type, DistributionType, GeneratorType>();
102  const typename scalar_field_type::value_type gamma_inverse = gamma.inversed();
103  const typename scalar_field_type::value_type delta_inverse = delta.inversed();
104 
105  /* A quadratic arithmetic program evaluated at t. */
108 
109  std::size_t non_zero_At = 0;
110  std::size_t non_zero_Bt = 0;
111  for (std::size_t i = 0; i < qap.num_variables + 1; ++i) {
112  if (!qap.At[i].is_zero()) {
113  ++non_zero_At;
114  }
115  if (!qap.Bt[i].is_zero()) {
116  ++non_zero_Bt;
117  }
118  }
119 
120  /* qap.{At,Bt,Ct,Ht} are now in unspecified state, but we do not use them later */
121  std::vector<typename scalar_field_type::value_type> At = std::move(qap.At);
122  std::vector<typename scalar_field_type::value_type> Bt = std::move(qap.Bt);
123  std::vector<typename scalar_field_type::value_type> Ct = std::move(qap.Ct);
124  std::vector<typename scalar_field_type::value_type> Ht = std::move(qap.Ht);
125 
126  /* The gamma inverse product component: (beta*A_i(t) + alpha*B_i(t) + C_i(t)) * gamma^{-1}.
127  */
128  std::vector<typename scalar_field_type::value_type> gamma_ABC;
129  gamma_ABC.reserve(qap.num_inputs);
130 
131  const typename scalar_field_type::value_type gamma_ABC_0 =
132  (beta * At[0] + alpha * Bt[0] + Ct[0]) * gamma_inverse;
133  for (std::size_t i = 1; i < qap.num_inputs + 1; ++i) {
134  gamma_ABC.emplace_back((beta * At[i] + alpha * Bt[i] + Ct[i]) * gamma_inverse);
135  }
136 
137  /* The delta inverse product component: (beta*A_i(t) + alpha*B_i(t) + C_i(t)) * delta^{-1}.
138  */
139  std::vector<typename scalar_field_type::value_type> Lt;
140  Lt.reserve(qap.num_variables - qap.num_inputs);
141 
142  const std::size_t Lt_offset = qap.num_inputs + 1;
143  for (std::size_t i = 0; i < qap.num_variables - qap.num_inputs; ++i) {
144  Lt.emplace_back((beta * At[Lt_offset + i] + alpha * Bt[Lt_offset + i] + Ct[Lt_offset + i]) *
145  delta_inverse);
146  }
147 
153  Ht.resize(Ht.size() - 2);
154 
155 #ifdef MULTICORE
156  const std::size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env
157  // var or call omp_set_num_threads()
158 #else
159  const std::size_t chunks = 1;
160 #endif
161 
162  const typename g1_type::value_type g1_generator = algebra::random_element<g1_type>();
163 
164  const std::size_t g1_scalar_count = non_zero_At + non_zero_Bt + qap.num_variables;
165  const std::size_t g1_scalar_size = scalar_field_type::value_bits;
166  const std::size_t g1_window_size = algebra::get_exp_window_size<g1_type>(g1_scalar_count);
167 
169  algebra::get_window_table<g1_type>(g1_scalar_size, g1_window_size, g1_generator);
170 
171  const typename g2_type::value_type G2_gen = algebra::random_element<g2_type>();
172 
173  const std::size_t g2_scalar_count = non_zero_Bt;
174  const std::size_t g2_scalar_size = scalar_field_type::value_bits;
175  std::size_t g2_window_size = algebra::get_exp_window_size<g2_type>(g2_scalar_count);
176 
178  algebra::get_window_table<g2_type>(g2_scalar_size, g2_window_size, G2_gen);
179 
180  typename g1_type::value_type alpha_g1 = alpha * g1_generator;
181  typename g1_type::value_type beta_g1 = beta * g1_generator;
182  typename g2_type::value_type beta_g2 = beta * G2_gen;
183  typename g1_type::value_type delta_g1 = delta * g1_generator;
184  typename g2_type::value_type delta_g2 = delta * G2_gen;
185 
186  typename std::vector<typename g1_type::value_type> A_query =
187  algebra::batch_exp<g1_type, scalar_field_type>(g1_scalar_size, g1_window_size, g1_table,
188  At);
189 #ifdef USE_MIXED_ADDITION
190  algebra::batch_to_special<g1_type>(A_query);
191 #endif
192 
194  kc_batch_exp<g2_type, g1_type, scalar_field_type>(
195  scalar_field_type::value_bits, g2_window_size, g1_window_size, g2_table, g1_table,
196  scalar_field_type::value_type::one(), scalar_field_type::value_type::one(), Bt, chunks);
197 
198  // NOTE: if USE_MIXED_ADDITION is defined,
199  // kc_batch_exp will convert its output to special form internally
200 
201  typename std::vector<typename g1_type::value_type> H_query =
202  algebra::batch_exp_with_coeff<g1_type, scalar_field_type>(
203  g1_scalar_size, g1_window_size, g1_table, qap.Zt * delta_inverse, Ht);
204 #ifdef USE_MIXED_ADDITION
205  algebra::batch_to_special<g1_type>(H_query);
206 #endif
207 
208  typename std::vector<typename g1_type::value_type> L_query =
209  algebra::batch_exp<g1_type, scalar_field_type>(g1_scalar_size, g1_window_size, g1_table,
210  Lt);
211 
212 #ifdef USE_MIXED_ADDITION
213  algebra::batch_to_special<g1_type>(L_query);
214 #endif
215 
216  typename gt_type::value_type alpha_g1_beta_g2 = pair_reduced<CurveType>(alpha_g1, beta_g2);
217  typename g2_type::value_type gamma_g2 = gamma * G2_gen;
218 
219  typename g1_type::value_type gamma_ABC_g1_0 = gamma_ABC_0 * g1_generator;
220 
221  typename std::vector<typename g1_type::value_type> gamma_ABC_g1_values =
222  algebra::batch_exp<g1_type, scalar_field_type>(g1_scalar_size, g1_window_size, g1_table,
223  gamma_ABC);
224 
225  typename g1_type::value_type gamma_g1 = gamma * g1_generator;
226 
227  accumulation_vector<g1_type> gamma_ABC_g1(std::move(gamma_ABC_g1_0),
228  std::move(gamma_ABC_g1_values));
229 
230  return std::make_tuple(std::move(alpha_g1), std::move(beta_g1), std::move(beta_g2),
231  std::move(delta_g1), std::move(delta_g2), std::move(gamma_g2),
232  std::move(A_query), std::move(B_query), std::move(H_query),
233  std::move(L_query), std::move(r1cs_copy), std::move(alpha_g1_beta_g2),
234  std::move(gamma_ABC_g1), std::move(gamma_g1));
235  }
236 
237  template<typename KeyPairType,
238  typename DistributionType =
239  boost::random::uniform_int_distribution<typename scalar_field_type::integral_type>,
240  typename GeneratorType = boost::random::mt19937>
241  static inline
242  typename std::enable_if<std::is_same<keypair_type, KeyPairType>::value, KeyPairType>::type
243  process(const constraint_system_type &constraint_system) {
244 
245  auto [alpha_g1, beta_g1, beta_g2, delta_g1, delta_g2, gamma_g2, A_query, B_query, H_query,
246  L_query, r1cs_copy, alpha_g1_beta_g2, gamma_ABC_g1, gamma_g1] =
247  basic_process<DistributionType, GeneratorType>(constraint_system);
248 
250  verification_key_type(alpha_g1_beta_g2, gamma_g2, delta_g2, gamma_ABC_g1);
251 
253  std::move(beta_g1),
254  std::move(beta_g2),
255  std::move(delta_g1),
256  std::move(delta_g2),
257  std::move(A_query),
258  std::move(B_query),
259  std::move(H_query),
260  std::move(L_query),
261  std::move(r1cs_copy));
262 
263  return {std::move(pk), std::move(vk)};
264  }
265 
266  template<typename KeyPairType,
267  typename DistributionType =
268  boost::random::uniform_int_distribution<typename scalar_field_type::integral_type>,
269  typename GeneratorType = boost::random::mt19937>
270  static inline typename std::enable_if<std::is_same<extended_keypair_type, KeyPairType>::value,
271  KeyPairType>::type
272  process(const constraint_system_type &constraint_system) {
273 
274  auto [alpha_g1, beta_g1, beta_g2, delta_g1, delta_g2, gamma_g2, A_query, B_query, H_query,
275  L_query, r1cs_copy, alpha_g1_beta_g2, gamma_ABC_g1, gamma_g1] =
276  basic_process<DistributionType, GeneratorType>(constraint_system);
277 
279  alpha_g1_beta_g2, gamma_g2, delta_g2, delta_g1, gamma_ABC_g1, gamma_g1);
280 
282  std::move(beta_g1),
283  std::move(beta_g2),
284  std::move(delta_g1),
285  std::move(delta_g2),
286  std::move(A_query),
287  std::move(B_query),
288  std::move(H_query),
289  std::move(L_query),
290  std::move(r1cs_copy));
291 
292  return {std::move(pk), std::move(vk)};
293  }
294  };
295  } // namespace snark
296  } // namespace zk
297  } // namespace crypto3
298 } // namespace nil
299 
300 #endif // CRYPTO3_ZK_R1CS_GG_PPZKSNARK_BASIC_GENERATOR_HPP
policy_type::auxiliary_input_type auxiliary_input_type
Definition: r1cs_gg_ppzksnark/generator.hpp:70
policy_type::extended_keypair_type extended_keypair_type
Definition: r1cs_gg_ppzksnark/generator.hpp:79
policy_type::extended_verification_key_type extended_verification_key_type
Definition: r1cs_gg_ppzksnark/generator.hpp:75
static auto basic_process(const constraint_system_type &constraint_system)
Definition: r1cs_gg_ppzksnark/generator.hpp:85
policy_type::proving_key_type proving_key_type
Definition: r1cs_gg_ppzksnark/generator.hpp:72
policy_type::processed_verification_key_type processed_verification_key_type
Definition: r1cs_gg_ppzksnark/generator.hpp:74
policy_type::processed_keypair_type processed_keypair_type
Definition: r1cs_gg_ppzksnark/generator.hpp:78
policy_type::primary_input_type primary_input_type
Definition: r1cs_gg_ppzksnark/generator.hpp:69
policy_type::proof_type proof_type
Definition: r1cs_gg_ppzksnark/generator.hpp:80
policy_type::verification_key_type verification_key_type
Definition: r1cs_gg_ppzksnark/generator.hpp:73
static std::enable_if< std::is_same< extended_keypair_type, KeyPairType >::value, KeyPairType >::type process(const constraint_system_type &constraint_system)
Definition: r1cs_gg_ppzksnark/generator.hpp:272
static std::enable_if< std::is_same< keypair_type, KeyPairType >::value, KeyPairType >::type process(const constraint_system_type &constraint_system)
Definition: r1cs_gg_ppzksnark/generator.hpp:243
policy_type::keypair_type keypair_type
Definition: r1cs_gg_ppzksnark/generator.hpp:77
policy_type::constraint_system_type constraint_system_type
Definition: r1cs_gg_ppzksnark/generator.hpp:68
Definition: r1cs_gg_ppzksnark/generator.hpp:49
std::vector< std::vector< typename GroupType::value_type > > window_table
Definition: multiexp.hpp:116
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
ProvingMode
Definition: modes.hpp:33
Definition: pair.hpp:31
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:78
r1cs_gg_ppzksnark_keypair< proving_key_type, verification_key_type > keypair_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:135
r1cs_auxiliary_input< typename curve_type::scalar_field_type > auxiliary_input_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:92
r1cs_primary_input< typename curve_type::scalar_field_type > primary_input_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:90
r1cs_gg_ppzksnark_keypair< proving_key_type, extended_verification_key_type > extended_keypair_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:153
r1cs_gg_ppzksnark_keypair< proving_key_type, processed_verification_key_type > processed_keypair_type
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/detail/basic_policy.hpp:144
std::vector< field_value_type > Ct
Definition: qap.hpp:196
std::size_t num_inputs
Definition: qap.hpp:190
std::vector< field_value_type > Bt
Definition: qap.hpp:196
std::vector< field_value_type > At
Definition: qap.hpp:196
field_value_type Zt
Definition: qap.hpp:198
std::size_t num_variables
Definition: qap.hpp:188
std::vector< field_value_type > Ht
Definition: qap.hpp:196
void swap_AB_if_beneficial()
Definition: r1cs.hpp:191
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/verification_key.hpp:121
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/verification_key.hpp:102
Definition: snark/systems/ppzksnark/r1cs_gg_ppzksnark/proof.hpp:40
Definition: systems/ppzksnark/r1cs_gg_ppzksnark/proving_key.hpp:39
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/verification_key.hpp:47
static qap_instance_evaluation< FieldType > instance_map_with_evaluation(const r1cs_constraint_system< FieldType > &cs, const typename FieldType::value_type &t)
Definition: r1cs_to_qap.hpp:140
Definition: sparse_vector.hpp:48