Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
edwards_pairing.cpp
Go to the documentation of this file.
1 
8 #include <cassert>
14 
15 namespace libff
16 {
17 
19  const edwards_Fq_conic_coefficients &other) const
20 {
21  return (
22  this->c_ZZ == other.c_ZZ && this->c_XY == other.c_XY &&
23  this->c_XZ == other.c_XZ);
24 }
25 
26 std::ostream &operator<<(
27  std::ostream &out, const edwards_Fq_conic_coefficients &cc)
28 {
29  out << cc.c_ZZ << OUTPUT_SEPARATOR << cc.c_XY << OUTPUT_SEPARATOR
30  << cc.c_XZ;
31  return out;
32 }
33 
34 std::istream &operator>>(std::istream &in, edwards_Fq_conic_coefficients &cc)
35 {
36  in >> cc.c_ZZ;
38  in >> cc.c_XY;
40  in >> cc.c_XZ;
41  return in;
42 }
43 
44 std::ostream &operator<<(
45  std::ostream &out, const edwards_tate_G1_precomp &prec_P)
46 {
47  out << prec_P.size() << "\n";
48  for (const edwards_Fq_conic_coefficients &cc : prec_P) {
49  out << cc << OUTPUT_NEWLINE;
50  }
51 
52  return out;
53 }
54 
55 std::istream &operator>>(std::istream &in, edwards_tate_G1_precomp &prec_P)
56 {
57  prec_P.clear();
58 
59  size_t s;
60  in >> s;
61 
62  consume_newline(in);
63  prec_P.reserve(s);
64 
65  for (size_t i = 0; i < s; ++i) {
67  in >> cc;
69  prec_P.emplace_back(cc);
70  }
71 
72  return in;
73 }
74 
76  const edwards_tate_G2_precomp &other) const
77 {
78  return (this->y0 == other.y0 && this->eta == other.eta);
79 }
80 
81 std::ostream &operator<<(
82  std::ostream &out, const edwards_tate_G2_precomp &prec_Q)
83 {
84  out << prec_Q.y0 << OUTPUT_SEPARATOR << prec_Q.eta;
85  return out;
86 }
87 
88 std::istream &operator>>(std::istream &in, edwards_tate_G2_precomp &prec_Q)
89 {
90  in >> prec_Q.y0;
92  in >> prec_Q.eta;
93  return in;
94 }
95 
97  const edwards_Fq3_conic_coefficients &other) const
98 {
99  return (
100  this->c_ZZ == other.c_ZZ && this->c_XY == other.c_XY &&
101  this->c_XZ == other.c_XZ);
102 }
103 
104 std::ostream &operator<<(
105  std::ostream &out, const edwards_Fq3_conic_coefficients &cc)
106 {
107  out << cc.c_ZZ << OUTPUT_SEPARATOR << cc.c_XY << OUTPUT_SEPARATOR
108  << cc.c_XZ;
109  return out;
110 }
111 
112 std::istream &operator>>(std::istream &in, edwards_Fq3_conic_coefficients &cc)
113 {
114  in >> cc.c_ZZ;
116  in >> cc.c_XY;
118  in >> cc.c_XZ;
119  return in;
120 }
121 
122 std::ostream &operator<<(
123  std::ostream &out, const edwards_ate_G2_precomp &prec_Q)
124 {
125  out << prec_Q.size() << "\n";
126  for (const edwards_Fq3_conic_coefficients &cc : prec_Q) {
127  out << cc << OUTPUT_NEWLINE;
128  }
129 
130  return out;
131 }
132 
133 std::istream &operator>>(std::istream &in, edwards_ate_G2_precomp &prec_Q)
134 {
135  prec_Q.clear();
136 
137  size_t s;
138  in >> s;
139 
140  consume_newline(in);
141 
142  prec_Q.reserve(s);
143 
144  for (size_t i = 0; i < s; ++i) {
146  in >> cc;
148  prec_Q.emplace_back(cc);
149  }
150 
151  return in;
152 }
153 
155  const edwards_ate_G1_precomp &other) const
156 {
157  return (
158  this->P_XY == other.P_XY && this->P_XZ == other.P_XZ &&
159  this->P_ZZplusYZ == other.P_ZZplusYZ);
160 }
161 
162 std::ostream &operator<<(
163  std::ostream &out, const edwards_ate_G1_precomp &prec_P)
164 {
165  out << prec_P.P_XY << OUTPUT_SEPARATOR << prec_P.P_XZ << OUTPUT_SEPARATOR
166  << prec_P.P_ZZplusYZ;
167 
168  return out;
169 }
170 
171 std::istream &operator>>(std::istream &in, edwards_ate_G1_precomp &prec_P)
172 {
173  in >> prec_P.P_XY >> prec_P.P_XZ >> prec_P.P_ZZplusYZ;
174 
175  return in;
176 }
177 
178 /* final exponentiations */
180  const edwards_Fq6 &elt, const edwards_Fq6 &elt_inv)
181 {
182  enter_block("Call to edwards_final_exponentiation_last_chunk");
183  const edwards_Fq6 elt_q = elt.Frobenius_map(1);
184  edwards_Fq6 w1_part =
186  edwards_Fq6 w0_part;
188  w0_part =
190  } else {
191  w0_part =
193  }
194  edwards_Fq6 result = w1_part * w0_part;
195  leave_block("Call to edwards_final_exponentiation_last_chunk");
196 
197  return result;
198 }
199 
201  const edwards_Fq6 &elt, const edwards_Fq6 &elt_inv)
202 {
203  enter_block("Call to edwards_final_exponentiation_first_chunk");
204 
205  /* (q^3-1)*(q+1) */
206 
207  /* elt_q3 = elt^(q^3) */
208  const edwards_Fq6 elt_q3 = elt.Frobenius_map(3);
209  /* elt_q3_over_elt = elt^(q^3-1) */
210  const edwards_Fq6 elt_q3_over_elt = elt_q3 * elt_inv;
211  /* alpha = elt^((q^3-1) * q) */
212  const edwards_Fq6 alpha = elt_q3_over_elt.Frobenius_map(1);
213  /* beta = elt^((q^3-1)*(q+1) */
214  const edwards_Fq6 beta = alpha * elt_q3_over_elt;
215  leave_block("Call to edwards_final_exponentiation_first_chunk");
216  return beta;
217 }
218 
220 {
221  enter_block("Call to edwards_final_exponentiation");
222  const edwards_Fq6 elt_inv = elt.inverse();
223  const edwards_Fq6 elt_to_first_chunk =
225  const edwards_Fq6 elt_inv_to_first_chunk =
228  elt_to_first_chunk, elt_inv_to_first_chunk);
229  leave_block("Call to edwards_final_exponentiation");
230 
231  return result;
232 }
233 
235 {
236  enter_block("Call to edwards_tate_precompute_G2");
237  edwards_G2 Qcopy = Q;
238  Qcopy.to_affine_coordinates();
240  result.y0 = Qcopy.Y * Qcopy.Z.inverse(); // Y/Z
241  result.eta =
242  (Qcopy.Z + Qcopy.Y) *
243  edwards_Fq6::mul_by_non_residue(Qcopy.X).inverse(); // (Z+Y)/(nqr*X)
244  leave_block("Call to edwards_tate_precompute_G2");
245 
246  return result;
247 }
248 
254 
255  void print() const
256  {
257  printf("extended edwards_G1 projective X/Y/Z/T:\n");
258  X.print();
259  Y.print();
260  Z.print();
261  T.print();
262  }
263 
264  void test_invariant() const { assert(T * Z == X * Y); }
265 };
266 
269 {
270  const edwards_Fq &X = current.X, &Y = current.Y, &Z = current.Z,
271  &T = current.T;
272  const edwards_Fq A = X.squared(); // A = X1^2
273  const edwards_Fq B = Y.squared(); // B = Y1^2
274  const edwards_Fq C = Z.squared(); // C = Z1^2
275  const edwards_Fq D = (X + Y).squared(); // D = (X1+Y1)^2
276  const edwards_Fq E = (Y + Z).squared(); // E = (Y1+Z1)^2
277  const edwards_Fq F = D - (A + B); // F = D-(A+B)
278  const edwards_Fq G = E - (B + C); // G = E-(B+C)
279  const edwards_Fq &H = A; // H = A (edwards_a=1)
280  const edwards_Fq I = H + B; // I = H+B
281  const edwards_Fq J = C - I; // J = C-I
282  const edwards_Fq K = J + C; // K = J+C
283 
284  cc.c_ZZ = Y * (T - X); // c_ZZ = 2*Y1*(T1-X1)
285  cc.c_ZZ = cc.c_ZZ + cc.c_ZZ;
286 
287  cc.c_XY = J + J + G; // c_XY = 2*J+G
288  cc.c_XZ = X * T - B; // c_XZ = 2*(X1*T1-B) (edwards_a=1)
289  cc.c_XZ = cc.c_XZ + cc.c_XZ;
290 
291  current.X = F * K; // X3 = F*K
292  current.Y = I * (B - H); // Y3 = I*(B-H)
293  current.Z = I * K; // Z3 = I*K
294  current.T = F * (B - H); // T3 = F*(B-H)
295 
296 #ifdef DEBUG
297  current.test_invariant();
298 #endif
299 }
300 
302  const extended_edwards_G1_projective &base,
305 {
306  const edwards_Fq &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z,
307  &T1 = current.T;
308  const edwards_Fq &X2 = base.X, &Y2 = base.Y, &Z2 = base.Z, &T2 = base.T;
309 
310  const edwards_Fq A = X1 * X2; // A = X1*X2
311  const edwards_Fq B = Y1 * Y2; // B = Y1*Y2
312  const edwards_Fq C = Z1 * T2; // C = Z1*T2
313  const edwards_Fq D = T1 * Z2; // D = T1*Z2
314  const edwards_Fq E = D + C; // E = D+C
315  const edwards_Fq F =
316  (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
317  const edwards_Fq G = B + A; // G = B + A (edwards_a=1)
318  const edwards_Fq H = D - C; // H = D-C
319  const edwards_Fq I = T1 * T2; // I = T1*T2
320 
321  cc.c_ZZ = (T1 - X1) * (T2 + X2) - I + A; // c_ZZ = (T1-X1)*(T2+X2)-I+A
322  cc.c_XY = X1 * Z2 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
323  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
324  current.X = E * F; // X3 = E*F
325  current.Y = G * H; // Y3 = G*H
326  current.Z = F * G; // Z3 = F*G
327  current.T = E * H; // T3 = E*H
328 
329 #ifdef DEBUG
330  current.test_invariant();
331 #endif
332 }
333 
335  const extended_edwards_G1_projective &base,
338 {
339  const edwards_Fq &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z,
340  &T1 = current.T;
341  const edwards_Fq &X2 = base.X, &Y2 = base.Y, &T2 = base.T;
342 
343  const edwards_Fq A = X1 * X2; // A = X1*X2
344  const edwards_Fq B = Y1 * Y2; // B = Y1*Y2
345  const edwards_Fq C = Z1 * T2; // C = Z1*T2
346  const edwards_Fq D = T1; // D = T1*Z2
347  const edwards_Fq E = D + C; // E = D+C
348  const edwards_Fq F =
349  (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
350  const edwards_Fq G = B + A; // G = B + A (edwards_a=1)
351  const edwards_Fq H = D - C; // H = D-C
352  const edwards_Fq I = T1 * T2; // I = T1*T2
353 
354  cc.c_ZZ = (T1 - X1) * (T2 + X2) - I + A; // c_ZZ = (T1-X1)*(T2+X2)-I+A
355  cc.c_XY = X1 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
356  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
357  current.X = E * F; // X3 = E*F
358  current.Y = G * H; // Y3 = G*H
359  current.Z = F * G; // Z3 = F*G
360  current.T = E * H; // T3 = E*H
361 
362 #ifdef DEBUG
363  current.test_invariant();
364 #endif
365 }
366 
368 {
369  enter_block("Call to edwards_tate_precompute_G1");
371 
372  edwards_G1 Pcopy = P;
373  Pcopy.to_affine_coordinates();
374 
376  P_ext.X = Pcopy.X;
377  P_ext.Y = Pcopy.Y;
378  P_ext.Z = Pcopy.Z;
379  P_ext.T = Pcopy.X * Pcopy.Y;
380 
382 
383  bool found_one = false;
384  for (long i = edwards_modulus_r.max_bits(); i >= 0; --i) {
385  const bool bit = edwards_modulus_r.test_bit(i);
386  if (!found_one) {
387  /* this skips the MSB itself */
388  found_one |= bit;
389  continue;
390  }
391 
392  /* code below gets executed for all bits (EXCEPT the MSB itself) of
393  edwards_modulus_r (skipping leading zeros) in MSB to LSB
394  order */
397  result.push_back(cc);
398 
399  if (bit) {
401  result.push_back(cc);
402  }
403  }
404 
405  leave_block("Call to edwards_tate_precompute_G1");
406  return result;
407 }
408 
410  const edwards_tate_G1_precomp &prec_P,
411  const edwards_tate_G2_precomp &prec_Q)
412 {
413  enter_block("Call to edwards_tate_miller_loop");
414 
416 
417  bool found_one = false;
418  size_t idx = 0;
419  for (long i = edwards_modulus_r.max_bits() - 1; i >= 0; --i) {
420  const bool bit = edwards_modulus_r.test_bit(i);
421  if (!found_one) {
422  /* this skips the MSB itself */
423  found_one |= bit;
424  continue;
425  }
426 
427  /* code below gets executed for all bits (EXCEPT the MSB itself) of
428  edwards_modulus_r (skipping leading zeros) in MSB to LSB
429  order */
430  edwards_Fq_conic_coefficients cc = prec_P[idx++];
431  edwards_Fq6 g_RR_at_Q = edwards_Fq6(
432  edwards_Fq3(cc.c_XZ, edwards_Fq(0l), edwards_Fq(0l)) +
433  cc.c_XY * prec_Q.y0,
434  cc.c_ZZ * prec_Q.eta);
435  f = f.squared() * g_RR_at_Q;
436  if (bit) {
437  cc = prec_P[idx++];
438 
439  edwards_Fq6 g_RP_at_Q = edwards_Fq6(
440  edwards_Fq3(cc.c_XZ, edwards_Fq(0l), edwards_Fq(0l)) +
441  cc.c_XY * prec_Q.y0,
442  cc.c_ZZ * prec_Q.eta);
443  f = f * g_RP_at_Q;
444  }
445  }
446  leave_block("Call to edwards_tate_miller_loop");
447 
448  return f;
449 }
450 
452 {
453  enter_block("Call to edwards_tate_pairing");
456  edwards_Fq6 result = edwards_tate_miller_loop(prec_P, prec_Q);
457  leave_block("Call to edwards_tate_pairing");
458  return result;
459 }
460 
462  const edwards_G1 &P, const edwards_G2 &Q)
463 {
464  enter_block("Call to edwards_tate_reduced_pairing");
465  const edwards_Fq6 f = edwards_tate_pairing(P, Q);
466  const edwards_GT result = edwards_final_exponentiation(f);
467  leave_block("Call to edwards_tate_reduce_pairing");
468  return result;
469 }
470 
476 
477  void print() const
478  {
479  printf("extended edwards_G2 projective X/Y/Z/T:\n");
480  X.print();
481  Y.print();
482  Z.print();
483  T.print();
484  }
485 
486  void test_invariant() const { assert(T * Z == X * Y); }
487 };
488 
491 {
492  const edwards_Fq3 &X = current.X, &Y = current.Y, &Z = current.Z,
493  &T = current.T;
494  const edwards_Fq3 A = X.squared(); // A = X1^2
495  const edwards_Fq3 B = Y.squared(); // B = Y1^2
496  const edwards_Fq3 C = Z.squared(); // C = Z1^2
497  const edwards_Fq3 D = (X + Y).squared(); // D = (X1+Y1)^2
498  const edwards_Fq3 E = (Y + Z).squared(); // E = (Y1+Z1)^2
499  const edwards_Fq3 F = D - (A + B); // F = D-(A+B)
500  const edwards_Fq3 G = E - (B + C); // G = E-(B+C)
501  const edwards_Fq3 H =
502  edwards_G2::mul_by_a(A); // edwards_param_twist_coeff_a is 1 * X for us
503  // H = twisted_a * A
504  const edwards_Fq3 I = H + B; // I = H+B
505  const edwards_Fq3 J = C - I; // J = C-I
506  const edwards_Fq3 K = J + C; // K = J+C
507 
508  cc.c_ZZ = Y * (T - X); // c_ZZ = 2*Y1*(T1-X1)
509  cc.c_ZZ = cc.c_ZZ + cc.c_ZZ;
510 
511  // c_XY = 2*(C-edwards_a * A * delta_3-B)+G (edwards_a = 1 for us)
512  cc.c_XY = C - edwards_G2::mul_by_a(A) -
513  B; // edwards_param_twist_coeff_a is 1 * X for us
514  cc.c_XY = cc.c_XY + cc.c_XY + G;
515 
516  // c_XZ = 2*(edwards_a*X1*T1*delta_3-B) (edwards_a = 1 for us)
517  cc.c_XZ = edwards_G2::mul_by_a(X * T) -
518  B; // edwards_param_twist_coeff_a is 1 * X for us
519  cc.c_XZ = cc.c_XZ + cc.c_XZ;
520 
521  current.X = F * K; // X3 = F*K
522  current.Y = I * (B - H); // Y3 = I*(B-H)
523  current.Z = I * K; // Z3 = I*K
524  current.T = F * (B - H); // T3 = F*(B-H)
525 #ifdef DEBUG
526  current.test_invariant();
527 #endif
528 }
529 
531  const extended_edwards_G2_projective &base,
534 {
535  const edwards_Fq3 &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z,
536  &T1 = current.T;
537  const edwards_Fq3 &X2 = base.X, &Y2 = base.Y, &Z2 = base.Z, &T2 = base.T;
538 
539  const edwards_Fq3 A = X1 * X2; // A = X1*X2
540  const edwards_Fq3 B = Y1 * Y2; // B = Y1*Y2
541  const edwards_Fq3 C = Z1 * T2; // C = Z1*T2
542  const edwards_Fq3 D = T1 * Z2; // D = T1*Z2
543  const edwards_Fq3 E = D + C; // E = D+C
544  const edwards_Fq3 F =
545  (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
546  // G = B + twisted_edwards_a * A
547  const edwards_Fq3 G =
548  B +
549  edwards_G2::mul_by_a(A); // edwards_param_twist_coeff_a is 1*X for us
550  const edwards_Fq3 H = D - C; // H = D-C
551  const edwards_Fq3 I = T1 * T2; // I = T1*T2
552 
553  // c_ZZ = delta_3* ((T1-X1)*(T2+X2)-I+A)
555  (T1 - X1) * (T2 + X2) - I +
556  A); // edwards_param_twist_coeff_a is 1*X for us
557 
558  cc.c_XY = X1 * Z2 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
559  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
560  current.X = E * F; // X3 = E*F
561  current.Y = G * H; // Y3 = G*H
562  current.Z = F * G; // Z3 = F*G
563  current.T = E * H; // T3 = E*H
564 
565 #ifdef DEBUG
566  current.test_invariant();
567 #endif
568 }
569 
571  const extended_edwards_G2_projective &base,
574 {
575  const edwards_Fq3 &X1 = current.X, &Y1 = current.Y, &Z1 = current.Z,
576  &T1 = current.T;
577  const edwards_Fq3 &X2 = base.X, &Y2 = base.Y, &T2 = base.T;
578 
579  const edwards_Fq3 A = X1 * X2; // A = X1*X2
580  const edwards_Fq3 B = Y1 * Y2; // B = Y1*Y2
581  const edwards_Fq3 C = Z1 * T2; // C = Z1*T2
582  const edwards_Fq3 E = T1 + C; // E = T1+C
583  const edwards_Fq3 F =
584  (X1 - Y1) * (X2 + Y2) + B - A; // F = (X1-Y1)*(X2+Y2)+B-A
585  // G = B + twisted_edwards_a * A
586  const edwards_Fq3 G =
587  B +
588  edwards_G2::mul_by_a(A); // edwards_param_twist_coeff_a is 1*X for us
589  const edwards_Fq3 H = T1 - C; // H = T1-C
590  const edwards_Fq3 I = T1 * T2; // I = T1*T2
591 
592  // c_ZZ = delta_3* ((T1-X1)*(T2+X2)-I+A)
594  (T1 - X1) * (T2 + X2) - I +
595  A); // edwards_param_twist_coeff_a is 1*X for us
596 
597  cc.c_XY = X1 - X2 * Z1 + F; // c_XY = X1*Z2-X2*Z1+F
598  cc.c_XZ = (Y1 - T1) * (Y2 + T2) - B + I - H; // c_XZ = (Y1-T1)*(Y2+T2)-B+I-H
599  current.X = E * F; // X3 = E*F
600  current.Y = G * H; // Y3 = G*H
601  current.Z = F * G; // Z3 = F*G
602  current.T = E * H; // T3 = E*H
603 
604 #ifdef DEBUG
605  current.test_invariant();
606 #endif
607 }
608 
610 {
611  enter_block("Call to edwards_ate_precompute_G1");
612  edwards_G1 Pcopy = P;
613  Pcopy.to_affine_coordinates();
614  edwards_ate_G1_precomp result;
615  result.P_XY = Pcopy.X * Pcopy.Y;
616  result.P_XZ = Pcopy.X; // P.X * P.Z but P.Z = 1
617  result.P_ZZplusYZ =
618  (edwards_Fq::one() + Pcopy.Y); // (P.Z + P.Y) * P.Z but P.Z = 1
619  leave_block("Call to edwards_ate_precompute_G1");
620  return result;
621 }
622 
624 {
625  enter_block("Call to edwards_ate_precompute_G2");
627  edwards_ate_G2_precomp result;
628 
629  edwards_G2 Qcopy(Q);
630  Qcopy.to_affine_coordinates();
631 
633  Q_ext.X = Qcopy.X;
634  Q_ext.Y = Qcopy.Y;
635  Q_ext.Z = Qcopy.Z;
636  Q_ext.T = Qcopy.X * Qcopy.Y;
637 
639 
640  bool found_one = false;
641  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
642  const bool bit = loop_count.test_bit(i);
643  if (!found_one) {
644  /* this skips the MSB itself */
645  found_one |= bit;
646  continue;
647  }
648 
651  result.push_back(cc);
652  if (bit) {
654  result.push_back(cc);
655  }
656  }
657 
658  leave_block("Call to edwards_ate_precompute_G2");
659  return result;
660 }
661 
663  const edwards_ate_G1_precomp &prec_P, const edwards_ate_G2_precomp &prec_Q)
664 {
665  enter_block("Call to edwards_ate_miller_loop");
667 
669 
670  bool found_one = false;
671  size_t idx = 0;
672  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
673  const bool bit = loop_count.test_bit(i);
674  if (!found_one) {
675  /* this skips the MSB itself */
676  found_one |= bit;
677  continue;
678  }
679 
680  /* code below gets executed for all bits (EXCEPT the MSB itself) of
681  edwards_param_p (skipping leading zeros) in MSB to LSB
682  order */
683  edwards_Fq3_conic_coefficients cc = prec_Q[idx++];
684 
685  edwards_Fq6 g_RR_at_P = edwards_Fq6(
686  prec_P.P_XY * cc.c_XY + prec_P.P_XZ * cc.c_XZ,
687  prec_P.P_ZZplusYZ * cc.c_ZZ);
688  f = f.squared() * g_RR_at_P;
689  if (bit) {
690  cc = prec_Q[idx++];
691  edwards_Fq6 g_RQ_at_P = edwards_Fq6(
692  prec_P.P_ZZplusYZ * cc.c_ZZ,
693  prec_P.P_XY * cc.c_XY + prec_P.P_XZ * cc.c_XZ);
694  f = f * g_RQ_at_P;
695  }
696  }
697  leave_block("Call to edwards_ate_miller_loop");
698 
699  return f;
700 }
701 
703  const edwards_ate_G1_precomp &prec_P1,
704  const edwards_ate_G2_precomp &prec_Q1,
705  const edwards_ate_G1_precomp &prec_P2,
706  const edwards_ate_G2_precomp &prec_Q2)
707 {
708  enter_block("Call to edwards_ate_double_miller_loop");
710 
712 
713  bool found_one = false;
714  size_t idx = 0;
715  for (long i = loop_count.max_bits() - 1; i >= 0; --i) {
716  const bool bit = loop_count.test_bit(i);
717  if (!found_one) {
718  /* this skips the MSB itself */
719  found_one |= bit;
720  continue;
721  }
722 
723  /* code below gets executed for all bits (EXCEPT the MSB itself) of
724  edwards_param_p (skipping leading zeros) in MSB to LSB
725  order */
726  edwards_Fq3_conic_coefficients cc1 = prec_Q1[idx];
727  edwards_Fq3_conic_coefficients cc2 = prec_Q2[idx];
728  ++idx;
729 
730  edwards_Fq6 g_RR_at_P1 = edwards_Fq6(
731  prec_P1.P_XY * cc1.c_XY + prec_P1.P_XZ * cc1.c_XZ,
732  prec_P1.P_ZZplusYZ * cc1.c_ZZ);
733 
734  edwards_Fq6 g_RR_at_P2 = edwards_Fq6(
735  prec_P2.P_XY * cc2.c_XY + prec_P2.P_XZ * cc2.c_XZ,
736  prec_P2.P_ZZplusYZ * cc2.c_ZZ);
737  f = f.squared() * g_RR_at_P1 * g_RR_at_P2;
738 
739  if (bit) {
740  cc1 = prec_Q1[idx];
741  cc2 = prec_Q2[idx];
742  ++idx;
743  edwards_Fq6 g_RQ_at_P1 = edwards_Fq6(
744  prec_P1.P_ZZplusYZ * cc1.c_ZZ,
745  prec_P1.P_XY * cc1.c_XY + prec_P1.P_XZ * cc1.c_XZ);
746  edwards_Fq6 g_RQ_at_P2 = edwards_Fq6(
747  prec_P2.P_ZZplusYZ * cc2.c_ZZ,
748  prec_P2.P_XY * cc2.c_XY + prec_P2.P_XZ * cc2.c_XZ);
749  f = f * g_RQ_at_P1 * g_RQ_at_P2;
750  }
751  }
752  leave_block("Call to edwards_ate_double_miller_loop");
753 
754  return f;
755 }
756 
758 {
759  enter_block("Call to edwards_ate_pairing");
762  edwards_Fq6 result = edwards_ate_miller_loop(prec_P, prec_Q);
763  leave_block("Call to edwards_ate_pairing");
764  return result;
765 }
766 
768 {
769  enter_block("Call to edwards_ate_reduced_pairing");
770  const edwards_Fq6 f = edwards_ate_pairing(P, Q);
771  const edwards_GT result = edwards_final_exponentiation(f);
772  leave_block("Call to edwards_ate_reduced_pairing");
773  return result;
774 }
775 
777 {
778  return edwards_ate_precompute_G1(P);
779 }
780 
782 {
783  return edwards_ate_precompute_G2(Q);
784 }
785 
787  const edwards_G1_precomp &prec_P, const edwards_G2_precomp &prec_Q)
788 {
789  return edwards_ate_miller_loop(prec_P, prec_Q);
790 }
791 
793  const edwards_G1_precomp &prec_P1,
794  const edwards_G2_precomp &prec_Q1,
795  const edwards_G1_precomp &prec_P2,
796  const edwards_G2_precomp &prec_Q2)
797 {
798  return edwards_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
799 }
800 
802 {
803  return edwards_ate_pairing(P, Q);
804 }
805 
807 {
808  return edwards_ate_reduced_pairing(P, Q);
809 }
810 } // namespace libff
libff::Fp_model::print
void print() const
libff::Fp6_2over3_model::one
static Fp6_2over3_model< n, modulus > one()
libff::edwards_final_exponentiation_last_chunk
edwards_Fq6 edwards_final_exponentiation_last_chunk(const edwards_Fq6 &elt, const edwards_Fq6 &elt_inv)
Definition: edwards_pairing.cpp:179
libff::extended_edwards_G1_projective::Y
edwards_Fq Y
Definition: edwards_pairing.cpp:251
libff::edwards_G2
Definition: edwards_g2.hpp:22
libff::Fp3_model::print
void print() const
Definition: fp3.hpp:77
libff::edwards_final_exponent_last_chunk_w1
bigint< edwards_q_limbs > edwards_final_exponent_last_chunk_w1
Definition: edwards_init.cpp:36
libff::enter_block
void enter_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:271
libff::edwards_Fq_conic_coefficients::c_XY
edwards_Fq c_XY
Definition: edwards_pairing.hpp:28
libff
Definition: ffi.cpp:8
libff::edwards_Fq_conic_coefficients::c_XZ
edwards_Fq c_XZ
Definition: edwards_pairing.hpp:29
libff::extended_edwards_G2_projective::X
edwards_Fq3 X
Definition: edwards_pairing.cpp:472
libff::Fp_model::squared
Fp_model squared() const
libff::extended_edwards_G2_projective::test_invariant
void test_invariant() const
Definition: edwards_pairing.cpp:486
libff::edwards_ate_G2_precomp
std::vector< edwards_Fq3_conic_coefficients > edwards_ate_G2_precomp
Definition: edwards_pairing.hpp:77
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::edwards_pairing
edwards_Fq6 edwards_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:801
libff::extended_edwards_G1_projective::T
edwards_Fq T
Definition: edwards_pairing.cpp:253
libff::edwards_G2::Z
edwards_Fq3 Z
Definition: edwards_g2.hpp:35
libff::Fp6_2over3_model::mul_by_non_residue
static my_Fp3 mul_by_non_residue(const my_Fp3 &elem)
libff::operator>>
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:446
libff::edwards_G2::mul_by_a
static edwards_Fq3 mul_by_a(const edwards_Fq3 &elt)
Definition: edwards_g2.cpp:31
edwards_g2.hpp
libff::edwards_tate_G2_precomp::eta
edwards_Fq3 eta
Definition: edwards_pairing.hpp:44
libff::edwards_precompute_G2
edwards_G2_precomp edwards_precompute_G2(const edwards_G2 &Q)
Definition: edwards_pairing.cpp:781
libff::edwards_G2::X
edwards_Fq3 X
Definition: edwards_g2.hpp:35
libff::extended_edwards_G1_projective::test_invariant
void test_invariant() const
Definition: edwards_pairing.cpp:264
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::edwards_G2_precomp
edwards_ate_G2_precomp edwards_G2_precomp
Definition: edwards_pairing.hpp:113
libff::edwards_tate_G2_precomp
Definition: edwards_pairing.hpp:43
libff::edwards_tate_precompute_G2
edwards_tate_G2_precomp edwards_tate_precompute_G2(const edwards_G2 &Q)
Definition: edwards_pairing.cpp:234
libff::edwards_ate_precompute_G2
edwards_ate_G2_precomp edwards_ate_precompute_G2(const edwards_G2 &Q)
Definition: edwards_pairing.cpp:623
libff::edwards_miller_loop
edwards_Fq6 edwards_miller_loop(const edwards_G1_precomp &prec_P, const edwards_G2_precomp &prec_Q)
Definition: edwards_pairing.cpp:786
libff::extended_edwards_G2_projective::print
void print() const
Definition: edwards_pairing.cpp:477
libff::edwards_final_exponent_last_chunk_is_w0_neg
bool edwards_final_exponent_last_chunk_is_w0_neg
Definition: edwards_init.cpp:35
libff::edwards_final_exponent_last_chunk_abs_of_w0
bigint< edwards_q_limbs > edwards_final_exponent_last_chunk_abs_of_w0
Definition: edwards_init.cpp:34
libff::edwards_ate_G1_precomp::operator==
bool operator==(const edwards_ate_G1_precomp &other) const
Definition: edwards_pairing.cpp:154
libff::edwards_Fq_conic_coefficients::operator==
bool operator==(const edwards_Fq_conic_coefficients &other) const
Definition: edwards_pairing.cpp:18
libff::edwards_tate_pairing
edwards_Fq6 edwards_tate_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:451
libff::edwards_ate_loop_count
bigint< edwards_q_limbs > edwards_ate_loop_count
Definition: edwards_init.cpp:32
libff::extended_edwards_G1_projective::print
void print() const
Definition: edwards_pairing.cpp:255
libff::edwards_ate_G1_precomp::P_XY
edwards_Fq P_XY
Definition: edwards_pairing.hpp:84
libff::edwards_G2::to_affine_coordinates
void to_affine_coordinates()
Definition: edwards_g2.cpp:107
libff::Fp_model< edwards_q_limbs, edwards_modulus_q >::one
static const Fp_model< n, modulus > & one()
OUTPUT_SEPARATOR
#define OUTPUT_SEPARATOR
Definition: serialization.hpp:69
libff::bigint::max_bits
static constexpr size_t max_bits()
The number of bits representable by this bigint type.
Definition: bigint.hpp:51
libff::edwards_tate_reduced_pairing
edwards_GT edwards_tate_reduced_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:461
libff::edwards_tate_precompute_G1
edwards_tate_G1_precomp edwards_tate_precompute_G1(const edwards_G1 &P)
Definition: edwards_pairing.cpp:367
edwards_init.hpp
libff::edwards_Fq3_conic_coefficients::c_XY
edwards_Fq3 c_XY
Definition: edwards_pairing.hpp:68
libff::consume_OUTPUT_SEPARATOR
void consume_OUTPUT_SEPARATOR(std::istream &in)
libff::edwards_modulus_r
bigint< edwards_r_limbs > edwards_modulus_r
Definition: edwards_init.cpp:15
libff::extended_edwards_G1_projective::X
edwards_Fq X
Definition: edwards_pairing.cpp:250
libff::edwards_Fq3_conic_coefficients::c_XZ
edwards_Fq3 c_XZ
Definition: edwards_pairing.hpp:69
libff::bigint
Definition: bigint.hpp:20
libff::full_addition_step_for_flipped_miller_loop
void full_addition_step_for_flipped_miller_loop(const extended_edwards_G2_projective &base, extended_edwards_G2_projective &current, edwards_Fq3_conic_coefficients &cc)
Definition: edwards_pairing.cpp:530
edwards_g1.hpp
libff::edwards_ate_double_miller_loop
edwards_Fq6 edwards_ate_double_miller_loop(const edwards_ate_G1_precomp &prec_P1, const edwards_ate_G2_precomp &prec_Q1, const edwards_ate_G1_precomp &prec_P2, const edwards_ate_G2_precomp &prec_Q2)
Definition: edwards_pairing.cpp:702
libff::Fp6_2over3_model::Frobenius_map
Fp6_2over3_model Frobenius_map(unsigned long power) const
libff::edwards_Fq3_conic_coefficients
Definition: edwards_pairing.hpp:66
libff::extended_edwards_G2_projective
Definition: edwards_pairing.cpp:471
libff::extended_edwards_G1_projective::Z
edwards_Fq Z
Definition: edwards_pairing.cpp:252
libff::edwards_precompute_G1
edwards_G1_precomp edwards_precompute_G1(const edwards_G1 &P)
Definition: edwards_pairing.cpp:776
libff::edwards_ate_miller_loop
edwards_Fq6 edwards_ate_miller_loop(const edwards_ate_G1_precomp &prec_P, const edwards_ate_G2_precomp &prec_Q)
Definition: edwards_pairing.cpp:662
libff::edwards_ate_precompute_G1
edwards_ate_G1_precomp edwards_ate_precompute_G1(const edwards_G1 &P)
Definition: edwards_pairing.cpp:609
libff::full_addition_step_for_miller_loop
void full_addition_step_for_miller_loop(const extended_edwards_G1_projective &base, extended_edwards_G1_projective &current, edwards_Fq_conic_coefficients &cc)
Definition: edwards_pairing.cpp:301
libff::edwards_tate_G2_precomp::operator==
bool operator==(const edwards_tate_G2_precomp &other) const
Definition: edwards_pairing.cpp:75
libff::extended_edwards_G2_projective::Z
edwards_Fq3 Z
Definition: edwards_pairing.cpp:474
libff::Fp3_model< edwards_q_limbs, edwards_modulus_q >
libff::edwards_Fq3
Fp3_model< edwards_q_limbs, edwards_modulus_q > edwards_Fq3
Definition: edwards_init.hpp:31
libff::edwards_tate_miller_loop
edwards_Fq6 edwards_tate_miller_loop(const edwards_tate_G1_precomp &prec_P, const edwards_tate_G2_precomp &prec_Q)
Definition: edwards_pairing.cpp:409
libff::edwards_final_exponentiation
edwards_GT edwards_final_exponentiation(const edwards_Fq6 &elt)
Definition: edwards_pairing.cpp:219
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::edwards_final_exponentiation_first_chunk
edwards_Fq6 edwards_final_exponentiation_first_chunk(const edwards_Fq6 &elt, const edwards_Fq6 &elt_inv)
Definition: edwards_pairing.cpp:200
libff::Fp_model< edwards_q_limbs, edwards_modulus_q >
libff::edwards_Fq_conic_coefficients::c_ZZ
edwards_Fq c_ZZ
Definition: edwards_pairing.hpp:27
libff::edwards_Fq
Fp_model< edwards_q_limbs, edwards_modulus_q > edwards_Fq
Definition: edwards_init.hpp:30
libff::edwards_G2::Y
edwards_Fq3 Y
Definition: edwards_g2.hpp:35
libff::operator<<
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
Definition: alt_bn128_g1.cpp:436
libff::Fp3_model::inverse
Fp3_model inverse() const
libff::edwards_reduced_pairing
edwards_GT edwards_reduced_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:806
libff::consume_OUTPUT_NEWLINE
void consume_OUTPUT_NEWLINE(std::istream &in)
libff::edwards_G1::Y
edwards_Fq Y
Definition: edwards_g1.hpp:33
libff::Fp6_2over3_model::cyclotomic_exp
Fp6_2over3_model cyclotomic_exp(const bigint< m > &exponent) const
libff::edwards_Fq3_conic_coefficients::c_ZZ
edwards_Fq3 c_ZZ
Definition: edwards_pairing.hpp:67
libff::extended_edwards_G2_projective::T
edwards_Fq3 T
Definition: edwards_pairing.cpp:475
profiling.hpp
libff::edwards_ate_G1_precomp::P_ZZplusYZ
edwards_Fq P_ZZplusYZ
Definition: edwards_pairing.hpp:86
libff::edwards_G1::X
edwards_Fq X
Definition: edwards_g1.hpp:33
libff::extended_edwards_G1_projective
Definition: edwards_pairing.cpp:249
libff::leave_block
void leave_block(const std::string &msg, const bool indent)
Definition: profiling.cpp:305
libff::edwards_G1::Z
edwards_Fq Z
Definition: edwards_g1.hpp:33
libff::edwards_ate_G1_precomp::P_XZ
edwards_Fq P_XZ
Definition: edwards_pairing.hpp:85
libff::edwards_ate_G1_precomp
Definition: edwards_pairing.hpp:83
libff::edwards_G1
Definition: edwards_g1.hpp:21
libff::edwards_Fq3_conic_coefficients::operator==
bool operator==(const edwards_Fq3_conic_coefficients &other) const
Definition: edwards_pairing.cpp:96
OUTPUT_NEWLINE
#define OUTPUT_NEWLINE
Definition: serialization.hpp:68
libff::edwards_Fq6
Fp6_2over3_model< edwards_q_limbs, edwards_modulus_q > edwards_Fq6
Definition: edwards_init.hpp:32
libff::Fp6_2over3_model
Definition: fp6_2over3.hpp:26
edwards_pairing.hpp
libff::edwards_ate_pairing
edwards_Fq6 edwards_ate_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:757
libff::edwards_double_miller_loop
edwards_Fq6 edwards_double_miller_loop(const edwards_G1_precomp &prec_P1, const edwards_G2_precomp &prec_Q1, const edwards_G1_precomp &prec_P2, const edwards_G2_precomp &prec_Q2)
Definition: edwards_pairing.cpp:792
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::bigint::test_bit
bool test_bit(const std::size_t bitno) const
libff::extended_edwards_G2_projective::Y
edwards_Fq3 Y
Definition: edwards_pairing.cpp:473
libff::edwards_tate_G2_precomp::y0
edwards_Fq3 y0
Definition: edwards_pairing.hpp:44
libff::edwards_tate_G1_precomp
std::vector< edwards_Fq_conic_coefficients > edwards_tate_G1_precomp
Definition: edwards_pairing.hpp:37
libff::consume_newline
void consume_newline(std::istream &in)
libff::Fp3_model::squared
Fp3_model squared() const
libff::Fp6_2over3_model::inverse
Fp6_2over3_model inverse() const
libff::edwards_G1::to_affine_coordinates
void to_affine_coordinates()
Definition: edwards_g1.cpp:62
libff::edwards_ate_reduced_pairing
edwards_GT edwards_ate_reduced_pairing(const edwards_G1 &P, const edwards_G2 &Q)
Definition: edwards_pairing.cpp:767
libff::Fp6_2over3_model::squared
Fp6_2over3_model squared() const
libff::edwards_Fq_conic_coefficients
Definition: edwards_pairing.hpp:26