Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
mnt4_pairing.cpp
Go to the documentation of this file.
1 
14 #include <cassert>
21 
22 namespace libff
23 {
24 
26 {
27  return (
28  this->PX == other.PX && this->PY == other.PY &&
29  this->PX_twist == other.PX_twist && this->PY_twist == other.PY_twist);
30 }
31 
32 std::ostream &operator<<(std::ostream &out, const mnt4_ate_G1_precomp &prec_P)
33 {
34  out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY << OUTPUT_SEPARATOR
35  << prec_P.PX_twist << OUTPUT_SEPARATOR << prec_P.PY_twist;
36 
37  return out;
38 }
39 
40 std::istream &operator>>(std::istream &in, mnt4_ate_G1_precomp &prec_P)
41 {
42  in >> prec_P.PX;
44  in >> prec_P.PY;
46  in >> prec_P.PX_twist;
48  in >> prec_P.PY_twist;
49 
50  return in;
51 }
52 
54 {
55  return (
56  this->c_H == other.c_H && this->c_4C == other.c_4C &&
57  this->c_J == other.c_J && this->c_L == other.c_L);
58 }
59 
60 std::ostream &operator<<(std::ostream &out, const mnt4_ate_dbl_coeffs &dc)
61 {
62  out << dc.c_H << OUTPUT_SEPARATOR << dc.c_4C << OUTPUT_SEPARATOR << dc.c_J
63  << OUTPUT_SEPARATOR << dc.c_L;
64  return out;
65 }
66 
67 std::istream &operator>>(std::istream &in, mnt4_ate_dbl_coeffs &dc)
68 {
69  in >> dc.c_H;
71  in >> dc.c_4C;
73  in >> dc.c_J;
75  in >> dc.c_L;
76 
77  return in;
78 }
79 
81 {
82  return (this->c_L1 == other.c_L1 && this->c_RZ == other.c_RZ);
83 }
84 
85 std::ostream &operator<<(std::ostream &out, const mnt4_ate_add_coeffs &ac)
86 {
87  out << ac.c_L1 << OUTPUT_SEPARATOR << ac.c_RZ;
88  return out;
89 }
90 
91 std::istream &operator>>(std::istream &in, mnt4_ate_add_coeffs &ac)
92 {
93  in >> ac.c_L1;
95  in >> ac.c_RZ;
96  return in;
97 }
98 
100 {
101  return (
102  this->QX == other.QX && this->QY == other.QY &&
103  this->QY2 == other.QY2 && this->QX_over_twist == other.QX_over_twist &&
104  this->QY_over_twist == other.QY_over_twist &&
105  this->dbl_coeffs == other.dbl_coeffs &&
106  this->add_coeffs == other.add_coeffs);
107 }
108 
109 std::ostream &operator<<(std::ostream &out, const mnt4_ate_G2_precomp &prec_Q)
110 {
111  out << prec_Q.QX << OUTPUT_SEPARATOR << prec_Q.QY << OUTPUT_SEPARATOR
112  << prec_Q.QY2 << OUTPUT_SEPARATOR << prec_Q.QX_over_twist
113  << OUTPUT_SEPARATOR << prec_Q.QY_over_twist << "\n";
114  out << prec_Q.dbl_coeffs.size() << "\n";
115  for (const mnt4_ate_dbl_coeffs &dc : prec_Q.dbl_coeffs) {
116  out << dc << OUTPUT_NEWLINE;
117  }
118  out << prec_Q.add_coeffs.size() << "\n";
119  for (const mnt4_ate_add_coeffs &ac : prec_Q.add_coeffs) {
120  out << ac << OUTPUT_NEWLINE;
121  }
122 
123  return out;
124 }
125 
126 std::istream &operator>>(std::istream &in, mnt4_ate_G2_precomp &prec_Q)
127 {
128  in >> prec_Q.QX;
130  in >> prec_Q.QY;
132  in >> prec_Q.QY2;
134  in >> prec_Q.QX_over_twist;
136  in >> prec_Q.QY_over_twist;
137  consume_newline(in);
138 
139  prec_Q.dbl_coeffs.clear();
140  size_t dbl_s;
141  in >> dbl_s;
142  consume_newline(in);
143 
144  prec_Q.dbl_coeffs.reserve(dbl_s);
145 
146  for (size_t i = 0; i < dbl_s; ++i) {
148  in >> dc;
150  prec_Q.dbl_coeffs.emplace_back(dc);
151  }
152 
153  prec_Q.add_coeffs.clear();
154  size_t add_s;
155  in >> add_s;
156  consume_newline(in);
157 
158  prec_Q.add_coeffs.reserve(add_s);
159 
160  for (size_t i = 0; i < add_s; ++i) {
162  in >> ac;
164  prec_Q.add_coeffs.emplace_back(ac);
165  }
166 
167  return in;
168 }
169 
170 /* final exponentiations */
171 
173  const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
174 {
175  enter_block("Call to mnt4_final_exponentiation_last_chunk");
176  const mnt4_Fq4 elt_q = elt.Frobenius_map(1);
178  mnt4_Fq4 w0_part;
180  w0_part =
182  } else {
184  }
185  mnt4_Fq4 result = w1_part * w0_part;
186  leave_block("Call to mnt4_final_exponentiation_last_chunk");
187 
188  return result;
189 }
190 
192  const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
193 {
194  enter_block("Call to mnt4_final_exponentiation_first_chunk");
195 
196  /* (q^2-1) */
197 
198  /* elt_q2 = elt^(q^2) */
199  const mnt4_Fq4 elt_q2 = elt.Frobenius_map(2);
200  /* elt_q3_over_elt = elt^(q^2-1) */
201  const mnt4_Fq4 elt_q2_over_elt = elt_q2 * elt_inv;
202 
203  leave_block("Call to mnt4_final_exponentiation_first_chunk");
204  return elt_q2_over_elt;
205 }
206 
208 {
209  enter_block("Call to mnt4_final_exponentiation");
210  const mnt4_Fq4 elt_inv = elt.inverse();
211  const mnt4_Fq4 elt_to_first_chunk =
213  const mnt4_Fq4 elt_inv_to_first_chunk =
216  elt_to_first_chunk, elt_inv_to_first_chunk);
217  leave_block("Call to mnt4_final_exponentiation");
218 
219  return result;
220 }
221 
222 /* affine ate miller loop */
223 
225  const mnt4_G1 &P)
226 {
227  enter_block("Call to mnt4_affine_ate_precompute_G1");
228 
229  mnt4_G1 Pcopy = P;
230  Pcopy.to_affine_coordinates();
231 
233  result.PX = Pcopy.X;
234  result.PY = Pcopy.Y;
235  result.PY_twist_squared = Pcopy.Y * mnt4_twist.squared();
236 
237  leave_block("Call to mnt4_affine_ate_precompute_G1");
238  return result;
239 }
240 
242  const mnt4_G2 &Q)
243 {
244  enter_block("Call to mnt4_affine_ate_precompute_G2");
245 
246  mnt4_G2 Qcopy(Q);
247  Qcopy.to_affine_coordinates();
248 
250  result.QX = Qcopy.X;
251  result.QY = Qcopy.Y;
252 
253  mnt4_Fq2 RX = Qcopy.X;
254  mnt4_Fq2 RY = Qcopy.Y;
255 
257  bool found_nonzero = false;
258 
259  std::vector<long> NAF = find_wnaf(1, loop_count);
260  for (long i = NAF.size() - 1; i >= 0; --i) {
261  if (!found_nonzero) {
262  /* this skips the MSB itself */
263  found_nonzero |= (NAF[i] != 0);
264  continue;
265  }
266 
268  c.old_RX = RX;
269  c.old_RY = RY;
270  mnt4_Fq2 old_RX_2 = c.old_RX.squared();
271  c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt4_twist_coeff_a) *
272  (c.old_RY + c.old_RY).inverse();
273  c.gamma_twist = c.gamma * mnt4_twist;
274  c.gamma_X = c.gamma * c.old_RX;
275  result.coeffs.push_back(c);
276 
277  RX = c.gamma.squared() - (c.old_RX + c.old_RX);
278  RY = c.gamma * (c.old_RX - RX) - c.old_RY;
279 
280  if (NAF[i] != 0) {
282  c.old_RX = RX;
283  c.old_RY = RY;
284  if (NAF[i] > 0) {
285  c.gamma =
286  (c.old_RY - result.QY) * (c.old_RX - result.QX).inverse();
287  } else {
288  c.gamma =
289  (c.old_RY + result.QY) * (c.old_RX - result.QX).inverse();
290  }
291  c.gamma_twist = c.gamma * mnt4_twist;
292  c.gamma_X = c.gamma * result.QX;
293  result.coeffs.push_back(c);
294 
295  RX = c.gamma.squared() - (c.old_RX + result.QX);
296  RY = c.gamma * (c.old_RX - RX) - c.old_RY;
297  }
298  }
299 
300  /* TODO: maybe handle neg
301  if (mnt4_ate_is_loop_count_neg)
302  {
303  mnt4_ate_add_coeffs ac;
304  mnt4_affine_ate_dbl_coeffs c;
305  c.old_RX = RX;
306  c.old_RY = -RY;
307  old_RX_2 = c.old_RY.squared();
308  c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt4_coeff_a) * (c.old_RY +
309  c.old_RY).inverse(); c.gamma_twist = c.gamma * mnt4_twist; c.gamma_X =
310  c.gamma * c.old_RX; result.coeffs.push_back(c);
311  }
312  */
313 
314  leave_block("Call to mnt4_affine_ate_precompute_G2");
315  return result;
316 }
317 
319  const mnt4_affine_ate_G1_precomputation &prec_P,
320  const mnt4_affine_ate_G2_precomputation &prec_Q)
321 {
322  enter_block("Call to mnt4_affine_ate_miller_loop");
323 
324  mnt4_Fq4 f = mnt4_Fq4::one();
325 
326  bool found_nonzero = false;
327  size_t idx = 0;
329 
330  std::vector<long> NAF = find_wnaf(1, loop_count);
331  for (long i = NAF.size() - 1; i >= 0; --i) {
332  if (!found_nonzero) {
333  /* this skips the MSB itself */
334  found_nonzero |= (NAF[i] != 0);
335  continue;
336  }
337 
338  /* code below gets executed for all bits (EXCEPT the MSB itself) of
339  mnt4_param_p (skipping leading zeros) in MSB to LSB
340  order */
341  mnt4_affine_ate_coeffs c = prec_Q.coeffs[idx++];
342 
343  mnt4_Fq4 g_RR_at_P = mnt4_Fq4(
344  prec_P.PY_twist_squared,
345  -prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
346  f = f.squared().mul_by_023(g_RR_at_P);
347 
348  if (NAF[i] != 0) {
349  mnt4_affine_ate_coeffs c = prec_Q.coeffs[idx++];
350  mnt4_Fq4 g_RQ_at_P;
351  if (NAF[i] > 0) {
352  g_RQ_at_P = mnt4_Fq4(
353  prec_P.PY_twist_squared,
354  -prec_P.PX * c.gamma_twist + c.gamma_X - prec_Q.QY);
355  } else {
356  g_RQ_at_P = mnt4_Fq4(
357  prec_P.PY_twist_squared,
358  -prec_P.PX * c.gamma_twist + c.gamma_X + prec_Q.QY);
359  }
360  f = f.mul_by_023(g_RQ_at_P);
361  }
362  }
363 
364  /* TODO: maybe handle neg
365  if (mnt4_ate_is_loop_count_neg)
366  {
367  // TODO:
368  mnt4_affine_ate_coeffs ac = prec_Q.coeffs[idx++];
369  mnt4_Fq4 g_RnegR_at_P = mnt4_Fq4(prec_P.PY_twist_squared,
370  - prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
371  f = (f * g_RnegR_at_P).inverse();
372  }
373  */
374 
375  leave_block("Call to mnt4_affine_ate_miller_loop");
376 
377  return f;
378 }
379 
380 /* ate pairing */
381 
387 
388  void print() const
389  {
390  printf("extended mnt4_G2 projective X/Y/Z/T:\n");
391  X.print();
392  Y.print();
393  Z.print();
394  T.print();
395  }
396 
397  void test_invariant() const { assert(T == Z.squared()); }
398 };
399 
402 {
403  const mnt4_Fq2 X = current.X, Y = current.Y, Z = current.Z, T = current.T;
404 
405  const mnt4_Fq2 A = T.squared(); // A = T1^2
406  const mnt4_Fq2 B = X.squared(); // B = X1^2
407  const mnt4_Fq2 C = Y.squared(); // C = Y1^2
408  const mnt4_Fq2 D = C.squared(); // D = C^2
409  const mnt4_Fq2 E = (X + C).squared() - B - D; // E = (X1+C)^2-B-D
410  const mnt4_Fq2 F = (B + B + B) + mnt4_twist_coeff_a * A; // F = 3*B + a *A
411  const mnt4_Fq2 G = F.squared(); // G = F^2
412 
413  current.X = -(E + E + E + E) + G; // X3 = -4*E+G
414  current.Y =
415  -mnt4_Fq("8") * D + F * (E + E - current.X); // Y3 = -8*D+F*(2*E-X3)
416  current.Z = (Y + Z).squared() - C - Z.squared(); // Z3 = (Y1+Z1)^2-C-Z1^2
417  current.T = current.Z.squared(); // T3 = Z3^2
418 
419  dc.c_H = (current.Z + T).squared() - current.T - A; // H = (Z3+T1)^2-T3-A
420  dc.c_4C = C + C + C + C; // fourC = 4*C
421  dc.c_J = (F + T).squared() - G - A; // J = (F+T1)^2-G-A
422  dc.c_L = (F + X).squared() - G - B; // L = (F+X1)^2-G-B
423 
424 #ifdef DEBUG
425  current.test_invariant();
426 #endif
427 }
428 
430  const mnt4_Fq2 base_X,
431  const mnt4_Fq2 base_Y,
432  const mnt4_Fq2 base_Y_squared,
435 {
436  const mnt4_Fq2 X1 = current.X, Y1 = current.Y, Z1 = current.Z,
437  T1 = current.T;
438  const mnt4_Fq2 &x2 = base_X, &y2 = base_Y, &y2_squared = base_Y_squared;
439 
440  const mnt4_Fq2 B = x2 * T1; // B = x2 * T1
441  const mnt4_Fq2 D = ((y2 + Z1).squared() - y2_squared - T1) *
442  T1; // D = ((y2 + Z1)^2 - y2squared - T1) * T1
443  const mnt4_Fq2 H = B - X1; // H = B - X1
444  const mnt4_Fq2 I = H.squared(); // I = H^2
445  const mnt4_Fq2 E = I + I + I + I; // E = 4*I
446  const mnt4_Fq2 J = H * E; // J = H * E
447  const mnt4_Fq2 V = X1 * E; // V = X1 * E
448  const mnt4_Fq2 L1 = D - (Y1 + Y1); // L1 = D - 2 * Y1
449 
450  current.X = L1.squared() - J - (V + V); // X3 = L1^2 - J - 2*V
451  current.Y =
452  L1 * (V - current.X) - (Y1 + Y1) * J; // Y3 = L1 * (V-X3) - 2*Y1 * J
453  current.Z = (Z1 + H).squared() - T1 - I; // Z3 = (Z1 + H)^2 - T1 - I
454  current.T = current.Z.squared(); // T3 = Z3^2
455 
456  ac.c_L1 = L1;
457  ac.c_RZ = current.Z;
458 #ifdef DEBUG
459  current.test_invariant();
460 #endif
461 }
462 
464 {
465  enter_block("Call to mnt4_ate_precompute_G1");
466 
467  mnt4_G1 Pcopy = P;
468  Pcopy.to_affine_coordinates();
469 
470  mnt4_ate_G1_precomp result;
471  result.PX = Pcopy.X;
472  result.PY = Pcopy.Y;
473  result.PX_twist = Pcopy.X * mnt4_twist;
474  result.PY_twist = Pcopy.Y * mnt4_twist;
475 
476  leave_block("Call to mnt4_ate_precompute_G1");
477  return result;
478 }
479 
481 {
482  enter_block("Call to mnt4_ate_precompute_G2");
483 
484  mnt4_G2 Qcopy(Q);
485  Qcopy.to_affine_coordinates();
486 
487  mnt4_ate_G2_precomp result;
488  result.QX = Qcopy.X;
489  result.QY = Qcopy.Y;
490  result.QY2 = Qcopy.Y.squared();
491  result.QX_over_twist = Qcopy.X * mnt4_twist.inverse();
492  result.QY_over_twist = Qcopy.Y * mnt4_twist.inverse();
493 
495  R.X = Qcopy.X;
496  R.Y = Qcopy.Y;
497  R.Z = mnt4_Fq2::one();
498  R.T = mnt4_Fq2::one();
499 
501  bool found_one = false;
502 
503  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
504  const bool bit = loop_count.test_bit(i);
505  if (!found_one) {
506  /* this skips the MSB itself */
507  found_one |= bit;
508  continue;
509  }
510 
513  result.dbl_coeffs.push_back(dc);
514  if (bit) {
517  result.QX, result.QY, result.QY2, R, ac);
518  result.add_coeffs.push_back(ac);
519  }
520  }
521 
523  mnt4_Fq2 RZ_inv = R.Z.inverse();
524  mnt4_Fq2 RZ2_inv = RZ_inv.squared();
525  mnt4_Fq2 RZ3_inv = RZ2_inv * RZ_inv;
526  mnt4_Fq2 minus_R_affine_X = R.X * RZ2_inv;
527  mnt4_Fq2 minus_R_affine_Y = -R.Y * RZ3_inv;
528  mnt4_Fq2 minus_R_affine_Y2 = minus_R_affine_Y.squared();
531  minus_R_affine_X, minus_R_affine_Y, minus_R_affine_Y2, R, ac);
532  result.add_coeffs.push_back(ac);
533  }
534 
535  leave_block("Call to mnt4_ate_precompute_G2");
536  return result;
537 }
538 
540  const mnt4_ate_G1_precomp &prec_P, const mnt4_ate_G2_precomp &prec_Q)
541 {
542  enter_block("Call to mnt4_ate_miller_loop");
543 
544  mnt4_Fq2 L1_coeff =
545  mnt4_Fq2(prec_P.PX, mnt4_Fq::zero()) - prec_Q.QX_over_twist;
546 
547  mnt4_Fq4 f = mnt4_Fq4::one();
548 
549  bool found_one = false;
550  size_t dbl_idx = 0;
551  size_t add_idx = 0;
552 
554  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
555  const bool bit = loop_count.test_bit(i);
556 
557  if (!found_one) {
558  /* this skips the MSB itself */
559  found_one |= bit;
560  continue;
561  }
562 
563  /* code below gets executed for all bits (EXCEPT the MSB itself) of
564  mnt4_param_p (skipping leading zeros) in MSB to LSB
565  order */
566  const mnt4_ate_dbl_coeffs &dc = prec_Q.dbl_coeffs[dbl_idx++];
567 
568  const mnt4_Fq4 g_RR_at_P = mnt4_Fq4(
569  -dc.c_4C - dc.c_J * prec_P.PX_twist + dc.c_L,
570  dc.c_H * prec_P.PY_twist);
571  f = f.squared() * g_RR_at_P;
572  if (bit) {
573  const mnt4_ate_add_coeffs &ac = prec_Q.add_coeffs[add_idx++];
574 
575  const mnt4_Fq4 g_RQ_at_P = mnt4_Fq4(
576  ac.c_RZ * prec_P.PY_twist,
577  -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
578  f = f * g_RQ_at_P;
579  }
580  }
581 
583  mnt4_ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
584  mnt4_Fq4 g_RnegR_at_P = mnt4_Fq4(
585  ac.c_RZ * prec_P.PY_twist,
586  -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
587  f = (f * g_RnegR_at_P).inverse();
588  }
589 
590  leave_block("Call to mnt4_ate_miller_loop");
591 
592  return f;
593 }
594 
596  const mnt4_ate_G1_precomp &prec_P1,
597  const mnt4_ate_G2_precomp &prec_Q1,
598  const mnt4_ate_G1_precomp &prec_P2,
599  const mnt4_ate_G2_precomp &prec_Q2)
600 {
601  enter_block("Call to mnt4_ate_double_miller_loop");
602 
603  mnt4_Fq2 L1_coeff1 =
604  mnt4_Fq2(prec_P1.PX, mnt4_Fq::zero()) - prec_Q1.QX_over_twist;
605  mnt4_Fq2 L1_coeff2 =
606  mnt4_Fq2(prec_P2.PX, mnt4_Fq::zero()) - prec_Q2.QX_over_twist;
607 
608  mnt4_Fq4 f = mnt4_Fq4::one();
609 
610  bool found_one = false;
611  size_t dbl_idx = 0;
612  size_t add_idx = 0;
613 
615  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
616  const bool bit = loop_count.test_bit(i);
617 
618  if (!found_one) {
619  /* this skips the MSB itself */
620  found_one |= bit;
621  continue;
622  }
623 
624  /* code below gets executed for all bits (EXCEPT the MSB itself) of
625  mnt4_param_p (skipping leading zeros) in MSB to LSB
626  order */
627  mnt4_ate_dbl_coeffs dc1 = prec_Q1.dbl_coeffs[dbl_idx];
628  mnt4_ate_dbl_coeffs dc2 = prec_Q2.dbl_coeffs[dbl_idx];
629  ++dbl_idx;
630 
631  mnt4_Fq4 g_RR_at_P1 = mnt4_Fq4(
632  -dc1.c_4C - dc1.c_J * prec_P1.PX_twist + dc1.c_L,
633  dc1.c_H * prec_P1.PY_twist);
634 
635  mnt4_Fq4 g_RR_at_P2 = mnt4_Fq4(
636  -dc2.c_4C - dc2.c_J * prec_P2.PX_twist + dc2.c_L,
637  dc2.c_H * prec_P2.PY_twist);
638 
639  f = f.squared() * g_RR_at_P1 * g_RR_at_P2;
640 
641  if (bit) {
642  mnt4_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
643  mnt4_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
644  ++add_idx;
645 
646  mnt4_Fq4 g_RQ_at_P1 = mnt4_Fq4(
647  ac1.c_RZ * prec_P1.PY_twist,
648  -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
649  mnt4_Fq4 g_RQ_at_P2 = mnt4_Fq4(
650  ac2.c_RZ * prec_P2.PY_twist,
651  -(prec_Q2.QY_over_twist * ac2.c_RZ + L1_coeff2 * ac2.c_L1));
652 
653  f = f * g_RQ_at_P1 * g_RQ_at_P2;
654  }
655  }
656 
658  mnt4_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
659  mnt4_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
660  ++add_idx;
661  mnt4_Fq4 g_RnegR_at_P1 = mnt4_Fq4(
662  ac1.c_RZ * prec_P1.PY_twist,
663  -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
664  mnt4_Fq4 g_RnegR_at_P2 = mnt4_Fq4(
665  ac2.c_RZ * prec_P2.PY_twist,
666  -(prec_Q2.QY_over_twist * ac2.c_RZ + L1_coeff2 * ac2.c_L1));
667 
668  f = (f * g_RnegR_at_P1 * g_RnegR_at_P2).inverse();
669  }
670 
671  leave_block("Call to mnt4_ate_double_miller_loop");
672 
673  return f;
674 }
675 
677 {
678  enter_block("Call to mnt4_ate_pairing");
681  mnt4_Fq4 result = mnt4_ate_miller_loop(prec_P, prec_Q);
682  leave_block("Call to mnt4_ate_pairing");
683  return result;
684 }
685 
687 {
688  enter_block("Call to mnt4_ate_reduced_pairing");
689  const mnt4_Fq4 f = mnt4_ate_pairing(P, Q);
690  const mnt4_GT result = mnt4_final_exponentiation(f);
691  leave_block("Call to mnt4_ate_reduced_pairing");
692  return result;
693 }
694 
696 {
697  return mnt4_ate_precompute_G1(P);
698 }
699 
701 {
702  return mnt4_ate_precompute_G2(Q);
703 }
704 
706  const mnt4_G1_precomp &prec_P, const mnt4_G2_precomp &prec_Q)
707 {
708  return mnt4_ate_miller_loop(prec_P, prec_Q);
709 }
710 
712  const mnt4_G1_precomp &prec_P1,
713  const mnt4_G2_precomp &prec_Q1,
714  const mnt4_G1_precomp &prec_P2,
715  const mnt4_G2_precomp &prec_Q2)
716 {
717  return mnt4_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
718 }
719 
721 {
722  return mnt4_ate_pairing(P, Q);
723 }
724 
726 {
727  return mnt4_ate_reduced_pairing(P, Q);
728 }
729 
731 {
732  const mnt4_affine_ate_G1_precomputation prec_P =
734  const mnt4_affine_ate_G2_precomputation prec_Q =
736  const mnt4_Fq4 f = mnt4_affine_ate_miller_loop(prec_P, prec_Q);
737  const mnt4_GT result = mnt4_final_exponentiation(f);
738  return result;
739 }
740 
741 } // namespace libff
libff::mnt4_ate_G2_precomp
Definition: mnt4_pairing.hpp:98
libff::extended_mnt4_G2_projective::test_invariant
void test_invariant() const
Definition: mnt4_pairing.cpp:397
libff::Fp4_model::Frobenius_map
Fp4_model Frobenius_map(unsigned long power) const
libff::mnt4_G2
Definition: mnt4_g2.hpp:26
libff::extended_mnt4_G2_projective::print
void print() const
Definition: mnt4_pairing.cpp:388
libff::mnt4_double_miller_loop
mnt4_Fq4 mnt4_double_miller_loop(const mnt4_G1_precomp &prec_P1, const mnt4_G2_precomp &prec_Q1, const mnt4_G1_precomp &prec_P2, const mnt4_G2_precomp &prec_Q2)
Definition: mnt4_pairing.cpp:711
libff::mnt4_miller_loop
mnt4_Fq4 mnt4_miller_loop(const mnt4_G1_precomp &prec_P, const mnt4_G2_precomp &prec_Q)
Definition: mnt4_pairing.cpp:705
libff::enter_block
void enter_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:271
libff::extended_mnt4_G2_projective::Z
mnt4_Fq2 Z
Definition: mnt4_pairing.cpp:385
libff::mnt4_ate_G1_precomp::operator==
bool operator==(const mnt4_ate_G1_precomp &other) const
Definition: mnt4_pairing.cpp:25
libff::extended_mnt4_G2_projective::X
mnt4_Fq2 X
Definition: mnt4_pairing.cpp:383
libff::mnt4_ate_G1_precomp
Definition: mnt4_pairing.hpp:63
libff::mnt4_G2::X
mnt4_Fq2 X
Definition: mnt4_g2.hpp:51
libff
Definition: ffi.cpp:8
libff::Fp2_model< mnt4_q_limbs, mnt4_modulus_q >::one
static const Fp2_model< n, modulus > & one()
libff::mnt4_G1::Y
mnt4_Fq Y
Definition: mnt4_g1.hpp:49
libff::mnt4_affine_ate_precompute_G1
mnt4_affine_ate_G1_precomputation mnt4_affine_ate_precompute_G1(const mnt4_G1 &P)
Definition: mnt4_pairing.cpp:224
libff::doubling_step_for_flipped_miller_loop
void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
Definition: alt_bn128_pairing.cpp:246
libff::mnt4_twist_coeff_a
mnt4_Fq2 mnt4_twist_coeff_a
Definition: mnt4_init.cpp:25
libff::mnt4_ate_G2_precomp::QY_over_twist
mnt4_Fq2 QY_over_twist
Definition: mnt4_pairing.hpp:103
libff::mnt4_final_exponentiation_last_chunk
mnt4_Fq4 mnt4_final_exponentiation_last_chunk(const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
Definition: mnt4_pairing.cpp:172
libff::mnt4_ate_G1_precomp::PY_twist
mnt4_Fq2 PY_twist
Definition: mnt4_pairing.hpp:67
libff::Fp_model< mnt4_q_limbs, mnt4_modulus_q >::zero
static const Fp_model< n, modulus > & zero()
libff::mnt4_ate_dbl_coeffs::c_L
mnt4_Fq2 c_L
Definition: mnt4_pairing.hpp:80
libff::mnt4_ate_reduced_pairing
mnt4_GT mnt4_ate_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:686
libff::mnt4_ate_precompute_G2
mnt4_ate_G2_precomp mnt4_ate_precompute_G2(const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:480
libff::mnt4_ate_G1_precomp::PX
mnt4_Fq PX
Definition: mnt4_pairing.hpp:64
libff::operator>>
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:446
libff::Fp4_model::cyclotomic_exp
Fp4_model cyclotomic_exp(const bigint< m > &exponent) const
libff::mnt4_ate_dbl_coeffs
Definition: mnt4_pairing.hpp:76
libff::mnt4_ate_dbl_coeffs::c_H
mnt4_Fq2 c_H
Definition: mnt4_pairing.hpp:77
libff::mixed_addition_step_for_flipped_miller_loop
void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
Definition: alt_bn128_pairing.cpp:290
libff::mnt4_G1
Definition: mnt4_g1.hpp:26
libff::Fp4_model::inverse
Fp4_model inverse() const
libff::mnt4_affine_ate_G1_precomputation::PX
mnt4_Fq PX
Definition: mnt4_pairing.hpp:32
libff::mnt4_final_exponent_last_chunk_abs_of_w0
bigint< mnt4_q_limbs > mnt4_final_exponent_last_chunk_abs_of_w0
Definition: mnt4_init.cpp:37
libff::mnt4_ate_dbl_coeffs::c_J
mnt4_Fq2 c_J
Definition: mnt4_pairing.hpp:79
libff::mnt4_affine_ate_G1_precomputation::PY
mnt4_Fq PY
Definition: mnt4_pairing.hpp:33
libff::extended_mnt4_G2_projective::T
mnt4_Fq2 T
Definition: mnt4_pairing.cpp:386
libff::mnt4_affine_ate_coeffs::gamma_twist
mnt4_Fq2 gamma_twist
Definition: mnt4_pairing.hpp:42
libff::Fp2_model::inverse
Fp2_model inverse() const
libff::mnt4_reduced_pairing
mnt4_GT mnt4_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:725
libff::mnt4_ate_add_coeffs::c_L1
mnt4_Fq2 c_L1
Definition: mnt4_pairing.hpp:89
libff::mnt4_Fq
Fp_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq
Definition: mnt4_init.hpp:37
libff::mnt4_ate_G2_precomp::QX_over_twist
mnt4_Fq2 QX_over_twist
Definition: mnt4_pairing.hpp:102
OUTPUT_SEPARATOR
#define OUTPUT_SEPARATOR
Definition: serialization.hpp:69
libff::mnt4_ate_add_coeffs::c_RZ
mnt4_Fq2 c_RZ
Definition: mnt4_pairing.hpp:90
mnt4_pairing.hpp
libff::bigint::max_bits
static constexpr size_t max_bits()
The number of bits representable by this bigint type.
Definition: bigint.hpp:51
libff::mnt4_precompute_G1
mnt4_G1_precomp mnt4_precompute_G1(const mnt4_G1 &P)
Definition: mnt4_pairing.cpp:695
libff::mnt4_ate_G2_precomp::operator==
bool operator==(const mnt4_ate_G2_precomp &other) const
Definition: mnt4_pairing.cpp:99
libff::mnt4_G2::to_affine_coordinates
void to_affine_coordinates()
Definition: mnt4_g2.cpp:96
libff::mnt4_affine_ate_coeffs::gamma_X
mnt4_Fq2 gamma_X
Definition: mnt4_pairing.hpp:43
libff::mnt4_affine_ate_coeffs::old_RY
mnt4_Fq2 old_RY
Definition: mnt4_pairing.hpp:40
libff::mnt4_pairing
mnt4_Fq4 mnt4_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:720
libff::mnt4_ate_G2_precomp::QY2
mnt4_Fq2 QY2
Definition: mnt4_pairing.hpp:101
libff::Fp4_model
Definition: fp4.hpp:26
libff::consume_OUTPUT_SEPARATOR
void consume_OUTPUT_SEPARATOR(std::istream &in)
libff::mnt4_affine_ate_precompute_G2
mnt4_affine_ate_G2_precomputation mnt4_affine_ate_precompute_G2(const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:241
libff::mnt4_ate_pairing
mnt4_Fq4 mnt4_ate_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:676
libff::mnt4_ate_add_coeffs
Definition: mnt4_pairing.hpp:88
libff::bigint
Definition: bigint.hpp:20
libff::mnt4_Fq2
Fp2_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq2
Definition: mnt4_init.hpp:38
libff::mnt4_final_exponentiation_first_chunk
mnt4_Fq4 mnt4_final_exponentiation_first_chunk(const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
Definition: mnt4_pairing.cpp:191
libff::mnt4_ate_double_miller_loop
mnt4_Fq4 mnt4_ate_double_miller_loop(const mnt4_ate_G1_precomp &prec_P1, const mnt4_ate_G2_precomp &prec_Q1, const mnt4_ate_G1_precomp &prec_P2, const mnt4_ate_G2_precomp &prec_Q2)
Definition: mnt4_pairing.cpp:595
libff::mnt4_ate_dbl_coeffs::operator==
bool operator==(const mnt4_ate_dbl_coeffs &other) const
Definition: mnt4_pairing.cpp:53
libff::Fp4_model::mul_by_023
Fp4_model mul_by_023(const Fp4_model &other) const
libff::mnt4_affine_ate_G2_precomputation::QY
mnt4_Fq2 QY
Definition: mnt4_pairing.hpp:48
libff::mnt4_ate_G1_precomp::PX_twist
mnt4_Fq2 PX_twist
Definition: mnt4_pairing.hpp:66
mnt4_init.hpp
libff::mnt4_ate_G1_precomp::PY
mnt4_Fq PY
Definition: mnt4_pairing.hpp:65
libff::mnt4_affine_ate_G2_precomputation::QX
mnt4_Fq2 QX
Definition: mnt4_pairing.hpp:47
libff::mnt4_ate_G2_precomp::QX
mnt4_Fq2 QX
Definition: mnt4_pairing.hpp:99
libff::mnt4_ate_G2_precomp::add_coeffs
std::vector< mnt4_ate_add_coeffs > add_coeffs
Definition: mnt4_pairing.hpp:105
libff::mnt4_ate_dbl_coeffs::c_4C
mnt4_Fq2 c_4C
Definition: mnt4_pairing.hpp:78
libff::mnt4_precompute_G2
mnt4_G2_precomp mnt4_precompute_G2(const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:700
libff::mnt4_affine_ate_coeffs
Definition: mnt4_pairing.hpp:37
libff::mnt4_ate_loop_count
bigint< mnt4_q_limbs > mnt4_ate_loop_count
Definition: mnt4_init.cpp:34
mnt4_g2.hpp
libff::mnt4_affine_ate_G1_precomputation
Definition: mnt4_pairing.hpp:31
libff::mnt4_ate_is_loop_count_neg
bool mnt4_ate_is_loop_count_neg
Definition: mnt4_init.cpp:35
libff::operator<<
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:436
libff::consume_OUTPUT_NEWLINE
void consume_OUTPUT_NEWLINE(std::istream &in)
libff::extended_mnt4_G2_projective
Definition: mnt4_pairing.cpp:382
libff::find_wnaf
std::vector< long > find_wnaf(const size_t window_size, const bigint< n > &scalar)
libff::mnt4_Fq4
Fp4_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq4
Definition: mnt4_init.hpp:39
libff::mnt4_final_exponent_last_chunk_is_w0_neg
bool mnt4_final_exponent_last_chunk_is_w0_neg
Definition: mnt4_init.cpp:38
libff::Fp2_model< mnt4_q_limbs, mnt4_modulus_q >
libff::Fp2_model::squared
Fp2_model squared() const
default is squared_complex
libff::Fp2_model::print
void print() const
Definition: fp2.hpp:78
profiling.hpp
wnaf.hpp
libff::mnt4_affine_ate_coeffs::old_RX
mnt4_Fq2 old_RX
Definition: mnt4_pairing.hpp:39
libff::mnt4_final_exponent_last_chunk_w1
bigint< mnt4_q_limbs > mnt4_final_exponent_last_chunk_w1
Definition: mnt4_init.cpp:39
libff::mnt4_affine_ate_coeffs::gamma
mnt4_Fq2 gamma
Definition: mnt4_pairing.hpp:41
libff::mnt4_ate_G2_precomp::QY
mnt4_Fq2 QY
Definition: mnt4_pairing.hpp:100
libff::leave_block
void leave_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:305
libff::mnt4_G2::Y
mnt4_Fq2 Y
Definition: mnt4_g2.hpp:51
libff::Fp4_model::squared
Fp4_model squared() const
OUTPUT_NEWLINE
#define OUTPUT_NEWLINE
Definition: serialization.hpp:68
libff::mnt4_G1::to_affine_coordinates
void to_affine_coordinates()
Definition: mnt4_g1.cpp:71
libff::bigint::test_bit
bool test_bit(const std::size_t bitno) const
libff::mnt4_G1::X
mnt4_Fq X
Definition: mnt4_g1.hpp:49
libff::mnt4_final_exponentiation
mnt4_GT mnt4_final_exponentiation(const mnt4_Fq4 &elt)
Definition: mnt4_pairing.cpp:207
libff::mnt4_affine_ate_miller_loop
mnt4_Fq4 mnt4_affine_ate_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P, const mnt4_affine_ate_G2_precomputation &prec_Q)
Definition: mnt4_pairing.cpp:318
libff::mnt4_affine_ate_G2_precomputation
Definition: mnt4_pairing.hpp:46
libff::mnt4_affine_ate_G2_precomputation::coeffs
std::vector< mnt4_affine_ate_coeffs > coeffs
Definition: mnt4_pairing.hpp:49
libff::mnt4_twist
mnt4_Fq2 mnt4_twist
Definition: mnt4_init.cpp:24
libff::consume_newline
void consume_newline(std::istream &in)
libff::mnt4_ate_add_coeffs::operator==
bool operator==(const mnt4_ate_add_coeffs &other) const
Definition: mnt4_pairing.cpp:80
libff::extended_mnt4_G2_projective::Y
mnt4_Fq2 Y
Definition: mnt4_pairing.cpp:384
libff::mnt4_ate_G2_precomp::dbl_coeffs
std::vector< mnt4_ate_dbl_coeffs > dbl_coeffs
Definition: mnt4_pairing.hpp:104
mnt4_g1.hpp
libff::Fp4_model::one
static Fp4_model< n, modulus > one()
libff::mnt4_ate_miller_loop
mnt4_Fq4 mnt4_ate_miller_loop(const mnt4_ate_G1_precomp &prec_P, const mnt4_ate_G2_precomp &prec_Q)
Definition: mnt4_pairing.cpp:539
libff::mnt4_ate_precompute_G1
mnt4_ate_G1_precomp mnt4_ate_precompute_G1(const mnt4_G1 &P)
Definition: mnt4_pairing.cpp:463
libff::mnt4_affine_ate_G1_precomputation::PY_twist_squared
mnt4_Fq2 PY_twist_squared
Definition: mnt4_pairing.hpp:34
libff::mnt4_affine_reduced_pairing
mnt4_GT mnt4_affine_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
Definition: mnt4_pairing.cpp:730