elgamal_verifiable.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2021 Ilias Khairullin <ilias@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 
26 #ifndef CRYPTO3_PUBKEY_ELGAMAL_VERIFIABLE_HPP
27 #define CRYPTO3_PUBKEY_ELGAMAL_VERIFIABLE_HPP
28 
29 #include <tuple>
30 #include <type_traits>
31 #include <iterator>
32 #include <vector>
33 
35 
39 
48 
49 namespace nil {
50  namespace crypto3 {
51  namespace pubkey {
52  template<typename Curve, std::size_t BlockBits = 4>
55  static_assert(BlockBits > 0);
56 
57  public:
58  typedef Curve curve_type;
59  static constexpr std::size_t block_bits = BlockBits;
60 
64  typedef std::tuple<public_key_type, private_key_type, verification_key_type> keypair_type;
65 
73 
74  typedef std::pair<std::vector<typename Curve::template g1_type<>::value_type>,
75  typename proof_system_type::proof_type>
77  typedef std::pair<std::vector<typename Curve::scalar_field_type::value_type>,
78  typename Curve::template g1_type<>::value_type>
80  };
81 
82  template<typename Curve, std::size_t BlockBits>
83  struct verification_key<elgamal_verifiable<Curve, BlockBits>> {
85  typedef typename Curve::template g2_type<> g2_type;
86 
87  friend class decrypt_op<scheme_type>;
88  friend class verify_decryption_op<scheme_type>;
89 
90  verification_key() = default;
91  verification_key(const typename g2_type::value_type &rho_g2,
92  const std::vector<typename g2_type::value_type> &rho_sv_g2,
93  const std::vector<typename g2_type::value_type> &rho_rhov_g2) :
94  rho_g2(rho_g2),
95  rho_sv_g2(rho_sv_g2), rho_rhov_g2(rho_rhov_g2) {
96  }
97  verification_key(typename g2_type::value_type &&rho_g2,
98  std::vector<typename g2_type::value_type> &&rho_sv_g2,
99  std::vector<typename g2_type::value_type> &&rho_rhov_g2) :
100  rho_g2(std::move(rho_g2)),
101  rho_sv_g2(std::move(rho_sv_g2)), rho_rhov_g2(std::move(rho_rhov_g2)) {
102  }
103 
104  // private:
105  typename g2_type::value_type rho_g2;
106  std::vector<typename g2_type::value_type> rho_sv_g2;
107  std::vector<typename g2_type::value_type> rho_rhov_g2;
108  };
109 
110  template<typename Curve, std::size_t BlockBits>
111  struct public_key<elgamal_verifiable<Curve, BlockBits>> {
113 
114  typedef typename Curve::template g1_type<> g1_type;
115  typedef typename Curve::template g2_type<> g2_type;
116 
117  public_key() = default;
118  public_key &operator=(const public_key &other) = default;
119  public_key(const public_key &other) = default;
120  public_key(public_key &&other) = default;
121  public_key(const typename g1_type::value_type &delta_g1,
122  const std::vector<typename g1_type::value_type> &delta_s_g1,
123  const std::vector<typename g1_type::value_type> &t_g1,
124  const std::vector<typename g2_type::value_type> &t_g2,
125  const typename g1_type::value_type &delta_sum_s_g1,
126  const typename g1_type::value_type &gamma_inverse_sum_s_g1) :
127  delta_g1(delta_g1),
128  delta_s_g1(delta_s_g1), t_g1(t_g1), t_g2(t_g2), delta_sum_s_g1(delta_sum_s_g1),
129  gamma_inverse_sum_s_g1(gamma_inverse_sum_s_g1) {
130  }
131  public_key(typename g1_type::value_type &&delta_g1,
132  std::vector<typename g1_type::value_type> &&delta_s_g1,
133  std::vector<typename g1_type::value_type> &&t_g1,
134  std::vector<typename g2_type::value_type> &&t_g2,
135  typename g1_type::value_type &&delta_sum_s_g1,
136  typename g1_type::value_type &&gamma_inverse_sum_s_g1) :
137  delta_g1(std::move(delta_g1)),
138  delta_s_g1(std::move(delta_s_g1)), t_g1(std::move(t_g1)), t_g2(std::move(t_g2)),
139  delta_sum_s_g1(std::move(delta_sum_s_g1)),
140  gamma_inverse_sum_s_g1(std::move(gamma_inverse_sum_s_g1)) {
141  }
142 
143  bool operator==(const public_key &other) const {
144  return delta_g1 == other.delta_g1 && delta_s_g1 == other.delta_s_g1 && t_g1 == other.t_g1 &&
145  t_g2 == other.t_g2 && delta_sum_s_g1 == other.delta_sum_s_g1 &&
146  gamma_inverse_sum_s_g1 == other.gamma_inverse_sum_s_g1;
147  }
148 
149  typename g1_type::value_type delta_g1;
150  std::vector<typename g1_type::value_type> delta_s_g1;
151  std::vector<typename g1_type::value_type> t_g1;
152  std::vector<typename g2_type::value_type> t_g2;
153  typename g1_type::value_type delta_sum_s_g1;
154  typename g1_type::value_type gamma_inverse_sum_s_g1;
155  };
156 
157  template<typename Curve, std::size_t BlockBits>
158  struct private_key<elgamal_verifiable<Curve, BlockBits>> {
160  typedef typename Curve::scalar_field_type scalar_field_type;
161 
162  friend class decrypt_op<scheme_type>;
163 
164  private_key() = default;
165  private_key(const typename scalar_field_type::value_type &rho) : rho(rho) {
166  }
167 
168  // private:
169  typename scalar_field_type::value_type rho;
170  };
171 
172  template<typename Curve, std::size_t BlockBits>
173  struct generate_keypair_op<elgamal_verifiable<Curve, BlockBits>> {
176 
181 
182  typedef typename Curve::scalar_field_type scalar_field_type;
183  typedef typename Curve::template g1_type<> g1_type;
184  typedef typename Curve::template g2_type<> g2_type;
185 
186  struct init_params_type {
187  const typename proof_system_type::keypair_type &gg_keypair;
188  std::size_t msg_size;
189  };
190  struct internal_accumulator_type {
191  const typename proof_system_type::keypair_type &gg_keypair;
192  std::size_t msg_size;
193  std::vector<typename scalar_field_type::value_type> rnd;
194  };
196 
197  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
198  // TODO: check
199  assert(init_params.gg_keypair.second.gamma_ABC_g1.rest.size() > init_params.msg_size);
200  return {init_params.gg_keypair, init_params.msg_size,
201  std::vector<typename scalar_field_type::value_type> {}};
202  }
203 
204  template<typename InputIterator>
205  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
206  std::move(first, last, std::back_inserter(acc.rnd));
207  }
208 
209  template<typename InputRange>
210  static inline void update(internal_accumulator_type &acc, InputRange range) {
211  update(acc, std::cbegin(range), std::cend(range));
212  }
213 
214  static inline result_type process(internal_accumulator_type &acc) {
215  // TODO: check
216  assert(acc.rnd.size() >= 3 * acc.msg_size + 2);
217  auto rnd_iter = std::cbegin(acc.rnd);
218 
219  typename scalar_field_type::value_type s_sum = scalar_field_type::value_type::zero();
220 
221  std::vector<typename g1_type::value_type> delta_s_g1;
222  typename g1_type::value_type delta_sum_s_g1;
223  typename g1_type::value_type gamma_inverse_sum_s_g1 = acc.gg_keypair.second.gamma_g1;
224 
225  typename scalar_field_type::value_type rho = *rnd_iter++;
226  typename g2_type::value_type rho_g2 = rho * g2_type::value_type::one();
227  std::vector<typename g2_type::value_type> rho_sv_g2;
228  std::vector<typename g2_type::value_type> rho_rhov_g2;
229 
230  std::vector<typename g1_type::value_type> t_g1;
231  std::vector<typename g2_type::value_type> t_g2;
232 
233  delta_s_g1.reserve(acc.msg_size);
234  rho_sv_g2.reserve(acc.msg_size);
235  rho_rhov_g2.reserve(acc.msg_size);
236  t_g1.reserve(acc.msg_size);
237  t_g2.reserve(acc.msg_size + 1);
238 
239  typename scalar_field_type::value_type t = *rnd_iter++;
240  t_g2.emplace_back(t * g2_type::value_type::one());
241  delta_sum_s_g1 = t * acc.gg_keypair.second.delta_g1;
242 
243  for (std::size_t i = 0; i < acc.msg_size; ++i) {
244  typename scalar_field_type::value_type s = *rnd_iter++;
245  typename scalar_field_type::value_type v = *rnd_iter++;
246  typename scalar_field_type::value_type sv = s * v;
247  t = *rnd_iter++;
248 
249  delta_s_g1.emplace_back(s * acc.gg_keypair.second.delta_g1);
250  t_g1.emplace_back(t * acc.gg_keypair.second.gamma_ABC_g1.rest[i]);
251  t_g2.emplace_back(t * g2_type::value_type::one());
252  delta_sum_s_g1 = delta_sum_s_g1 + (s * t) * acc.gg_keypair.second.delta_g1;
253  gamma_inverse_sum_s_g1 = gamma_inverse_sum_s_g1 + s * acc.gg_keypair.second.gamma_g1;
254 
255  rho_sv_g2.emplace_back(sv * g2_type::value_type::one());
256  rho_rhov_g2.emplace_back(v * rho_g2);
257  }
258  gamma_inverse_sum_s_g1 = -gamma_inverse_sum_s_g1;
259 
260  public_key_type pk(acc.gg_keypair.second.delta_g1, delta_s_g1, t_g1, t_g2, delta_sum_s_g1,
261  gamma_inverse_sum_s_g1);
262  private_key_type sk(rho);
263  verification_key_type vk(rho_g2, rho_sv_g2, rho_rhov_g2);
264 
265  return {pk, sk, vk};
266  }
267  };
268 
269  template<typename Curve, std::size_t BlockBits>
270  struct encrypt_op<elgamal_verifiable<Curve, BlockBits>> {
274 
275  typedef typename Curve::scalar_field_type scalar_field_type;
276  typedef typename Curve::template g1_type<> g1_type;
277 
278  struct init_params_type {
279  typename scalar_field_type::value_type r;
281  const typename proof_system_type::keypair_type &gg_keypair;
282  // TODO: accumulate primary_input and auxiliary_input
283  const typename proof_system_type::primary_input_type &primary_input;
284  const typename proof_system_type::auxiliary_input_type &auxiliary_input;
285  };
286  struct internal_accumulator_type {
287  std::vector<typename scalar_field_type::value_type> plain_text;
288  typename scalar_field_type::value_type r;
290  const typename proof_system_type::keypair_type &gg_keypair;
291  const typename proof_system_type::primary_input_type &primary_input;
292  const typename proof_system_type::auxiliary_input_type &auxiliary_input;
293  };
295 
296  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
297  return {std::vector<typename scalar_field_type::value_type> {},
298  std::move(init_params.r),
299  init_params.pubkey,
300  init_params.gg_keypair,
301  init_params.primary_input,
302  init_params.auxiliary_input};
303  }
304 
305  // TODO: process input data in place
306  // TODO: use marshaling module instead of custom marshaling to process input data
307  template<typename InputIterator>
308  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
309  std::copy(first, last, std::back_inserter(acc.plain_text));
310  }
311 
312  template<typename InputRange>
313  static inline void update(internal_accumulator_type &acc, InputRange range) {
314  update(acc, std::cbegin(range), std::cend(range));
315  }
316 
317  static inline result_type process(internal_accumulator_type &acc) {
318  // TODO: check
319  assert(acc.gg_keypair.second.gamma_ABC_g1.rest.size() > acc.plain_text.size());
320  assert(acc.primary_input.size() > acc.plain_text.size());
321  assert(acc.gg_keypair.second.gamma_ABC_g1.rest.size() == acc.primary_input.size());
322  assert(acc.plain_text.size() == acc.pubkey.delta_s_g1.size());
323  assert(acc.plain_text.size() == acc.pubkey.t_g1.size());
324  assert(acc.plain_text.size() == acc.pubkey.t_g2.size() - 1);
325  for (std::size_t i = 0; i < acc.plain_text.size(); ++i) {
326  assert(acc.primary_input[i] == acc.plain_text[i]);
327  }
328 
329  typename result_type::first_type ct_g1;
330  ct_g1.reserve(acc.plain_text.size() + 2);
331  ct_g1.emplace_back(acc.r * acc.pubkey.delta_g1);
332 
333  typename g1_type::value_type sum_tm_g1 = acc.r * acc.pubkey.delta_sum_s_g1;
334 
335  for (std::size_t i = 0; i < acc.plain_text.size(); ++i) {
336  ct_g1.emplace_back(acc.r * acc.pubkey.delta_s_g1[i] +
337  acc.plain_text[i] * acc.gg_keypair.second.gamma_ABC_g1.rest[i]);
338  sum_tm_g1 = sum_tm_g1 + acc.plain_text[i] * acc.pubkey.t_g1[i];
339  }
340  ct_g1.emplace_back(sum_tm_g1);
341  auto proof = zk::snark::prove<proof_system_type>(acc.gg_keypair.first, acc.pubkey,
342  acc.primary_input, acc.auxiliary_input, acc.r);
343 
344  return {ct_g1, proof};
345  }
346  };
347 
348  template<typename Curve, std::size_t BlockBits>
349  struct decrypt_op<elgamal_verifiable<Curve, BlockBits>> {
354 
355  typedef typename Curve::scalar_field_type scalar_field_type;
356  typedef typename Curve::template g1_type<> g1_type;
357  typedef typename Curve::gt_type gt_type;
358 
359  struct init_params_type {
362  const typename proof_system_type::keypair_type &gg_keypair;
363  };
364  struct internal_accumulator_type {
365  std::vector<typename g1_type::value_type> cipher_text;
368  const typename proof_system_type::keypair_type &gg_keypair;
369  };
371 
372  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
373  return internal_accumulator_type {std::vector<typename g1_type::value_type> {}, init_params.privkey,
374  init_params.vk, init_params.gg_keypair};
375  }
376 
377  // TODO: process input data in place
378  // TODO: use marshaling module instead of custom marshaling to process input data
379  template<typename InputIterator>
380  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
381  std::copy(first, last, std::back_inserter(acc.cipher_text));
382  }
383 
384  template<typename InputRange>
385  static inline void update(internal_accumulator_type &acc, InputRange range) {
386  update(acc, std::cbegin(range), std::cend(range));
387  }
388 
389  static inline result_type process(internal_accumulator_type &acc) {
390  // TODO: check
391  assert(acc.gg_keypair.second.gamma_ABC_g1.rest.size() > acc.cipher_text.size() - 2);
392  assert(acc.cipher_text.size() - 2 == acc.vk.rho_sv_g2.size());
393  assert(acc.cipher_text.size() - 2 == acc.vk.rho_rhov_g2.size());
394  std::vector<typename scalar_field_type::value_type> m_new;
395  m_new.reserve(acc.cipher_text.size() - 2);
396 
397  for (size_t j = 1; j < acc.cipher_text.size() - 1; ++j) {
398  typename gt_type::value_type ci_sk_i =
399  algebra::pair_reduced<Curve>(acc.cipher_text[j], acc.vk.rho_rhov_g2[j - 1]);
400  typename gt_type::value_type c0_sk_0 =
401  algebra::pair_reduced<Curve>(acc.cipher_text[0], acc.vk.rho_sv_g2[j - 1])
402  .pow(acc.privkey.rho.data);
403  typename gt_type::value_type dec_tmp = ci_sk_i * c0_sk_0.inversed();
404  auto discrete_log = gt_type::value_type::one();
405  typename gt_type::value_type bruteforce = algebra::pair_reduced<Curve>(
406  acc.gg_keypair.second.gamma_ABC_g1.rest[j - 1], acc.vk.rho_rhov_g2[j - 1]);
407  std::size_t exp = 0;
408  bool deciphered = false;
409  do {
410  if (dec_tmp == discrete_log) {
411  m_new.template emplace_back(exp);
412  deciphered = true;
413  break;
414  }
415  discrete_log = discrete_log * bruteforce;
416  } while (exp++ < 1 << scheme_type::block_bits);
417  assert(deciphered);
418  }
419 
420  typename g1_type::value_type verify_c0 = acc.privkey.rho * acc.cipher_text[0];
421 
422  return {m_new, verify_c0};
423  }
424  };
425 
426  template<typename Curve, std::size_t BlockBits>
427  struct verify_encryption_op<elgamal_verifiable<Curve, BlockBits>> {
431 
432  typedef typename Curve::scalar_field_type scalar_field_type;
433  typedef typename Curve::template g1_type<> g1_type;
434 
435  struct init_params_type {
437  const typename proof_system_type::verification_key_type &gg_vk;
438  const typename proof_system_type::proof_type &proof;
439  const typename proof_system_type::primary_input_type &unencrypted_primary_input;
440  };
441  struct internal_accumulator_type {
443  const typename proof_system_type::verification_key_type &gg_vk;
444  const typename proof_system_type::proof_type &proof;
445  const typename proof_system_type::primary_input_type &unencrypted_primary_input;
446  std::vector<typename g1_type::value_type> cipher_text;
447  };
448  typedef bool result_type;
449 
450  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
451  return internal_accumulator_type {init_params.pubkey, init_params.gg_vk, init_params.proof,
452  init_params.unencrypted_primary_input,
453  std::vector<typename g1_type::value_type> {}};
454  }
455 
456  // TODO: process input data in place
457  // TODO: use marshaling module instead of custom marshaling to process input data
458  template<typename InputIterator>
459  static inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
460  std::copy(first, last, std::back_inserter(acc.cipher_text));
461  }
462 
463  template<typename InputRange>
464  static inline void update(internal_accumulator_type &acc, InputRange range) {
465  update(acc, std::cbegin(range), std::cend(range));
466  }
467 
468  static inline result_type process(internal_accumulator_type &acc) {
469  return zk::snark::verify<proof_system_type>(std::cbegin(acc.cipher_text),
470  std::cend(acc.cipher_text), acc.gg_vk, acc.pubkey,
471  acc.unencrypted_primary_input, acc.proof);
472  }
473  };
474 
475  template<typename Curve, std::size_t BlockBits>
476  struct verify_decryption_op<elgamal_verifiable<Curve, BlockBits>> {
481 
482  typedef typename Curve::scalar_field_type scalar_field_type;
483  typedef typename Curve::template g1_type<> g1_type;
484  typedef typename Curve::template g2_type<> g2_type;
485  typedef typename Curve::gt_type gt_type;
486 
487  struct init_params_type {
489  const typename proof_system_type::keypair_type &gg_keypair;
490  const typename g1_type::value_type &proof;
491  };
492  struct internal_accumulator_type {
494  const typename proof_system_type::keypair_type &gg_keypair;
495  const typename g1_type::value_type &proof;
496  std::vector<typename scalar_field_type::value_type> plain_text;
497  std::vector<typename g1_type::value_type> cipher_text;
498  };
499  typedef bool result_type;
500 
501  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
502  return internal_accumulator_type {init_params.vk, init_params.gg_keypair, init_params.proof,
503  std::vector<typename scalar_field_type::value_type> {},
504  std::vector<typename g1_type::value_type> {}};
505  }
506 
507  // TODO: process input data in place
508  // TODO: use marshaling module instead of custom marshaling to process input data
509  template<typename InputIterator>
510  static inline typename std::enable_if<
511  std::is_same<typename scalar_field_type::value_type,
512  typename std::iterator_traits<InputIterator>::value_type>::value>::type
513  update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
514  std::copy(first, last, std::back_inserter(acc.plain_text));
515  }
516 
517  template<typename InputIterator>
518  static inline typename std::enable_if<
519  std::is_same<typename g1_type::value_type,
520  typename std::iterator_traits<InputIterator>::value_type>::value>::type
521  update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
522  std::copy(first, last, std::back_inserter(acc.cipher_text));
523  }
524 
525  template<typename InputRange>
526  static inline void update(internal_accumulator_type &acc, InputRange range) {
527  update(acc, std::cbegin(range), std::cend(range));
528  }
529 
530  static inline result_type process(internal_accumulator_type &acc) {
531  assert(acc.plain_text.size() + 2 == acc.cipher_text.size());
532  assert(acc.gg_keypair.second.gamma_ABC_g1.rest.size() > acc.plain_text.size());
533  typename gt_type::value_type vm_gt =
534  algebra::pair_reduced<Curve>(acc.proof, g2_type::value_type::one());
535  typename gt_type::value_type new_c0_v0_gt =
536  algebra::pair_reduced<Curve>(acc.cipher_text[0], acc.vk.rho_g2);
537  bool ans = (vm_gt == new_c0_v0_gt);
538 
539  for (size_t i = 1; i < acc.cipher_text.size() - 1; ++i) {
540  typename gt_type::value_type ci_v_nj_gt =
541  algebra::pair_reduced<Curve>(acc.cipher_text[i], acc.vk.rho_rhov_g2[i - 1]);
542  typename gt_type::value_type v_vj_gt =
543  algebra::pair_reduced<Curve>(acc.proof, acc.vk.rho_sv_g2[i - 1]);
544  typename gt_type::value_type verify_tmp = ci_v_nj_gt * v_vj_gt.inversed();
545  typename gt_type::value_type verify_msg =
546  algebra::pair_reduced<Curve>(acc.gg_keypair.second.gamma_ABC_g1.rest[i - 1],
547  acc.vk.rho_rhov_g2[i - 1])
548  .pow(acc.plain_text[i - 1].data);
549  bool ans_m = (verify_tmp == verify_msg);
550  ans &= ans_m;
551  }
552 
553  return ans;
554  }
555  };
556 
557  template<typename Curve, std::size_t BlockBits>
558  struct rerandomize_op<elgamal_verifiable<Curve, BlockBits>> {
562 
563  typedef typename Curve::scalar_field_type scalar_field_type;
564  typedef typename Curve::template g1_type<> g1_type;
565  typedef typename Curve::template g2_type<> g2_type;
566  typedef typename Curve::gt_type gt_type;
567 
568  struct init_params_type {
570  const typename proof_system_type::keypair_type &gg_keypair;
571  const typename proof_system_type::proof_type &proof;
572  };
573  struct internal_accumulator_type {
575  const typename proof_system_type::keypair_type &gg_keypair;
576  const typename proof_system_type::proof_type &proof;
577  std::vector<typename scalar_field_type::value_type> rnd;
578  std::vector<typename g1_type::value_type> cipher_text;
579  };
581 
582  static inline internal_accumulator_type init_accumulator(const init_params_type &init_params) {
583  return internal_accumulator_type {init_params.pubkey, init_params.gg_keypair, init_params.proof,
584  std::vector<typename scalar_field_type::value_type> {},
585  std::vector<typename g1_type::value_type> {}};
586  }
587 
588  // TODO: process input data in place
589  // TODO: use marshaling module instead of custom marshaling to process input data
590  template<typename InputIterator>
591  static inline typename std::enable_if<
592  std::is_same<typename scalar_field_type::value_type,
593  typename std::iterator_traits<InputIterator>::value_type>::value>::type
594  update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
595  std::copy(first, last, std::back_inserter(acc.rnd));
596  }
597 
598  template<typename InputIterator>
599  static inline typename std::enable_if<
600  std::is_same<typename g1_type::value_type,
601  typename std::iterator_traits<InputIterator>::value_type>::value>::type
602  update(internal_accumulator_type &acc, InputIterator first, InputIterator last) {
603  std::copy(first, last, std::back_inserter(acc.cipher_text));
604  }
605 
606  template<typename InputRange>
607  static inline void update(internal_accumulator_type &acc, InputRange range) {
608  update(acc, std::cbegin(range), std::cend(range));
609  }
610 
611  static inline result_type process(internal_accumulator_type &acc) {
612  assert(acc.rnd.size() >= 3);
613  assert(acc.pubkey.delta_s_g1.size() == acc.cipher_text.size() - 2);
614  assert(acc.pubkey.t_g1.size() == acc.cipher_text.size() - 2);
615  assert(acc.pubkey.t_g2.size() - 1 == acc.cipher_text.size() - 2);
616  std::vector<typename g1_type::value_type> ct_g1;
617  ct_g1.reserve(acc.cipher_text.size());
618 
619  auto rnd_it = std::cbegin(acc.rnd);
620  typename scalar_field_type::value_type r = *rnd_it++;
621  typename scalar_field_type::value_type z1 = *rnd_it++;
622  typename scalar_field_type::value_type z2 = *rnd_it++;
623 
624  typename scalar_field_type::value_type z1_inverse = z1.inversed();
625 
626  ct_g1.emplace_back(acc.cipher_text.front() + r * acc.pubkey.delta_g1);
627  for (size_t i = 1; i < acc.cipher_text.size() - 1; ++i) {
628  ct_g1.emplace_back(acc.cipher_text[i] + r * acc.pubkey.delta_s_g1[i - 1]);
629  }
630  ct_g1.emplace_back(acc.cipher_text.back() + r * acc.pubkey.delta_sum_s_g1);
631 
632  typename g1_type::value_type g1_A = z1 * acc.proof.g_A;
633  typename g2_type::value_type g2_B =
634  z1_inverse * acc.proof.g_B + z2 * acc.gg_keypair.second.delta_g2;
635  typename g1_type::value_type g1_C =
636  acc.proof.g_C + z2 * g1_A + r * acc.pubkey.gamma_inverse_sum_s_g1;
637 
638  return std::make_pair(ct_g1, typename proof_system_type::proof_type {
639  std::move(g1_A), std::move(g2_B), std::move(g1_C)});
640  }
641  };
642  } // namespace pubkey
643  } // namespace crypto3
644 } // namespace nil
645 
646 #endif
Definition: elgamal_verifiable.hpp:53
std::tuple< public_key_type, private_key_type, verification_key_type > keypair_type
Definition: elgamal_verifiable.hpp:64
std::pair< std::vector< typename Curve::scalar_field_type::value_type >, typename Curve::template g1_type<>::value_type > decipher_type
Definition: elgamal_verifiable.hpp:79
private_key< self_type > private_key_type
Definition: elgamal_verifiable.hpp:62
verification_key< self_type > verification_key_type
Definition: elgamal_verifiable.hpp:63
zk::snark::r1cs_gg_ppzksnark< Curve, zk::snark::r1cs_gg_ppzksnark_generator< Curve, zk::snark::ProvingMode::EncryptedInput >, zk::snark::r1cs_gg_ppzksnark_prover< Curve, zk::snark::ProvingMode::EncryptedInput >, zk::snark::r1cs_gg_ppzksnark_verifier_strong_input_consistency< Curve, zk::snark::ProvingMode::EncryptedInput >, zk::snark::ProvingMode::EncryptedInput > proof_system_type
Definition: elgamal_verifiable.hpp:72
std::pair< std::vector< typename Curve::template g1_type<>::value_type >, typename proof_system_type::proof_type > cipher_type
Definition: elgamal_verifiable.hpp:76
Curve curve_type
Definition: elgamal_verifiable.hpp:55
public_key< self_type > public_key_type
Definition: elgamal_verifiable.hpp:61
static constexpr std::size_t block_bits
Definition: elgamal_verifiable.hpp:59
Definition: r1cs_gg_ppzksnark/generator.hpp:49
Definition: r1cs_gg_ppzksnark/prover.hpp:47
Definition: zk/include/nil/crypto3/zk/snark/systems/ppzksnark/r1cs_gg_ppzksnark/verifier.hpp:75
ppzkSNARK for R1CS with a security proof in the generic group (GG) model
Definition: r1cs_gg_ppzksnark.hpp:109
OutputIterator move(const SinglePassRange &rng, OutputIterator result)
Definition: move.hpp:45
boost::mpl::apply< AccumulatorSet, tag::pubkey< ProcessingMode > >::type::result_type pubkey(const AccumulatorSet &acc)
Definition: accumulators/pubkey.hpp:106
Definition: pair.hpp:31
const private_key_type & privkey
Definition: elgamal_verifiable.hpp:360
const verification_key_type & vk
Definition: elgamal_verifiable.hpp:361
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:362
const verification_key_type & vk
Definition: elgamal_verifiable.hpp:367
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:368
std::vector< typename g1_type::value_type > cipher_text
Definition: elgamal_verifiable.hpp:365
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:389
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:372
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:355
scheme_type::decipher_type result_type
Definition: elgamal_verifiable.hpp:370
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:385
Curve::gt_type gt_type
Definition: elgamal_verifiable.hpp:357
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:356
scheme_type::private_key_type private_key_type
Definition: elgamal_verifiable.hpp:352
scheme_type::verification_key_type verification_key_type
Definition: elgamal_verifiable.hpp:353
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:350
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:380
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:351
Definition: decrypt_op.hpp:33
const proof_system_type::auxiliary_input_type & auxiliary_input
Definition: elgamal_verifiable.hpp:284
const proof_system_type::primary_input_type & primary_input
Definition: elgamal_verifiable.hpp:283
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:281
scalar_field_type::value_type r
Definition: elgamal_verifiable.hpp:279
const public_key_type & pubkey
Definition: elgamal_verifiable.hpp:280
const proof_system_type::auxiliary_input_type & auxiliary_input
Definition: elgamal_verifiable.hpp:292
const proof_system_type::primary_input_type & primary_input
Definition: elgamal_verifiable.hpp:291
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:290
std::vector< typename scalar_field_type::value_type > plain_text
Definition: elgamal_verifiable.hpp:287
scheme_type::public_key_type public_key_type
Definition: elgamal_verifiable.hpp:273
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:308
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:296
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:317
scheme_type::cipher_type result_type
Definition: elgamal_verifiable.hpp:294
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:276
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:272
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:271
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:313
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:275
Definition: encrypt_op.hpp:33
std::vector< typename scalar_field_type::value_type > rnd
Definition: elgamal_verifiable.hpp:193
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:191
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:205
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:210
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:174
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:175
scheme_type::private_key_type private_key_type
Definition: elgamal_verifiable.hpp:178
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:214
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:182
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:197
scheme_type::keypair_type keypair_type
Definition: elgamal_verifiable.hpp:180
Curve::template g2_type g2_type
Definition: elgamal_verifiable.hpp:184
scheme_type::verification_key_type verification_key_type
Definition: elgamal_verifiable.hpp:179
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:183
scheme_type::public_key_type public_key_type
Definition: elgamal_verifiable.hpp:177
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:187
Definition: generate_keypair_op.hpp:33
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:160
private_key(const typename scalar_field_type::value_type &rho)
Definition: elgamal_verifiable.hpp:165
scalar_field_type::value_type rho
Definition: elgamal_verifiable.hpp:169
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:159
Private key - a key known only to its owner. Only the user keeping his private key secret guarantees ...
Definition: private_key.hpp:47
std::vector< typename g1_type::value_type > t_g1
Definition: elgamal_verifiable.hpp:151
public_key(const typename g1_type::value_type &delta_g1, const std::vector< typename g1_type::value_type > &delta_s_g1, const std::vector< typename g1_type::value_type > &t_g1, const std::vector< typename g2_type::value_type > &t_g2, const typename g1_type::value_type &delta_sum_s_g1, const typename g1_type::value_type &gamma_inverse_sum_s_g1)
Definition: elgamal_verifiable.hpp:121
std::vector< typename g1_type::value_type > delta_s_g1
Definition: elgamal_verifiable.hpp:150
g1_type::value_type delta_sum_s_g1
Definition: elgamal_verifiable.hpp:153
Curve::template g2_type g2_type
Definition: elgamal_verifiable.hpp:115
bool operator==(const public_key &other) const
Definition: elgamal_verifiable.hpp:143
std::vector< typename g2_type::value_type > t_g2
Definition: elgamal_verifiable.hpp:152
g1_type::value_type delta_g1
Definition: elgamal_verifiable.hpp:149
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:112
public_key(typename g1_type::value_type &&delta_g1, std::vector< typename g1_type::value_type > &&delta_s_g1, std::vector< typename g1_type::value_type > &&t_g1, std::vector< typename g2_type::value_type > &&t_g2, typename g1_type::value_type &&delta_sum_s_g1, typename g1_type::value_type &&gamma_inverse_sum_s_g1)
Definition: elgamal_verifiable.hpp:131
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:114
g1_type::value_type gamma_inverse_sum_s_g1
Definition: elgamal_verifiable.hpp:154
Public key - a key that can be published and used to verify the authenticity of the signed document,...
Definition: public_key.hpp:43
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:570
const proof_system_type::proof_type & proof
Definition: elgamal_verifiable.hpp:571
static std::enable_if< std::is_same< typename scalar_field_type::value_type, typename std::iterator_traits< InputIterator >::value_type >::value >::type update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:594
scheme_type::public_key_type public_key_type
Definition: elgamal_verifiable.hpp:561
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:563
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:560
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:559
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:611
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:582
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:564
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:607
Curve::gt_type gt_type
Definition: elgamal_verifiable.hpp:566
static std::enable_if< std::is_same< typename g1_type::value_type, typename std::iterator_traits< InputIterator >::value_type >::value >::type update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:602
scheme_type::cipher_type result_type
Definition: elgamal_verifiable.hpp:580
Curve::template g2_type g2_type
Definition: elgamal_verifiable.hpp:565
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:575
std::vector< typename scalar_field_type::value_type > rnd
Definition: elgamal_verifiable.hpp:577
std::vector< typename g1_type::value_type > cipher_text
Definition: elgamal_verifiable.hpp:578
const proof_system_type::proof_type & proof
Definition: elgamal_verifiable.hpp:576
Definition: rerandomize_op.hpp:33
verification_key(typename g2_type::value_type &&rho_g2, std::vector< typename g2_type::value_type > &&rho_sv_g2, std::vector< typename g2_type::value_type > &&rho_rhov_g2)
Definition: elgamal_verifiable.hpp:97
g2_type::value_type rho_g2
Definition: elgamal_verifiable.hpp:105
verification_key(const typename g2_type::value_type &rho_g2, const std::vector< typename g2_type::value_type > &rho_sv_g2, const std::vector< typename g2_type::value_type > &rho_rhov_g2)
Definition: elgamal_verifiable.hpp:91
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:84
std::vector< typename g2_type::value_type > rho_rhov_g2
Definition: elgamal_verifiable.hpp:107
std::vector< typename g2_type::value_type > rho_sv_g2
Definition: elgamal_verifiable.hpp:106
Curve::template g2_type g2_type
Definition: elgamal_verifiable.hpp:85
Definition: pubkey/include/nil/crypto3/pubkey/keys/verification_key.hpp:39
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:477
static std::enable_if< std::is_same< typename g1_type::value_type, typename std::iterator_traits< InputIterator >::value_type >::value >::type update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:521
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:526
scheme_type::verification_key_type verification_key_type
Definition: elgamal_verifiable.hpp:480
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:501
scheme_type::public_key_type public_key_type
Definition: elgamal_verifiable.hpp:479
static std::enable_if< std::is_same< typename scalar_field_type::value_type, typename std::iterator_traits< InputIterator >::value_type >::value >::type update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:513
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:482
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:483
Curve::template g2_type g2_type
Definition: elgamal_verifiable.hpp:484
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:530
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:478
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:494
std::vector< typename scalar_field_type::value_type > plain_text
Definition: elgamal_verifiable.hpp:496
std::vector< typename g1_type::value_type > cipher_text
Definition: elgamal_verifiable.hpp:497
const proof_system_type::keypair_type & gg_keypair
Definition: elgamal_verifiable.hpp:489
Definition: verify_decryption_op.hpp:33
const proof_system_type::verification_key_type & gg_vk
Definition: elgamal_verifiable.hpp:437
const proof_system_type::primary_input_type & unencrypted_primary_input
Definition: elgamal_verifiable.hpp:439
const proof_system_type::proof_type & proof
Definition: elgamal_verifiable.hpp:438
elgamal_verifiable< Curve, BlockBits > scheme_type
Definition: elgamal_verifiable.hpp:428
static internal_accumulator_type init_accumulator(const init_params_type &init_params)
Definition: elgamal_verifiable.hpp:450
Curve::template g1_type g1_type
Definition: elgamal_verifiable.hpp:433
scheme_type::proof_system_type proof_system_type
Definition: elgamal_verifiable.hpp:429
scheme_type::public_key_type public_key_type
Definition: elgamal_verifiable.hpp:430
static result_type process(internal_accumulator_type &acc)
Definition: elgamal_verifiable.hpp:468
static void update(internal_accumulator_type &acc, InputRange range)
Definition: elgamal_verifiable.hpp:464
Curve::scalar_field_type scalar_field_type
Definition: elgamal_verifiable.hpp:432
static void update(internal_accumulator_type &acc, InputIterator first, InputIterator last)
Definition: elgamal_verifiable.hpp:459
const proof_system_type::proof_type & proof
Definition: elgamal_verifiable.hpp:444
const proof_system_type::verification_key_type & gg_vk
Definition: elgamal_verifiable.hpp:443
std::vector< typename g1_type::value_type > cipher_text
Definition: elgamal_verifiable.hpp:446
const proof_system_type::primary_input_type & unencrypted_primary_input
Definition: elgamal_verifiable.hpp:445
Definition: verify_encryption_op.hpp:33