Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
bw6_761_pairing.cpp
Go to the documentation of this file.
1 #include <cassert>
7 
8 namespace libff
9 {
10 
12  const bw6_761_ate_G1_precomp &other) const
13 {
14  return (this->PX == other.PX && this->PY == other.PY);
15 }
16 
17 std::ostream &operator<<(
18  std::ostream &out, const bw6_761_ate_G1_precomp &prec_P)
19 {
20  out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY;
21 
22  return out;
23 }
24 
25 std::istream &operator>>(std::istream &in, bw6_761_ate_G1_precomp &prec_P)
26 {
27  in >> prec_P.PX;
29  in >> prec_P.PY;
30 
31  return in;
32 }
33 
35  const bw6_761_ate_ell_coeffs &other) const
36 {
37  return (
38  this->ell_0 == other.ell_0 && this->ell_VW == other.ell_VW &&
39  this->ell_VV == other.ell_VV);
40 }
41 
42 std::ostream &operator<<(std::ostream &out, const bw6_761_ate_ell_coeffs &c)
43 {
44  out << c.ell_0 << OUTPUT_SEPARATOR << c.ell_VW << OUTPUT_SEPARATOR
45  << c.ell_VV;
46  return out;
47 }
48 
49 std::istream &operator>>(std::istream &in, bw6_761_ate_ell_coeffs &c)
50 {
51  in >> c.ell_0;
53  in >> c.ell_VW;
55  in >> c.ell_VV;
56 
57  return in;
58 }
59 
61  const bw6_761_ate_G2_precomp_iteration &other) const
62 {
63  return (
64  this->QX == other.QX && this->QY == other.QY &&
65  this->coeffs == other.coeffs);
66 }
67 
68 std::ostream &operator<<(
69  std::ostream &out, const bw6_761_ate_G2_precomp_iteration &prec_Q)
70 {
71  out << prec_Q.QX << OUTPUT_SEPARATOR << prec_Q.QY << "\n";
72  out << prec_Q.coeffs.size() << "\n";
73  for (const bw6_761_ate_ell_coeffs &c : prec_Q.coeffs) {
74  out << c << OUTPUT_NEWLINE;
75  }
76  return out;
77 }
78 
79 std::istream &operator>>(
80  std::istream &in, bw6_761_ate_G2_precomp_iteration &prec_Q)
81 {
82  in >> prec_Q.QX;
84  in >> prec_Q.QY;
85  consume_newline(in);
86 
87  prec_Q.coeffs.clear();
88  size_t s;
89  in >> s;
90 
91  consume_newline(in);
92 
93  prec_Q.coeffs.reserve(s);
94 
95  for (size_t i = 0; i < s; ++i) {
97  in >> c;
99  prec_Q.coeffs.emplace_back(c);
100  }
101 
102  return in;
103 }
104 
106  const bw6_761_ate_G2_precomp &other) const
107 {
108  return (
109  this->precomp_1 == other.precomp_1 &&
110  this->precomp_2 == other.precomp_2);
111 }
112 
113 std::ostream &operator<<(
114  std::ostream &out, const bw6_761_ate_G2_precomp &prec_Q)
115 {
116  out << prec_Q.precomp_1 << OUTPUT_SEPARATOR << prec_Q.precomp_2 << "\n";
117  return out;
118 }
119 
120 std::istream &operator>>(std::istream &in, bw6_761_ate_G2_precomp &prec_Q)
121 {
122  in >> prec_Q.precomp_1;
124  in >> prec_Q.precomp_2;
125  consume_newline(in);
126  return in;
127 }
128 
129 // Below is the code related to the final exponentiation
130 
132 {
133  // Compute elt^{(q^3-1)*(q+1)}
134  enter_block("Call to bw6_761_final_exponentiation_first_chunk");
135 
136  // A = elt^(q^3)
137  const bw6_761_Fq6 A = elt.Frobenius_map(3);
138  // B = elt^(q^3-1)
139  const bw6_761_Fq6 elt_inv = elt.inverse();
140  const bw6_761_Fq6 B = A * elt_inv;
141  // D = elt^((q^3-1) * q)
142  const bw6_761_Fq6 D = B.Frobenius_map(1);
143  // result = elt^{(q^3-1)*(q+1)}
144  const bw6_761_Fq6 result = D * B;
145 
146  leave_block("Call to bw6_761_final_exponentiation_first_chunk");
147  return result;
148 }
149 
151 {
152  enter_block("Call to bw6_761_exp_by_z");
153 
156  result = result.unitary_inverse();
157  }
158 
159  leave_block("Call to bw6_761_exp_by_z");
160 
161  return result;
162 }
163 
164 // See Algorithm 6, Appendix B: https://eprint.iacr.org/2020/351.pdf
165 // This function computes:
166 // elt^{σ′(u)}, where σ′(u) = R_0(u) + q*R_1(u)
167 // and where:
168 // - R0(x) := (-103*x^7 + 70*x^6 + 269*x^5 - 197*x^4 - 314*x^3 - 73*x^2 - 263*x
169 // - 220)
170 // - R1(x) := (103*x^9 - 276*x^8 + 77*x^7 + 492*x^6 - 445*x^5 - 65*x^4 +
171 // 452*x^3 - 181*x^2 + 34*x + 229)
173 {
174  enter_block("Call to bw6_761_final_exponentiation_last_chunk");
175 
176  // Step 1
177  const bw6_761_Fq6 f0 = elt;
178  const bw6_761_Fq6 f0p = f0.Frobenius_map(1);
179 
180  // Step 2-3: For loop
181  const bw6_761_Fq6 f1 = bw6_761_exp_by_z(f0);
182  const bw6_761_Fq6 f1p = f1.Frobenius_map(1);
183  const bw6_761_Fq6 f2 = bw6_761_exp_by_z(f1);
184  const bw6_761_Fq6 f2p = f2.Frobenius_map(1);
185  const bw6_761_Fq6 f3 = bw6_761_exp_by_z(f2);
186  const bw6_761_Fq6 f3p = f3.Frobenius_map(1);
187  const bw6_761_Fq6 f4 = bw6_761_exp_by_z(f3);
188  const bw6_761_Fq6 f4p = f4.Frobenius_map(1);
189  const bw6_761_Fq6 f5 = bw6_761_exp_by_z(f4);
190  const bw6_761_Fq6 f5p = f5.Frobenius_map(1);
191  const bw6_761_Fq6 f6 = bw6_761_exp_by_z(f5);
192  const bw6_761_Fq6 f6p = f6.Frobenius_map(1);
193  const bw6_761_Fq6 f7 = bw6_761_exp_by_z(f6);
194  const bw6_761_Fq6 f7p = f7.Frobenius_map(1);
195 
196  // Step 4
197  const bw6_761_Fq6 f8p = bw6_761_exp_by_z(f7p);
198  const bw6_761_Fq6 f9p = bw6_761_exp_by_z(f8p);
199 
200  // Step 5
201  const bw6_761_Fq6 result1 = f3p * f6p * f5p.Frobenius_map(3);
202 
203  // Step 6
204  const bw6_761_Fq6 result2 = result1.squared();
205  const bw6_761_Fq6 f4_2p = f4 * f2p;
206  const bw6_761_Fq6 result3 =
207  result2 * f5 * f0p * (f0 * f1 * f3 * f4_2p * f8p).Frobenius_map(3);
208 
209  // Step 7
210  const bw6_761_Fq6 result4 = result3.squared();
211  const bw6_761_Fq6 result5 = result4 * f9p * f7.Frobenius_map(3);
212 
213  // Step 8
214  const bw6_761_Fq6 result6 = result5.squared();
215  const bw6_761_Fq6 f2_4p = f2 * f4p;
216  const bw6_761_Fq6 f4_2p_5p = f4_2p * f5p;
217  const bw6_761_Fq6 result7 =
218  result6 * f4_2p_5p * f6 * f7p * (f2_4p * f3 * f3p).Frobenius_map(3);
219 
220  // Step 9
221  const bw6_761_Fq6 result8 = result7.squared();
222  const bw6_761_Fq6 result9 =
223  result8 * f0 * f7 * f1p * (f0p * f9p).Frobenius_map(3);
224 
225  // Step 10
226  const bw6_761_Fq6 result10 = result9.squared();
227  const bw6_761_Fq6 f6p_8p = f6p * f8p;
228  const bw6_761_Fq6 f5_7p = f5 * f7p;
229  const bw6_761_Fq6 result11 =
230  result10 * f5_7p * f2p * (f6p_8p).Frobenius_map(3);
231 
232  // Step 11
233  const bw6_761_Fq6 result12 = result11.squared();
234  const bw6_761_Fq6 f3_6 = f3 * f6;
235  const bw6_761_Fq6 f1_7 = f1 * f7;
236  const bw6_761_Fq6 result13 =
237  result12 * f3_6 * f9p * (f1_7 * f2).Frobenius_map(3);
238 
239  // Step 12
240  const bw6_761_Fq6 result14 = result13.squared();
241  const bw6_761_Fq6 result15 = result14 * f0 * f0p * f3p * f5p *
242  (f4_2p * f5_7p * f6p_8p).Frobenius_map(3);
243 
244  // Step 13
245  const bw6_761_Fq6 result16 = result15.squared();
246  const bw6_761_Fq6 result17 = result16 * f1p * (f3_6).Frobenius_map(3);
247 
248  // Step 14
249  const bw6_761_Fq6 result18 = result17.squared();
250  const bw6_761_Fq6 result19 = result18 * f1_7 * f5_7p * f0p *
251  (f2_4p * f4_2p_5p * f9p).Frobenius_map(3);
252 
253  leave_block("Call to bw6_761_final_exponentiation_last_chunk");
254 
255  return result19;
256 }
257 
259 {
260  enter_block("Call to bw6_761_final_exponentiation");
261 
262  bw6_761_Fq6 elt_to_first_chunk =
264  bw6_761_GT result =
265  bw6_761_final_exponentiation_last_chunk(elt_to_first_chunk);
266 
267  leave_block("Call to bw6_761_final_exponentiation");
268 
269  return result;
270 }
271 
272 // Below is the code related to the computation of the Ate pairing
273 
275  bw6_761_G2 &current, bw6_761_ate_ell_coeffs &c)
276 {
277  const bw6_761_Fq X = current.X, Y = current.Y, Z = current.Z;
278 
279  // A = X1 * Y1
280  const bw6_761_Fq A = X * Y;
281  // B = Y1^2
282  const bw6_761_Fq B = Y.squared();
283  // B4 = 4 * Y1^2
284  const bw6_761_Fq B4 = B + B + B + B;
285  // C = Z1^2
286  const bw6_761_Fq C = Z.squared();
287  // D = 3 * C
288  const bw6_761_Fq D = C + C + C;
289  // E = bw6_761_twist_coeff_b * D
290  const bw6_761_Fq E = bw6_761_twist_coeff_b * D;
291  // F = 3 * E
292  const bw6_761_Fq F = E + E + E;
293  // G = B+F
294  const bw6_761_Fq G = B + F;
295  // H = (Y1+Z1)^2-(B+C)
296  const bw6_761_Fq H = (Y + Z).squared() - (B + C);
297  // I = E-B
298  const bw6_761_Fq I = E - B;
299  // J = X1^2
300  const bw6_761_Fq J = X.squared();
301  // E2_squared = (2E)^2
302  const bw6_761_Fq E2_squared = (E + E).squared();
303 
304  // X3 = 2A * (B-F)
305  current.X = (A + A) * (B - F);
306  // Y3 = G^2 - 3*E2^2
307  current.Y = G.squared() - (E2_squared + E2_squared + E2_squared);
308  // Z3 = 4 * B * H
309  current.Z = B4 * H;
310 
311  // ell_0 = I
312  c.ell_0 = I;
313  // ell_VW = -xi * H (later: * yP)
314  c.ell_VW = -bw6_761_twist * H;
315  // ell_VV = 3*J (later: * xP)
316  c.ell_VV = J + J + J;
317 }
318 
320  const bw6_761_G2 base, bw6_761_G2 &current, bw6_761_ate_ell_coeffs &c)
321 {
322  const bw6_761_Fq X1 = current.X, Y1 = current.Y, Z1 = current.Z;
323  const bw6_761_Fq &X2 = base.X, &Y2 = base.Y;
324 
325  // D = X1 - X2*Z1
326  const bw6_761_Fq D = X1 - X2 * Z1;
327  // E = Y1 - Y2*Z1
328  const bw6_761_Fq E = Y1 - Y2 * Z1;
329  // F = D^2
330  const bw6_761_Fq F = D.squared();
331  // G = E^2
332  const bw6_761_Fq G = E.squared();
333  // H = D*F
334  const bw6_761_Fq H = D * F;
335  // I = X1 * F
336  const bw6_761_Fq I = X1 * F;
337  // J = H + Z1*G - (I+I)
338  const bw6_761_Fq J = H + Z1 * G - (I + I);
339 
340  // X3 = D*J
341  current.X = D * J;
342  // Y3 = E*(I-J)-(H*Y1)
343  current.Y = E * (I - J) - (H * Y1);
344  // Z3 = Z1*H
345  current.Z = Z1 * H;
346 
347  c.ell_0 = E * X2 - D * Y2;
348  // VV gets multiplied to xP during line evaluation at P
349  c.ell_VV = -E;
350  // VW gets multiplied to yP during line evaluation at P
351  c.ell_VW = bw6_761_twist * D;
352 }
353 
355 {
356  enter_block("Call to bw6_761_ate_precompute_G1");
357 
358  bw6_761_G1 Pcopy = P;
359  Pcopy.to_affine_coordinates();
360 
361  bw6_761_ate_G1_precomp result;
362  result.PX = Pcopy.X;
363  result.PY = Pcopy.Y;
364 
365  leave_block("Call to bw6_761_ate_precompute_G1");
366  return result;
367 }
368 
369 static bw6_761_ate_G2_precomp_iteration bw6_761_ate_precompute_G2_internal(
370  const bw6_761_G2 &Q, const bigint<bw6_761_Fq::num_limbs> &loop_count)
371 {
372  enter_block("Call to bw6_761_ate_precompute_G2");
373 
374  bw6_761_G2 Qcopy(Q);
375  Qcopy.to_affine_coordinates();
376 
377  bw6_761_ate_G2_precomp_iteration result;
378  result.QX = Qcopy.X;
379  result.QY = Qcopy.Y;
380 
381  bw6_761_G2 R;
382  R.X = Qcopy.X;
383  R.Y = Qcopy.Y;
384  R.Z = bw6_761_Fq::one();
385 
386  bool found_nonzero = false;
387  bw6_761_ate_ell_coeffs c;
388 
389  std::vector<long> NAF = find_wnaf(1, loop_count);
390  for (long i = NAF.size() - 1; i >= 0; --i) {
391  if (!found_nonzero) {
392  // This skips the MSB itself
393  found_nonzero |= (NAF[i] != 0);
394  continue;
395  }
396 
398  result.coeffs.push_back(c);
399 
400  if (NAF[i] != 0) {
401  if (NAF[i] > 0) {
403  } else {
405  }
406  result.coeffs.push_back(c);
407  }
408  }
409 
410  leave_block("Call to bw6_761_ate_precompute_G2");
411  return result;
412 }
413 
415 {
416  return {
417  bw6_761_ate_precompute_G2_internal(Q, bw6_761_ate_loop_count1),
418  bw6_761_ate_precompute_G2_internal(Q, bw6_761_ate_loop_count2),
419  };
420 }
421 
422 // https://gitlab.inria.fr/zk-curves/bw6-761/-/blob/master/sage/pairing.py#L344
424  const bw6_761_ate_G1_precomp &prec_P, const bw6_761_ate_G2_precomp &prec_Q)
425 {
426  enter_block("Call to bw6_761_ate_miller_loop");
427 
428  const bw6_761_ate_G2_precomp_iteration &prec_Q_1 = prec_Q.precomp_1;
429  const bw6_761_ate_G2_precomp_iteration &prec_Q_2 = prec_Q.precomp_2;
430 
431  // f_{u+1,Q}(P)
433 
434  bool found_nonzero_1 = false;
435  size_t idx_1 = 0;
436 
439 
440  // Get the Non-Adjacent Form of the loop count
441  // loop_count_1 = u+1
442  // This allows to cover steps 2 to 11 Algorithm 5:
443  // https://eprint.iacr.org/2020/351.pdf
444  std::vector<long> NAF_1 = find_wnaf(1, loop_count_1);
445  for (long i = NAF_1.size() - 1; i >= 0; --i) {
446  if (!found_nonzero_1) {
447  // This skips the MSB itself
448  found_nonzero_1 |= (NAF_1[i] != 0);
449  continue;
450  }
451 
452  // The code below gets executed for all bits (EXCEPT the MSB itself) of
453  // bw6_761_param_p (skipping leading zeros) in MSB to LSB
454  // order
455  c_1 = prec_Q_1.coeffs[idx_1];
456  ++idx_1;
457  f_1 = f_1.squared();
458  f_1 = f_1.mul_by_045(
459  c_1.ell_0, prec_P.PY * c_1.ell_VW, prec_P.PX * c_1.ell_VV);
460 
461  if (NAF_1[i] != 0) {
462  c_1 = prec_Q_1.coeffs[idx_1];
463  ++idx_1;
464  f_1 = f_1.mul_by_045(
465  c_1.ell_0, prec_P.PY * c_1.ell_VW, prec_P.PX * c_1.ell_VV);
466  }
467  }
468 
469  // f_{u^3-u^2-u,Q}(P)
471 
472  bool found_nonzero_2 = false;
473  size_t idx_2 = 0;
474 
477 
478  std::vector<long> NAF_2 = find_wnaf(1, loop_count_2);
479  for (long i = NAF_2.size() - 1; i >= 0; --i) {
480  if (!found_nonzero_2) {
481  // This skips the MSB itself
482  found_nonzero_2 |= (NAF_2[i] != 0);
483  continue;
484  }
485 
486  // The code below gets executed for all bits (EXCEPT the MSB itself) of
487  // bw6_761_param_p (skipping leading zeros) in MSB to LSB
488  // order
489  c_2 = prec_Q_2.coeffs[idx_2++];
490  f_2 = f_2.squared();
491  f_2 = f_2.mul_by_045(
492  c_2.ell_0, prec_P.PY * c_2.ell_VW, prec_P.PX * c_2.ell_VV);
493 
494  if (NAF_2[i] != 0) {
495  c_2 = prec_Q_2.coeffs[idx_2++];
496  f_2 = f_2.mul_by_045(
497  c_2.ell_0, prec_P.PY * c_2.ell_VW, prec_P.PX * c_2.ell_VV);
498  }
499  }
500 
501  leave_block("Call to bw6_761_ate_miller_loop");
502 
503  f_2 = f_2.Frobenius_map(1);
504 
505  return f_1 * f_2;
506 }
507 
509  const bw6_761_ate_G1_precomp &prec_P1,
510  const bw6_761_ate_G2_precomp &prec_Q1,
511  const bw6_761_ate_G1_precomp &prec_P2,
512  const bw6_761_ate_G2_precomp &prec_Q2)
513 {
514  enter_block("Call to bw6_761_ate_double_miller_loop");
515 
516  const bw6_761_ate_G2_precomp_iteration &prec_Q1_1 = prec_Q1.precomp_1;
517  const bw6_761_ate_G2_precomp_iteration &prec_Q2_1 = prec_Q1.precomp_2;
518  const bw6_761_ate_G2_precomp_iteration &prec_Q1_2 = prec_Q2.precomp_1;
519  const bw6_761_ate_G2_precomp_iteration &prec_Q2_2 = prec_Q2.precomp_2;
520 
521  // f_{u+1,Q}(P)
523 
524  bool found_nonzero_1 = false;
525  size_t idx_1 = 0;
526 
529 
531  // Get the Non-Adjacent Form of the 1st loop count
532  std::vector<long> NAF_1 = find_wnaf(1, loop_count_1);
533  for (long i = NAF_1.size() - 1; i >= 0; --i) {
534  if (!found_nonzero_1) {
535  // This skips the MSB itself
536  found_nonzero_1 |= (NAF_1[i] != 0);
537  continue;
538  }
539 
540  // The code below gets executed for all bits (EXCEPT the MSB itself) of
541  // bw6_761_param_p (skipping leading zeros) in MSB to LSB
542  // order
543  c_1_1 = prec_Q1_1.coeffs[idx_1];
544  c_1_2 = prec_Q1_2.coeffs[idx_1];
545  ++idx_1;
546 
547  f_1 = f_1.squared();
548  f_1 = f_1.mul_by_045(
549  c_1_1.ell_0, prec_P1.PY * c_1_1.ell_VW, prec_P1.PX * c_1_1.ell_VV);
550  f_1 = f_1.mul_by_045(
551  c_1_2.ell_0, prec_P2.PY * c_1_2.ell_VW, prec_P2.PX * c_1_2.ell_VV);
552 
553  if (NAF_1[i] != 0) {
554  c_1_1 = prec_Q1_1.coeffs[idx_1];
555  c_1_2 = prec_Q1_2.coeffs[idx_1];
556  ++idx_1;
557 
558  f_1 = f_1.mul_by_045(
559  c_1_1.ell_0,
560  prec_P1.PY * c_1_1.ell_VW,
561  prec_P1.PX * c_1_1.ell_VV);
562  f_1 = f_1.mul_by_045(
563  c_1_2.ell_0,
564  prec_P2.PY * c_1_2.ell_VW,
565  prec_P2.PX * c_1_2.ell_VV);
566  }
567  }
568 
569  // f_{u^3-u^2-u,Q}(P)
571 
572  bool found_nonzero_2 = false;
573  size_t idx_2 = 0;
574 
577 
579  // Get the Non-Adjacent Form of the 1st loop count
580  std::vector<long> NAF_2 = find_wnaf(1, loop_count_2);
581  for (long i = NAF_2.size() - 1; i >= 0; --i) {
582  if (!found_nonzero_2) {
583  // This skips the MSB itself
584  found_nonzero_2 |= (NAF_2[i] != 0);
585  continue;
586  }
587 
588  // The code below gets executed for all bits (EXCEPT the MSB itself) of
589  // bw6_761_param_p (skipping leading zeros) in MSB to LSB
590  // order
591  c_2_1 = prec_Q2_1.coeffs[idx_2];
592  c_2_2 = prec_Q2_2.coeffs[idx_2];
593  ++idx_2;
594 
595  f_2 = f_2.squared();
596 
597  f_2 = f_2.mul_by_045(
598  c_2_1.ell_0, prec_P1.PY * c_2_1.ell_VW, prec_P1.PX * c_2_1.ell_VV);
599  f_2 = f_2.mul_by_045(
600  c_2_2.ell_0, prec_P2.PY * c_2_2.ell_VW, prec_P2.PX * c_2_2.ell_VV);
601 
602  if (NAF_2[i] != 0) {
603  c_2_1 = prec_Q2_1.coeffs[idx_2];
604  c_2_2 = prec_Q2_2.coeffs[idx_2];
605  ++idx_2;
606 
607  f_2 = f_2.mul_by_045(
608  c_2_1.ell_0,
609  prec_P1.PY * c_2_1.ell_VW,
610  prec_P1.PX * c_2_1.ell_VV);
611  f_2 = f_2.mul_by_045(
612  c_2_2.ell_0,
613  prec_P2.PY * c_2_2.ell_VW,
614  prec_P2.PX * c_2_2.ell_VV);
615  }
616  }
617 
618  leave_block("Call to bw6_761_ate_double_miller_loop");
619 
620  f_2 = f_2.Frobenius_map(1);
621 
622  return f_1 * f_2;
623 }
624 
626 {
627  enter_block("Call to bw6_761_ate_pairing");
630  bw6_761_Fq6 result = bw6_761_ate_miller_loop(prec_P, prec_Q);
631  leave_block("Call to bw6_761_ate_pairing");
632  return result;
633 }
634 
636 {
637  enter_block("Call to bw6_761_ate_reduced_pairing");
638  const bw6_761_Fq6 f = bw6_761_ate_pairing(P, Q);
639  const bw6_761_GT result = bw6_761_final_exponentiation(f);
640  leave_block("Call to bw6_761_ate_reduced_pairing");
641  return result;
642 }
643 
644 // Choice of pairing
645 
647 {
648  return bw6_761_ate_precompute_G1(P);
649 }
650 
652 {
653  return bw6_761_ate_precompute_G2(Q);
654 }
655 
657  const bw6_761_G1_precomp &prec_P, const bw6_761_G2_precomp &prec_Q)
658 {
659  return bw6_761_ate_miller_loop(prec_P, prec_Q);
660 }
661 
663  const bw6_761_ate_G1_precomp &prec_P1,
664  const bw6_761_ate_G2_precomp &prec_Q1,
665  const bw6_761_ate_G1_precomp &prec_P2,
666  const bw6_761_ate_G2_precomp &prec_Q2)
667 {
668  return bw6_761_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
669 }
670 
672 {
673  return bw6_761_ate_pairing(P, Q);
674 }
675 
677 {
678  return bw6_761_ate_reduced_pairing(P, Q);
679 }
680 
681 } // namespace libff
libff::Fp6_2over3_model::one
static Fp6_2over3_model< n, modulus > one()
libff::bw6_761_ate_G2_precomp_iteration
Definition: bw6_761_pairing.hpp:39
libff::bw6_761_reduced_pairing
bw6_761_GT bw6_761_reduced_pairing(const bw6_761_G1 &P, const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:676
libff::bw6_761_ate_G2_precomp
Definition: bw6_761_pairing.hpp:51
libff::bw6_761_ate_ell_coeffs::operator==
bool operator==(const bw6_761_ate_ell_coeffs &other) const
Definition: bw6_761_pairing.cpp:34
libff::bw6_761_twist
bw6_761_Fq bw6_761_twist
Definition: bw6_761_init.cpp:18
libff::enter_block
void enter_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:271
libff::bw6_761_final_exponentiation_first_chunk
bw6_761_Fq6 bw6_761_final_exponentiation_first_chunk(const bw6_761_Fq6 &elt)
Definition: bw6_761_pairing.cpp:131
libff::bw6_761_miller_loop
bw6_761_Fq6 bw6_761_miller_loop(const bw6_761_G1_precomp &prec_P, const bw6_761_G2_precomp &prec_Q)
Definition: bw6_761_pairing.cpp:656
libff::bw6_761_ate_G1_precomp::operator==
bool operator==(const bw6_761_ate_G1_precomp &other) const
Definition: bw6_761_pairing.cpp:11
libff::Fp6_2over3_model::mul_by_045
Fp6_2over3_model mul_by_045(const my_Fp &ell_0, const my_Fp &ell_VW, const my_Fp &ell_VV) const
libff
Definition: ffi.cpp:8
libff::bw6_761_G2
Definition: bw6_761_g2.hpp:15
libff::bw6_761_ate_double_miller_loop
bw6_761_Fq6 bw6_761_ate_double_miller_loop(const bw6_761_ate_G1_precomp &prec_P1, const bw6_761_ate_G2_precomp &prec_Q1, const bw6_761_ate_G1_precomp &prec_P2, const bw6_761_ate_G2_precomp &prec_Q2)
Definition: bw6_761_pairing.cpp:508
libff::Fp_model::squared
Fp_model squared() const
libff::bw6_761_ate_G2_precomp_iteration::QY
bw6_761_Fq QY
Definition: bw6_761_pairing.hpp:41
libff::bw6_761_ate_miller_loop
bw6_761_Fq6 bw6_761_ate_miller_loop(const bw6_761_ate_G1_precomp &prec_P, const bw6_761_ate_G2_precomp &prec_Q)
Definition: bw6_761_pairing.cpp:423
libff::operator>>
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:446
libff::bw6_761_pairing
bw6_761_Fq6 bw6_761_pairing(const bw6_761_G1 &P, const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:671
libff::bw6_761_ate_G2_precomp::operator==
bool operator==(const bw6_761_ate_G2_precomp &other) const
Definition: bw6_761_pairing.cpp:105
libff::bw6_761_ate_G2_precomp::precomp_2
bw6_761_ate_G2_precomp_iteration precomp_2
Definition: bw6_761_pairing.hpp:53
libff::bw6_761_ate_loop_count2
bigint< bw6_761_q_limbs > bw6_761_ate_loop_count2
Definition: bw6_761_init.cpp:22
libff::Fp6_2over3_model::unitary_inverse
Fp6_2over3_model unitary_inverse() const
libff::Fp_model< bw6_761_q_limbs, bw6_761_modulus_q >::one
static const Fp_model< n, modulus > & one()
libff::bw6_761_ate_ell_coeffs::ell_0
bw6_761_Fq ell_0
Definition: bw6_761_pairing.hpp:28
OUTPUT_SEPARATOR
#define OUTPUT_SEPARATOR
Definition: serialization.hpp:69
libff::bw6_761_final_exponentiation
bw6_761_GT bw6_761_final_exponentiation(const bw6_761_Fq6 &elt)
Definition: bw6_761_pairing.cpp:258
libff::bw6_761_ate_G1_precomp::PX
bw6_761_Fq PX
Definition: bw6_761_pairing.hpp:17
libff::bw6_761_final_exponent_is_z_neg
bool bw6_761_final_exponent_is_z_neg
Definition: bw6_761_init.cpp:25
libff::bw6_761_ate_precompute_G1
bw6_761_ate_G1_precomp bw6_761_ate_precompute_G1(const bw6_761_G1 &P)
Definition: bw6_761_pairing.cpp:354
libff::bw6_761_ate_precompute_G2
bw6_761_ate_G2_precomp bw6_761_ate_precompute_G2(const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:414
libff::bw6_761_ate_G1_precomp::PY
bw6_761_Fq PY
Definition: bw6_761_pairing.hpp:18
bw6_761_pairing.hpp
libff::bw6_761_exp_by_z
bw6_761_Fq6 bw6_761_exp_by_z(const bw6_761_Fq6 &elt)
Definition: bw6_761_pairing.cpp:150
libff::bw6_761_ate_ell_coeffs::ell_VV
bw6_761_Fq ell_VV
Definition: bw6_761_pairing.hpp:30
libff::consume_OUTPUT_SEPARATOR
void consume_OUTPUT_SEPARATOR(std::istream &in)
bw6_761_g2.hpp
libff::bw6_761_final_exponentiation_last_chunk
bw6_761_Fq6 bw6_761_final_exponentiation_last_chunk(const bw6_761_Fq6 &elt)
Definition: bw6_761_pairing.cpp:172
libff::bw6_761_ate_ell_coeffs
Definition: bw6_761_pairing.hpp:27
libff::bw6_761_ate_G2_precomp_iteration::coeffs
std::vector< bw6_761_ate_ell_coeffs > coeffs
Definition: bw6_761_pairing.hpp:42
libff::bigint
Definition: bigint.hpp:20
libff::bw6_761_ate_G2_precomp::precomp_1
bw6_761_ate_G2_precomp_iteration precomp_1
Definition: bw6_761_pairing.hpp:52
libff::Fp6_2over3_model::Frobenius_map
Fp6_2over3_model Frobenius_map(unsigned long power) const
libff::bw6_761_ate_reduced_pairing
bw6_761_GT bw6_761_ate_reduced_pairing(const bw6_761_G1 &P, const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:635
bw6_761_init.hpp
libff::bw6_761_precompute_G1
bw6_761_G1_precomp bw6_761_precompute_G1(const bw6_761_G1 &P)
Definition: bw6_761_pairing.cpp:646
libff::bw6_761_G1::Y
bw6_761_Fq Y
Definition: bw6_761_g1.hpp:37
libff::bw6_761_G2::X
bw6_761_Fq X
Definition: bw6_761_g2.hpp:39
libff::mixed_addition_step_for_miller_loop
void mixed_addition_step_for_miller_loop(const bw6_761_G2 base, bw6_761_G2 &current, bw6_761_ate_ell_coeffs &c)
Definition: bw6_761_pairing.cpp:319
libff::Fp_model
Definition: fp.hpp:20
libff::bw6_761_G1::X
bw6_761_Fq X
Definition: bw6_761_g1.hpp:37
libff::operator<<
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:436
libff::bw6_761_final_exponent_z
bigint< bw6_761_q_limbs > bw6_761_final_exponent_z
Definition: bw6_761_init.cpp:24
libff::consume_OUTPUT_NEWLINE
void consume_OUTPUT_NEWLINE(std::istream &in)
libff::Fp6_2over3_model::cyclotomic_exp
Fp6_2over3_model cyclotomic_exp(const bigint< m > &exponent) const
libff::find_wnaf
std::vector< long > find_wnaf(const size_t window_size, const bigint< n > &scalar)
libff::bw6_761_ate_G2_precomp_iteration::operator==
bool operator==(const bw6_761_ate_G2_precomp_iteration &other) const
Definition: bw6_761_pairing.cpp:60
profiling.hpp
bw6_761_g1.hpp
libff::bw6_761_G2::Z
bw6_761_Fq Z
Definition: bw6_761_g2.hpp:39
libff::bw6_761_ate_G2_precomp_iteration::QX
bw6_761_Fq QX
Definition: bw6_761_pairing.hpp:40
libff::leave_block
void leave_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:305
libff::bw6_761_twist_coeff_b
bw6_761_Fq bw6_761_twist_coeff_b
Definition: bw6_761_init.cpp:19
OUTPUT_NEWLINE
#define OUTPUT_NEWLINE
Definition: serialization.hpp:68
libff::Fp6_2over3_model
Definition: fp6_2over3.hpp:26
libff::doubling_step_for_miller_loop
void doubling_step_for_miller_loop(bw6_761_G2 &current, bw6_761_ate_ell_coeffs &c)
Definition: bw6_761_pairing.cpp:274
libff::bw6_761_double_miller_loop
bw6_761_Fq6 bw6_761_double_miller_loop(const bw6_761_ate_G1_precomp &prec_P1, const bw6_761_ate_G2_precomp &prec_Q1, const bw6_761_ate_G1_precomp &prec_P2, const bw6_761_ate_G2_precomp &prec_Q2)
Definition: bw6_761_pairing.cpp:662
libff::bw6_761_precompute_G2
bw6_761_G2_precomp bw6_761_precompute_G2(const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:651
libff::bw6_761_G1
Definition: bw6_761_g1.hpp:14
libff::consume_newline
void consume_newline(std::istream &in)
libff::bw6_761_ate_ell_coeffs::ell_VW
bw6_761_Fq ell_VW
Definition: bw6_761_pairing.hpp:29
libff::Fp6_2over3_model::inverse
Fp6_2over3_model inverse() const
libff::Fp6_2over3_model::squared
Fp6_2over3_model squared() const
libff::bw6_761_ate_G1_precomp
Definition: bw6_761_pairing.hpp:16
libff::bw6_761_ate_pairing
bw6_761_Fq6 bw6_761_ate_pairing(const bw6_761_G1 &P, const bw6_761_G2 &Q)
Definition: bw6_761_pairing.cpp:625
libff::bw6_761_G2::Y
bw6_761_Fq Y
Definition: bw6_761_g2.hpp:39
libff::bw6_761_ate_loop_count1
bigint< bw6_761_q_limbs > bw6_761_ate_loop_count1
Definition: bw6_761_init.cpp:21
libff::bw6_761_G1::to_affine_coordinates
void to_affine_coordinates()
Definition: bw6_761_g1.cpp:58