Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
mnt4_pairing.cpp
Go to the documentation of this file.
1
14#include <cassert>
15
22
23namespace libff {
24
26{
27 return (this->PX == other.PX &&
28 this->PY == other.PY &&
29 this->PX_twist == other.PX_twist &&
30 this->PY_twist == other.PY_twist);
31}
32
33std::ostream& operator<<(std::ostream &out, const mnt4_ate_G1_precomp &prec_P)
34{
35 out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY << OUTPUT_SEPARATOR << prec_P.PX_twist << OUTPUT_SEPARATOR << prec_P.PY_twist;
36
37 return out;
38}
39
40std::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 (this->c_H == other.c_H &&
56 this->c_4C == other.c_4C &&
57 this->c_J == other.c_J &&
58 this->c_L == other.c_L);
59}
60
61std::ostream& operator<<(std::ostream &out, const mnt4_ate_dbl_coeffs &dc)
62{
63 out << dc.c_H << OUTPUT_SEPARATOR << dc.c_4C << OUTPUT_SEPARATOR << dc.c_J << OUTPUT_SEPARATOR << dc.c_L;
64 return out;
65}
66
67std::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 &&
83 this->c_RZ == other.c_RZ);
84}
85
86std::ostream& operator<<(std::ostream &out, const mnt4_ate_add_coeffs &ac)
87{
88 out << ac.c_L1 << OUTPUT_SEPARATOR << ac.c_RZ;
89 return out;
90}
91
92std::istream& operator>>(std::istream &in, mnt4_ate_add_coeffs &ac)
93{
94 in >> ac.c_L1;
96 in >> ac.c_RZ;
97 return in;
98}
99
101{
102 return (this->QX == other.QX &&
103 this->QY == other.QY &&
104 this->QY2 == other.QY2 &&
105 this->QX_over_twist == other.QX_over_twist &&
106 this->QY_over_twist == other.QY_over_twist &&
107 this->dbl_coeffs == other.dbl_coeffs &&
108 this->add_coeffs == other.add_coeffs);
109}
110
111std::ostream& operator<<(std::ostream& out, const mnt4_ate_G2_precomp &prec_Q)
112{
113 out << prec_Q.QX << OUTPUT_SEPARATOR
114 << prec_Q.QY << OUTPUT_SEPARATOR
115 << prec_Q.QY2 << OUTPUT_SEPARATOR
117 << prec_Q.QY_over_twist << "\n";
118 out << prec_Q.dbl_coeffs.size() << "\n";
119 for (const mnt4_ate_dbl_coeffs &dc : prec_Q.dbl_coeffs)
120 {
121 out << dc << OUTPUT_NEWLINE;
122 }
123 out << prec_Q.add_coeffs.size() << "\n";
124 for (const mnt4_ate_add_coeffs &ac : prec_Q.add_coeffs)
125 {
126 out << ac << OUTPUT_NEWLINE;
127 }
128
129 return out;
130}
131
132std::istream& operator>>(std::istream& in, mnt4_ate_G2_precomp &prec_Q)
133{
134 in >> prec_Q.QX;
136 in >> prec_Q.QY;
138 in >> prec_Q.QY2;
140 in >> prec_Q.QX_over_twist;
142 in >> prec_Q.QY_over_twist;
143 consume_newline(in);
144
145 prec_Q.dbl_coeffs.clear();
146 size_t dbl_s;
147 in >> dbl_s;
148 consume_newline(in);
149
150 prec_Q.dbl_coeffs.reserve(dbl_s);
151
152 for (size_t i = 0; i < dbl_s; ++i)
153 {
155 in >> dc;
157 prec_Q.dbl_coeffs.emplace_back(dc);
158 }
159
160 prec_Q.add_coeffs.clear();
161 size_t add_s;
162 in >> add_s;
163 consume_newline(in);
164
165 prec_Q.add_coeffs.reserve(add_s);
166
167 for (size_t i = 0; i < add_s; ++i)
168 {
170 in >> ac;
172 prec_Q.add_coeffs.emplace_back(ac);
173 }
174
175 return in;
176}
177
178/* final exponentiations */
179
181{
182 enter_block("Call to mnt4_final_exponentiation_last_chunk");
183 const mnt4_Fq4 elt_q = elt.Frobenius_map(1);
185 mnt4_Fq4 w0_part;
187 {
189 } else {
191 }
192 mnt4_Fq4 result = w1_part * w0_part;
193 leave_block("Call to mnt4_final_exponentiation_last_chunk");
194
195 return result;
196}
197
199{
200 enter_block("Call to mnt4_final_exponentiation_first_chunk");
201
202 /* (q^2-1) */
203
204 /* elt_q2 = elt^(q^2) */
205 const mnt4_Fq4 elt_q2 = elt.Frobenius_map(2);
206 /* elt_q3_over_elt = elt^(q^2-1) */
207 const mnt4_Fq4 elt_q2_over_elt = elt_q2 * elt_inv;
208
209 leave_block("Call to mnt4_final_exponentiation_first_chunk");
210 return elt_q2_over_elt;
211}
212
214{
215 enter_block("Call to mnt4_final_exponentiation");
216 const mnt4_Fq4 elt_inv = elt.inverse();
217 const mnt4_Fq4 elt_to_first_chunk = mnt4_final_exponentiation_first_chunk(elt, elt_inv);
218 const mnt4_Fq4 elt_inv_to_first_chunk = mnt4_final_exponentiation_first_chunk(elt_inv, elt);
219 mnt4_GT result = mnt4_final_exponentiation_last_chunk(elt_to_first_chunk, elt_inv_to_first_chunk);
220 leave_block("Call to mnt4_final_exponentiation");
221
222 return result;
223}
224
225/* affine ate miller loop */
226
228{
229 enter_block("Call to mnt4_affine_ate_precompute_G1");
230
231 mnt4_G1 Pcopy = P;
232 Pcopy.to_affine_coordinates();
233
235 result.PX = Pcopy.X;
236 result.PY = Pcopy.Y;
237 result.PY_twist_squared = Pcopy.Y * mnt4_twist.squared();
238
239 leave_block("Call to mnt4_affine_ate_precompute_G1");
240 return result;
241}
242
244{
245 enter_block("Call to mnt4_affine_ate_precompute_G2");
246
247 mnt4_G2 Qcopy(Q);
248 Qcopy.to_affine_coordinates();
249
251 result.QX = Qcopy.X;
252 result.QY = Qcopy.Y;
253
254 mnt4_Fq2 RX = Qcopy.X;
255 mnt4_Fq2 RY = Qcopy.Y;
256
258 bool found_nonzero = false;
259
260 std::vector<long> NAF = find_wnaf(1, loop_count);
261 for (long i = NAF.size() - 1; i >= 0; --i)
262 {
263 if (!found_nonzero)
264 {
265 /* this skips the MSB itself */
266 found_nonzero |= (NAF[i] != 0);
267 continue;
268 }
269
271 c.old_RX = RX;
272 c.old_RY = RY;
273 mnt4_Fq2 old_RX_2 = c.old_RX.squared();
274 c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt4_twist_coeff_a) * (c.old_RY + c.old_RY).inverse();
276 c.gamma_X = c.gamma * c.old_RX;
277 result.coeffs.push_back(c);
278
279 RX = c.gamma.squared() - (c.old_RX+c.old_RX);
280 RY = c.gamma * (c.old_RX - RX) - c.old_RY;
281
282 if (NAF[i] != 0)
283 {
285 c.old_RX = RX;
286 c.old_RY = RY;
287 if (NAF[i] > 0)
288 {
289 c.gamma = (c.old_RY - result.QY) * (c.old_RX - result.QX).inverse();
290 }
291 else
292 {
293 c.gamma = (c.old_RY + result.QY) * (c.old_RX - result.QX).inverse();
294 }
296 c.gamma_X = c.gamma * result.QX;
297 result.coeffs.push_back(c);
298
299 RX = c.gamma.squared() - (c.old_RX+result.QX);
300 RY = c.gamma * (c.old_RX - RX) - c.old_RY;
301 }
302 }
303
304 /* TODO: maybe handle neg
305 if (mnt4_ate_is_loop_count_neg)
306 {
307 mnt4_ate_add_coeffs ac;
308 mnt4_affine_ate_dbl_coeffs c;
309 c.old_RX = RX;
310 c.old_RY = -RY;
311 old_RX_2 = c.old_RY.squared();
312 c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt4_coeff_a) * (c.old_RY + c.old_RY).inverse();
313 c.gamma_twist = c.gamma * mnt4_twist;
314 c.gamma_X = c.gamma * c.old_RX;
315 result.coeffs.push_back(c);
316 }
317 */
318
319 leave_block("Call to mnt4_affine_ate_precompute_G2");
320 return result;
321}
322
325{
326 enter_block("Call to mnt4_affine_ate_miller_loop");
327
329
330 bool found_nonzero = false;
331 size_t idx = 0;
333
334 std::vector<long> NAF = find_wnaf(1, loop_count);
335 for (long i = NAF.size() - 1; i >= 0; --i)
336 {
337 if (!found_nonzero)
338 {
339 /* this skips the MSB itself */
340 found_nonzero |= (NAF[i] != 0);
341 continue;
342 }
343
344 /* code below gets executed for all bits (EXCEPT the MSB itself) of
345 mnt4_param_p (skipping leading zeros) in MSB to LSB
346 order */
347 mnt4_affine_ate_coeffs c = prec_Q.coeffs[idx++];
348
349 mnt4_Fq4 g_RR_at_P = mnt4_Fq4(prec_P.PY_twist_squared,
350 - prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
351 f = f.squared().mul_by_023(g_RR_at_P);
352
353 if (NAF[i] != 0)
354 {
355 mnt4_affine_ate_coeffs c = prec_Q.coeffs[idx++];
356 mnt4_Fq4 g_RQ_at_P;
357 if (NAF[i] > 0)
358 {
359 g_RQ_at_P = mnt4_Fq4(prec_P.PY_twist_squared,
360 - prec_P.PX * c.gamma_twist + c.gamma_X - prec_Q.QY);
361 }
362 else
363 {
364 g_RQ_at_P = mnt4_Fq4(prec_P.PY_twist_squared,
365 - prec_P.PX * c.gamma_twist + c.gamma_X + prec_Q.QY);
366 }
367 f = f.mul_by_023(g_RQ_at_P);
368 }
369 }
370
371 /* TODO: maybe handle neg
372 if (mnt4_ate_is_loop_count_neg)
373 {
374 // TODO:
375 mnt4_affine_ate_coeffs ac = prec_Q.coeffs[idx++];
376 mnt4_Fq4 g_RnegR_at_P = mnt4_Fq4(prec_P.PY_twist_squared,
377 - prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
378 f = (f * g_RnegR_at_P).inverse();
379 }
380 */
381
382 leave_block("Call to mnt4_affine_ate_miller_loop");
383
384 return f;
385}
386
387/* ate pairing */
388
394
395 void print() const
396 {
397 printf("extended mnt4_G2 projective X/Y/Z/T:\n");
398 X.print();
399 Y.print();
400 Z.print();
401 T.print();
402 }
403
404 void test_invariant() const
405 {
406 assert(T == Z.squared());
407 }
408};
409
412{
413 const mnt4_Fq2 X = current.X, Y = current.Y, Z = current.Z, T = current.T;
414
415 const mnt4_Fq2 A = T.squared(); // A = T1^2
416 const mnt4_Fq2 B = X.squared(); // B = X1^2
417 const mnt4_Fq2 C = Y.squared(); // C = Y1^2
418 const mnt4_Fq2 D = C.squared(); // D = C^2
419 const mnt4_Fq2 E = (X+C).squared() - B - D; // E = (X1+C)^2-B-D
420 const mnt4_Fq2 F = (B+B+B) + mnt4_twist_coeff_a * A; // F = 3*B + a *A
421 const mnt4_Fq2 G = F.squared(); // G = F^2
422
423 current.X = -(E+E+E+E) + G; // X3 = -4*E+G
424 current.Y = -mnt4_Fq("8")*D + F*(E+E-current.X); // Y3 = -8*D+F*(2*E-X3)
425 current.Z = (Y+Z).squared() - C - Z.squared(); // Z3 = (Y1+Z1)^2-C-Z1^2
426 current.T = current.Z.squared(); // T3 = Z3^2
427
428 dc.c_H = (current.Z + T).squared() - current.T - A; // H = (Z3+T1)^2-T3-A
429 dc.c_4C = C+C+C+C; // fourC = 4*C
430 dc.c_J = (F+T).squared() - G - A; // J = (F+T1)^2-G-A
431 dc.c_L = (F+X).squared() - G - B; // L = (F+X1)^2-G-B
432
433#ifdef DEBUG
434 current.test_invariant();
435#endif
436}
437
438void mixed_addition_step_for_flipped_miller_loop(const mnt4_Fq2 base_X, const mnt4_Fq2 base_Y, const mnt4_Fq2 base_Y_squared,
441{
442 const mnt4_Fq2 X1 = current.X, Y1 = current.Y, Z1 = current.Z, T1 = current.T;
443 const mnt4_Fq2 &x2 = base_X, &y2 = base_Y, &y2_squared = base_Y_squared;
444
445 const mnt4_Fq2 B = x2 * T1; // B = x2 * T1
446 const mnt4_Fq2 D = ((y2 + Z1).squared() - y2_squared - T1) * T1; // D = ((y2 + Z1)^2 - y2squared - T1) * T1
447 const mnt4_Fq2 H = B - X1; // H = B - X1
448 const mnt4_Fq2 I = H.squared(); // I = H^2
449 const mnt4_Fq2 E = I + I + I + I; // E = 4*I
450 const mnt4_Fq2 J = H * E; // J = H * E
451 const mnt4_Fq2 V = X1 * E; // V = X1 * E
452 const mnt4_Fq2 L1 = D - (Y1 + Y1); // L1 = D - 2 * Y1
453
454 current.X = L1.squared() - J - (V+V); // X3 = L1^2 - J - 2*V
455 current.Y = L1 * (V-current.X) - (Y1+Y1) * J; // Y3 = L1 * (V-X3) - 2*Y1 * J
456 current.Z = (Z1+H).squared() - T1 - I; // Z3 = (Z1 + H)^2 - T1 - I
457 current.T = current.Z.squared(); // T3 = Z3^2
458
459 ac.c_L1 = L1;
460 ac.c_RZ = current.Z;
461#ifdef DEBUG
462 current.test_invariant();
463#endif
464}
465
467{
468 enter_block("Call to mnt4_ate_precompute_G1");
469
470 mnt4_G1 Pcopy = P;
471 Pcopy.to_affine_coordinates();
472
473 mnt4_ate_G1_precomp result;
474 result.PX = Pcopy.X;
475 result.PY = Pcopy.Y;
476 result.PX_twist = Pcopy.X * mnt4_twist;
477 result.PY_twist = Pcopy.Y * mnt4_twist;
478
479 leave_block("Call to mnt4_ate_precompute_G1");
480 return result;
481}
482
484{
485 enter_block("Call to mnt4_ate_precompute_G2");
486
487 mnt4_G2 Qcopy(Q);
488 Qcopy.to_affine_coordinates();
489
490 mnt4_ate_G2_precomp result;
491 result.QX = Qcopy.X;
492 result.QY = Qcopy.Y;
493 result.QY2 = Qcopy.Y.squared();
494 result.QX_over_twist = Qcopy.X * mnt4_twist.inverse();
495 result.QY_over_twist = Qcopy.Y * mnt4_twist.inverse();
496
498 R.X = Qcopy.X;
499 R.Y = Qcopy.Y;
500 R.Z = mnt4_Fq2::one();
501 R.T = mnt4_Fq2::one();
502
504 bool found_one = false;
505
506 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
507 {
508 const bool bit = loop_count.test_bit(i);
509 if (!found_one)
510 {
511 /* this skips the MSB itself */
512 found_one |= bit;
513 continue;
514 }
515
518 result.dbl_coeffs.push_back(dc);
519 if (bit)
520 {
522 mixed_addition_step_for_flipped_miller_loop(result.QX, result.QY, result.QY2, R, ac);
523 result.add_coeffs.push_back(ac);
524 }
525 }
526
528 {
529 mnt4_Fq2 RZ_inv = R.Z.inverse();
530 mnt4_Fq2 RZ2_inv = RZ_inv.squared();
531 mnt4_Fq2 RZ3_inv = RZ2_inv * RZ_inv;
532 mnt4_Fq2 minus_R_affine_X = R.X * RZ2_inv;
533 mnt4_Fq2 minus_R_affine_Y = - R.Y * RZ3_inv;
534 mnt4_Fq2 minus_R_affine_Y2 = minus_R_affine_Y.squared();
536 mixed_addition_step_for_flipped_miller_loop(minus_R_affine_X, minus_R_affine_Y, minus_R_affine_Y2, R, ac);
537 result.add_coeffs.push_back(ac);
538 }
539
540 leave_block("Call to mnt4_ate_precompute_G2");
541 return result;
542}
543
545 const mnt4_ate_G2_precomp &prec_Q)
546{
547 enter_block("Call to mnt4_ate_miller_loop");
548
549 mnt4_Fq2 L1_coeff = mnt4_Fq2(prec_P.PX, mnt4_Fq::zero()) - prec_Q.QX_over_twist;
550
552
553 bool found_one = false;
554 size_t dbl_idx = 0;
555 size_t add_idx = 0;
556
558 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
559 {
560 const bool bit = loop_count.test_bit(i);
561
562 if (!found_one)
563 {
564 /* this skips the MSB itself */
565 found_one |= bit;
566 continue;
567 }
568
569 /* code below gets executed for all bits (EXCEPT the MSB itself) of
570 mnt4_param_p (skipping leading zeros) in MSB to LSB
571 order */
572 mnt4_ate_dbl_coeffs dc = prec_Q.dbl_coeffs[dbl_idx++];
573
574 mnt4_Fq4 g_RR_at_P = mnt4_Fq4(- dc.c_4C - dc.c_J * prec_P.PX_twist + dc.c_L,
575 dc.c_H * prec_P.PY_twist);
576 f = f.squared() * g_RR_at_P;
577 if (bit)
578 {
579 mnt4_ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
580
581 mnt4_Fq4 g_RQ_at_P = mnt4_Fq4(ac.c_RZ * prec_P.PY_twist,
582 -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
583 f = f * g_RQ_at_P;
584 }
585 }
586
588 {
589 mnt4_ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
590 mnt4_Fq4 g_RnegR_at_P = mnt4_Fq4(ac.c_RZ * prec_P.PY_twist,
591 -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
592 f = (f * g_RnegR_at_P).inverse();
593 }
594
595 leave_block("Call to mnt4_ate_miller_loop");
596
597 return f;
598}
599
601 const mnt4_ate_G2_precomp &prec_Q1,
602 const mnt4_ate_G1_precomp &prec_P2,
603 const mnt4_ate_G2_precomp &prec_Q2)
604{
605 enter_block("Call to mnt4_ate_double_miller_loop");
606
607 mnt4_Fq2 L1_coeff1 = mnt4_Fq2(prec_P1.PX, mnt4_Fq::zero()) - prec_Q1.QX_over_twist;
608 mnt4_Fq2 L1_coeff2 = mnt4_Fq2(prec_P2.PX, mnt4_Fq::zero()) - prec_Q2.QX_over_twist;
609
611
612 bool found_one = false;
613 size_t dbl_idx = 0;
614 size_t add_idx = 0;
615
617 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
618 {
619 const bool bit = loop_count.test_bit(i);
620
621 if (!found_one)
622 {
623 /* this skips the MSB itself */
624 found_one |= bit;
625 continue;
626 }
627
628 /* code below gets executed for all bits (EXCEPT the MSB itself) of
629 mnt4_param_p (skipping leading zeros) in MSB to LSB
630 order */
631 mnt4_ate_dbl_coeffs dc1 = prec_Q1.dbl_coeffs[dbl_idx];
632 mnt4_ate_dbl_coeffs dc2 = prec_Q2.dbl_coeffs[dbl_idx];
633 ++dbl_idx;
634
635 mnt4_Fq4 g_RR_at_P1 = mnt4_Fq4(- dc1.c_4C - dc1.c_J * prec_P1.PX_twist + dc1.c_L,
636 dc1.c_H * prec_P1.PY_twist);
637
638 mnt4_Fq4 g_RR_at_P2 = mnt4_Fq4(- dc2.c_4C - dc2.c_J * prec_P2.PX_twist + dc2.c_L,
639 dc2.c_H * prec_P2.PY_twist);
640
641 f = f.squared() * g_RR_at_P1 * g_RR_at_P2;
642
643 if (bit)
644 {
645 mnt4_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
646 mnt4_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
647 ++add_idx;
648
649 mnt4_Fq4 g_RQ_at_P1 = mnt4_Fq4(ac1.c_RZ * prec_P1.PY_twist,
650 -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
651 mnt4_Fq4 g_RQ_at_P2 = mnt4_Fq4(ac2.c_RZ * prec_P2.PY_twist,
652 -(prec_Q2.QY_over_twist * ac2.c_RZ + L1_coeff2 * ac2.c_L1));
653
654 f = f * g_RQ_at_P1 * g_RQ_at_P2;
655 }
656 }
657
659 {
660 mnt4_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
661 mnt4_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
662 ++add_idx;
663 mnt4_Fq4 g_RnegR_at_P1 = mnt4_Fq4(ac1.c_RZ * prec_P1.PY_twist,
664 -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
665 mnt4_Fq4 g_RnegR_at_P2 = mnt4_Fq4(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
699
704
706 const mnt4_G2_precomp &prec_Q)
707{
708 return mnt4_ate_miller_loop(prec_P, prec_Q);
709}
710
712 const mnt4_G2_precomp &prec_Q1,
713 const mnt4_G1_precomp &prec_P2,
714 const mnt4_G2_precomp &prec_Q2)
715{
716 return mnt4_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
717}
718
720 const mnt4_G2 &Q)
721{
722 return mnt4_ate_pairing(P, Q);
723}
724
726 const mnt4_G2 &Q)
727{
728 return mnt4_ate_reduced_pairing(P, Q);
729}
730
740
741} // libff
void print() const
Definition fp2.hpp:54
Fp2_model inverse() const
static Fp2_model< n, modulus > one()
Fp2_model squared() const
Fp4_model inverse() const
Fp4_model cyclotomic_exp(const bigint< m > &exponent) const
Fp4_model Frobenius_map(unsigned long power) const
static Fp4_model< n, modulus > one()
static Fp_model< n, modulus > zero()
bool test_bit(const std::size_t bitno) const
size_t max_bits() const
Definition bigint.hpp:48
void to_affine_coordinates()
Definition mnt4_g1.cpp:72
void to_affine_coordinates()
Definition mnt4_g2.cpp:88
mnt4_Fq2 Y
Definition mnt4_g2.hpp:45
mnt4_Fq2 X
Definition mnt4_g2.hpp:45
#define D(var, file, col, who, lev,...)
Definition debug.h:44
#define P
Definition dtoa.c:437
#define OUTPUT_NEWLINE
#define OUTPUT_SEPARATOR
XT< 0 > X
Definition lib.h:50
mnt4_Fq4 mnt4_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
bool mnt4_final_exponent_last_chunk_is_w0_neg
Definition mnt4_init.cpp:37
Fp_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq
Definition mnt4_init.hpp:36
mnt4_GT mnt4_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
void consume_OUTPUT_NEWLINE(std::istream &in)
mnt4_G1_precomp mnt4_precompute_G1(const mnt4_G1 &P)
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)
mnt4_affine_ate_G1_precomputation mnt4_affine_ate_precompute_G1(const mnt4_G1 &P)
mnt4_Fq4 mnt4_ate_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
Fp4_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq4
Definition mnt4_init.hpp:38
void consume_OUTPUT_SEPARATOR(std::istream &in)
mnt4_Fq4 mnt4_final_exponentiation_last_chunk(const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
mnt4_G2_precomp mnt4_precompute_G2(const mnt4_G2 &Q)
mnt4_Fq4 mnt4_ate_miller_loop(const mnt4_ate_G1_precomp &prec_P, const mnt4_ate_G2_precomp &prec_Q)
bool mnt4_ate_is_loop_count_neg
Definition mnt4_init.cpp:34
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
bigint< mnt4_q_limbs > mnt4_final_exponent_last_chunk_abs_of_w0
Definition mnt4_init.cpp:36
mnt4_Fq2 mnt4_twist
Definition mnt4_init.cpp:23
void enter_block(const std::string &msg, const bool indent)
mnt4_Fq4 mnt4_miller_loop(const mnt4_G1_precomp &prec_P, const mnt4_G2_precomp &prec_Q)
bigint< mnt4_q_limbs > mnt4_final_exponent_last_chunk_w1
Definition mnt4_init.cpp:38
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)
mnt4_ate_G2_precomp mnt4_ate_precompute_G2(const mnt4_G2 &Q)
void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
bigint< mnt4_q_limbs > mnt4_ate_loop_count
Definition mnt4_init.cpp:33
mnt4_Fq4 mnt4_affine_ate_miller_loop(const mnt4_affine_ate_G1_precomputation &prec_P, const mnt4_affine_ate_G2_precomputation &prec_Q)
mnt4_GT mnt4_affine_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
std::vector< long > find_wnaf(const size_t window_size, const bigint< n > &scalar)
mnt4_GT mnt4_final_exponentiation(const mnt4_Fq4 &elt)
void leave_block(const std::string &msg, const bool indent)
mnt4_Fq4 mnt4_final_exponentiation_first_chunk(const mnt4_Fq4 &elt, const mnt4_Fq4 &elt_inv)
mnt4_affine_ate_G2_precomputation mnt4_affine_ate_precompute_G2(const mnt4_G2 &Q)
mnt4_Fq2 mnt4_twist_coeff_a
Definition mnt4_init.cpp:24
Fp2_model< mnt4_q_limbs, mnt4_modulus_q > mnt4_Fq2
Definition mnt4_init.hpp:37
mnt4_ate_G1_precomp mnt4_ate_precompute_G1(const mnt4_G1 &P)
void consume_newline(std::istream &in)
void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
mnt4_GT mnt4_ate_reduced_pairing(const mnt4_G1 &P, const mnt4_G2 &Q)
#define T(meth, val, expected)
Definition test_zm.cpp:19
Definition lib.h:43
std::vector< mnt4_affine_ate_coeffs > coeffs
bool operator==(const mnt4_ate_G1_precomp &other) const
std::vector< mnt4_ate_add_coeffs > add_coeffs
std::vector< mnt4_ate_dbl_coeffs > dbl_coeffs
bool operator==(const mnt4_ate_G2_precomp &other) const
bool operator==(const mnt4_ate_add_coeffs &other) const
bool operator==(const mnt4_ate_dbl_coeffs &other) const
#define R
#define A
int bit
Definition yubihsm.h:566