Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
mnt6_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 mnt6_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, mnt6_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 mnt6_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, mnt6_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 mnt6_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, mnt6_ate_add_coeffs &ac)
93{
94 in >> ac.c_L1;
96 in >> ac.c_RZ;
97
98 return in;
99}
100
101
103{
104 return (this->QX == other.QX &&
105 this->QY == other.QY &&
106 this->QY2 == other.QY2 &&
107 this->QX_over_twist == other.QX_over_twist &&
108 this->QY_over_twist == other.QY_over_twist &&
109 this->dbl_coeffs == other.dbl_coeffs &&
110 this->add_coeffs == other.add_coeffs);
111}
112
113std::ostream& operator<<(std::ostream& out, const mnt6_ate_G2_precomp &prec_Q)
114{
115 out << prec_Q.QX << OUTPUT_SEPARATOR
116 << prec_Q.QY << OUTPUT_SEPARATOR
117 << prec_Q.QY2 << OUTPUT_SEPARATOR
119 << prec_Q.QY_over_twist << "\n";
120 out << prec_Q.dbl_coeffs.size() << "\n";
121 for (const mnt6_ate_dbl_coeffs &dc : prec_Q.dbl_coeffs)
122 {
123 out << dc << OUTPUT_NEWLINE;
124 }
125 out << prec_Q.add_coeffs.size() << "\n";
126 for (const mnt6_ate_add_coeffs &ac : prec_Q.add_coeffs)
127 {
128 out << ac << OUTPUT_NEWLINE;
129 }
130
131 return out;
132}
133
134std::istream& operator>>(std::istream& in, mnt6_ate_G2_precomp &prec_Q)
135{
136 in >> prec_Q.QX;
138 in >> prec_Q.QY;
140 in >> prec_Q.QY2;
142 in >> prec_Q.QX_over_twist;
144 in >> prec_Q.QY_over_twist;
145 consume_newline(in);
146
147 prec_Q.dbl_coeffs.clear();
148 size_t dbl_s;
149 in >> dbl_s;
150 consume_newline(in);
151
152 prec_Q.dbl_coeffs.reserve(dbl_s);
153
154 for (size_t i = 0; i < dbl_s; ++i)
155 {
157 in >> dc;
159 prec_Q.dbl_coeffs.emplace_back(dc);
160 }
161
162 prec_Q.add_coeffs.clear();
163 size_t add_s;
164 in >> add_s;
165 consume_newline(in);
166
167 prec_Q.add_coeffs.reserve(add_s);
168
169 for (size_t i = 0; i < add_s; ++i)
170 {
172 in >> ac;
174 prec_Q.add_coeffs.emplace_back(ac);
175 }
176
177 return in;
178}
179
180/* final exponentiations */
181
183{
184 enter_block("Call to mnt6_final_exponentiation_last_chunk");
185 const mnt6_Fq6 elt_q = elt.Frobenius_map(1);
187 mnt6_Fq6 w0_part;
189 {
191 } else {
193 }
194 mnt6_Fq6 result = w1_part * w0_part;
195 leave_block("Call to mnt6_final_exponentiation_last_chunk");
196
197 return result;
198}
199
201{
202 enter_block("Call to mnt6_final_exponentiation_first_chunk");
203
204 /* (q^3-1)*(q+1) */
205
206 /* elt_q3 = elt^(q^3) */
207 const mnt6_Fq6 elt_q3 = elt.Frobenius_map(3);
208 /* elt_q3_over_elt = elt^(q^3-1) */
209 const mnt6_Fq6 elt_q3_over_elt = elt_q3 * elt_inv;
210 /* alpha = elt^((q^3-1) * q) */
211 const mnt6_Fq6 alpha = elt_q3_over_elt.Frobenius_map(1);
212 /* beta = elt^((q^3-1)*(q+1) */
213 const mnt6_Fq6 beta = alpha * elt_q3_over_elt;
214 leave_block("Call to mnt6_final_exponentiation_first_chunk");
215 return beta;
216}
217
219{
220 enter_block("Call to mnt6_final_exponentiation");
221 const mnt6_Fq6 elt_inv = elt.inverse();
222 const mnt6_Fq6 elt_to_first_chunk = mnt6_final_exponentiation_first_chunk(elt, elt_inv);
223 const mnt6_Fq6 elt_inv_to_first_chunk = mnt6_final_exponentiation_first_chunk(elt_inv, elt);
224 mnt6_GT result = mnt6_final_exponentiation_last_chunk(elt_to_first_chunk, elt_inv_to_first_chunk);
225 leave_block("Call to mnt6_final_exponentiation");
226
227 return result;
228}
229
230/* affine ate miller loop */
231
233{
234 enter_block("Call to mnt6_affine_ate_precompute_G1");
235
236 mnt6_G1 Pcopy = P;
237 Pcopy.to_affine_coordinates();
238
240 result.PX = Pcopy.X;
241 result.PY = Pcopy.Y;
242 result.PY_twist_squared = Pcopy.Y * mnt6_twist.squared();
243
244 leave_block("Call to mnt6_affine_ate_precompute_G1");
245 return result;
246}
247
249{
250 enter_block("Call to mnt6_affine_ate_precompute_G2");
251
252 mnt6_G2 Qcopy(Q);
253 Qcopy.to_affine_coordinates();
254
256 result.QX = Qcopy.X;
257 result.QY = Qcopy.Y;
258
259 mnt6_Fq3 RX = Qcopy.X;
260 mnt6_Fq3 RY = Qcopy.Y;
261
263 bool found_nonzero = false;
264
265 std::vector<long> NAF = find_wnaf(1, loop_count);
266 for (long i = NAF.size() - 1; i >= 0; --i)
267 {
268 if (!found_nonzero)
269 {
270 /* this skips the MSB itself */
271 found_nonzero |= (NAF[i] != 0);
272 continue;
273 }
274
276 c.old_RX = RX;
277 c.old_RY = RY;
278 mnt6_Fq3 old_RX_2 = c.old_RX.squared();
279 c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt6_twist_coeff_a) * (c.old_RY + c.old_RY).inverse();
281 c.gamma_X = c.gamma * c.old_RX;
282 result.coeffs.push_back(c);
283
284 RX = c.gamma.squared() - (c.old_RX+c.old_RX);
285 RY = c.gamma * (c.old_RX - RX) - c.old_RY;
286
287 if (NAF[i] != 0)
288 {
290 c.old_RX = RX;
291 c.old_RY = RY;
292 if (NAF[i] > 0)
293 {
294 c.gamma = (c.old_RY - result.QY) * (c.old_RX - result.QX).inverse();
295 }
296 else
297 {
298 c.gamma = (c.old_RY + result.QY) * (c.old_RX - result.QX).inverse();
299 }
301 c.gamma_X = c.gamma * result.QX;
302 result.coeffs.push_back(c);
303
304 RX = c.gamma.squared() - (c.old_RX+result.QX);
305 RY = c.gamma * (c.old_RX - RX) - c.old_RY;
306 }
307 }
308
309 /* TODO: maybe handle neg
310 if (mnt6_ate_is_loop_count_neg)
311 {
312 mnt6_ate_add_coeffs ac;
313 mnt6_affine_ate_dbl_coeffs c;
314 c.old_RX = RX;
315 c.old_RY = -RY;
316 old_RX_2 = c.old_RY.squared();
317 c.gamma = (old_RX_2 + old_RX_2 + old_RX_2 + mnt6_coeff_a) * (c.old_RY + c.old_RY).inverse();
318 c.gamma_twist = c.gamma * mnt6_twist;
319 c.gamma_X = c.gamma * c.old_RX;
320 result.coeffs.push_back(c);
321 }
322 */
323
324 leave_block("Call to mnt6_affine_ate_precompute_G2");
325 return result;
326}
327
330{
331 enter_block("Call to mnt6_affine_ate_miller_loop");
332
334
336 bool found_nonzero = false;
337 size_t idx = 0;
338
339 std::vector<long> NAF = find_wnaf(1, loop_count);
340 for (long i = NAF.size() - 1; i >= 0; --i)
341 {
342 if (!found_nonzero)
343 {
344 /* this skips the MSB itself */
345 found_nonzero |= (NAF[i] != 0);
346 continue;
347 }
348
349 /* code below gets executed for all bits (EXCEPT the MSB itself) of
350 mnt6_param_p (skipping leading zeros) in MSB to LSB
351 order */
352 mnt6_affine_ate_coeffs c = prec_Q.coeffs[idx++];
353
354 mnt6_Fq6 g_RR_at_P = mnt6_Fq6(prec_P.PY_twist_squared,
355 - prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
356 f = f.squared().mul_by_2345(g_RR_at_P);
357
358 if (NAF[i] != 0)
359 {
360 mnt6_affine_ate_coeffs c = prec_Q.coeffs[idx++];
361 mnt6_Fq6 g_RQ_at_P;
362 if (NAF[i] > 0)
363 {
364 g_RQ_at_P = mnt6_Fq6(prec_P.PY_twist_squared,
365 - prec_P.PX * c.gamma_twist + c.gamma_X - prec_Q.QY);
366 }
367 else
368 {
369 g_RQ_at_P = mnt6_Fq6(prec_P.PY_twist_squared,
370 - prec_P.PX * c.gamma_twist + c.gamma_X + prec_Q.QY);
371 }
372 f = f.mul_by_2345(g_RQ_at_P);
373 }
374
375 }
376
377 /* TODO: maybe handle neg
378 if (mnt6_ate_is_loop_count_neg)
379 {
380 // TODO:
381 mnt6_affine_ate_coeffs ac = prec_Q.coeffs[idx++];
382 mnt6_Fq6 g_RnegR_at_P = mnt6_Fq6(prec_P.PY_twist_squared,
383 - prec_P.PX * c.gamma_twist + c.gamma_X - c.old_RY);
384 f = (f * g_RnegR_at_P).inverse();
385 }
386 */
387
388 leave_block("Call to mnt6_affine_ate_miller_loop");
389
390 return f;
391}
392
393/* ate pairing */
394
400
401 void print() const
402 {
403 printf("extended mnt6_G2 projective X/Y/Z/T:\n");
404 X.print();
405 Y.print();
406 Z.print();
407 T.print();
408 }
409
410 void test_invariant() const
411 {
412 assert(T == Z.squared());
413 }
414};
415
418{
419 const mnt6_Fq3 X = current.X, Y = current.Y, Z = current.Z, T = current.T;
420
421 const mnt6_Fq3 A = T.squared(); // A = T1^2
422 const mnt6_Fq3 B = X.squared(); // B = X1^2
423 const mnt6_Fq3 C = Y.squared(); // C = Y1^2
424 const mnt6_Fq3 D = C.squared(); // D = C^2
425 const mnt6_Fq3 E = (X+C).squared() - B - D; // E = (X1+C)^2-B-D
426 const mnt6_Fq3 F = (B+B+B) + mnt6_twist_coeff_a * A; // F = 3*B + a *A
427 const mnt6_Fq3 G = F.squared(); // G = F^2
428
429 current.X = -(E+E+E+E) + G; // X3 = -4*E+G
430 current.Y = -mnt6_Fq("8")*D + F*(E+E-current.X); // Y3 = -8*D+F*(2*E-X3)
431 current.Z = (Y+Z).squared() - C - Z.squared(); // Z3 = (Y1+Z1)^2-C-Z1^2
432 current.T = current.Z.squared(); // T3 = Z3^2
433
434 dc.c_H = (current.Z + T).squared() - current.T - A; // H = (Z3+T1)^2-T3-A
435 dc.c_4C = C+C+C+C; // fourC = 4*C
436 dc.c_J = (F+T).squared() - G - A; // J = (F+T1)^2-G-A
437 dc.c_L = (F+X).squared() - G - B; // L = (F+X1)^2-G-B
438
439#ifdef DEBUG
440 current.test_invariant();
441#endif
442}
443
444void mixed_addition_step_for_flipped_miller_loop(const mnt6_Fq3 base_X, const mnt6_Fq3 base_Y, const mnt6_Fq3 base_Y_squared,
447{
448 const mnt6_Fq3 X1 = current.X, Y1 = current.Y, Z1 = current.Z, T1 = current.T;
449 const mnt6_Fq3 &x2 = base_X, &y2 = base_Y, &y2_squared = base_Y_squared;
450
451 const mnt6_Fq3 B = x2 * T1; // B = x2 * T1
452 const mnt6_Fq3 D = ((y2 + Z1).squared() - y2_squared - T1) * T1; // D = ((y2 + Z1)^2 - y2squared - T1) * T1
453 const mnt6_Fq3 H = B - X1; // H = B - X1
454 const mnt6_Fq3 I = H.squared(); // I = H^2
455 const mnt6_Fq3 E = I + I + I + I; // E = 4*I
456 const mnt6_Fq3 J = H * E; // J = H * E
457 const mnt6_Fq3 V = X1 * E; // V = X1 * E
458 const mnt6_Fq3 L1 = D - (Y1 + Y1); // L1 = D - 2 * Y1
459
460 current.X = L1.squared() - J - (V+V); // X3 = L1^2 - J - 2*V
461 current.Y = L1 * (V-current.X) - (Y1+Y1) * J; // Y3 = L1 * (V-X3) - 2*Y1 * J
462 current.Z = (Z1+H).squared() - T1 - I; // Z3 = (Z1 + H)^2 - T1 - I
463 current.T = current.Z.squared(); // T3 = Z3^2
464
465 ac.c_L1 = L1;
466 ac.c_RZ = current.Z;
467#ifdef DEBUG
468 current.test_invariant();
469#endif
470}
471
473{
474 enter_block("Call to mnt6_ate_precompute_G1");
475
476 mnt6_G1 Pcopy = P;
477 Pcopy.to_affine_coordinates();
478
479 mnt6_ate_G1_precomp result;
480 result.PX = Pcopy.X;
481 result.PY = Pcopy.Y;
482 result.PX_twist = Pcopy.X * mnt6_twist;
483 result.PY_twist = Pcopy.Y * mnt6_twist;
484
485 leave_block("Call to mnt6_ate_precompute_G1");
486 return result;
487}
488
490{
491 enter_block("Call to mnt6_ate_precompute_G2");
492
493 mnt6_G2 Qcopy(Q);
494 Qcopy.to_affine_coordinates();
495
496 mnt6_Fq3 mnt6_twist_inv = mnt6_twist.inverse(); // could add to global params if needed
497
498 mnt6_ate_G2_precomp result;
499 result.QX = Qcopy.X;
500 result.QY = Qcopy.Y;
501 result.QY2 = Qcopy.Y.squared();
502 result.QX_over_twist = Qcopy.X * mnt6_twist_inv;
503 result.QY_over_twist = Qcopy.Y * mnt6_twist_inv;
504
506 R.X = Qcopy.X;
507 R.Y = Qcopy.Y;
508 R.Z = mnt6_Fq3::one();
509 R.T = mnt6_Fq3::one();
510
512 bool found_one = false;
513 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
514 {
515 const bool bit = loop_count.test_bit(i);
516
517 if (!found_one)
518 {
519 /* this skips the MSB itself */
520 found_one |= bit;
521 continue;
522 }
523
526 result.dbl_coeffs.push_back(dc);
527
528 if (bit)
529 {
531 mixed_addition_step_for_flipped_miller_loop(result.QX, result.QY, result.QY2, R, ac);
532 result.add_coeffs.push_back(ac);
533 }
534 }
535
537 {
538 mnt6_Fq3 RZ_inv = R.Z.inverse();
539 mnt6_Fq3 RZ2_inv = RZ_inv.squared();
540 mnt6_Fq3 RZ3_inv = RZ2_inv * RZ_inv;
541 mnt6_Fq3 minus_R_affine_X = R.X * RZ2_inv;
542 mnt6_Fq3 minus_R_affine_Y = - R.Y * RZ3_inv;
543 mnt6_Fq3 minus_R_affine_Y2 = minus_R_affine_Y.squared();
545 mixed_addition_step_for_flipped_miller_loop(minus_R_affine_X, minus_R_affine_Y, minus_R_affine_Y2, R, ac);
546 result.add_coeffs.push_back(ac);
547 }
548
549 leave_block("Call to mnt6_ate_precompute_G2");
550 return result;
551}
552
554 const mnt6_ate_G2_precomp &prec_Q)
555{
556 enter_block("Call to mnt6_ate_miller_loop");
557
558 mnt6_Fq3 L1_coeff = mnt6_Fq3(prec_P.PX, mnt6_Fq::zero(), mnt6_Fq::zero()) - prec_Q.QX_over_twist;
559
561
562 bool found_one = false;
563 size_t dbl_idx = 0;
564 size_t add_idx = 0;
565
567
568 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
569 {
570 const bool bit = loop_count.test_bit(i);
571
572 if (!found_one)
573 {
574 /* this skips the MSB itself */
575 found_one |= bit;
576 continue;
577 }
578
579 /* code below gets executed for all bits (EXCEPT the MSB itself) of
580 mnt6_param_p (skipping leading zeros) in MSB to LSB
581 order */
582 mnt6_ate_dbl_coeffs dc = prec_Q.dbl_coeffs[dbl_idx++];
583
584 mnt6_Fq6 g_RR_at_P = mnt6_Fq6(- dc.c_4C - dc.c_J * prec_P.PX_twist + dc.c_L,
585 dc.c_H * prec_P.PY_twist);
586 f = f.squared() * g_RR_at_P;
587
588 if (bit)
589 {
590 mnt6_ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
591 mnt6_Fq6 g_RQ_at_P = mnt6_Fq6(ac.c_RZ * prec_P.PY_twist,
592 -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
593 f = f * g_RQ_at_P;
594 }
595
596 }
597
599 {
600 mnt6_ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
601 mnt6_Fq6 g_RnegR_at_P = mnt6_Fq6(ac.c_RZ * prec_P.PY_twist,
602 -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
603 f = (f * g_RnegR_at_P).inverse();
604 }
605
606 leave_block("Call to mnt6_ate_miller_loop");
607
608 return f;
609}
610
612 const mnt6_ate_G2_precomp &prec_Q1,
613 const mnt6_ate_G1_precomp &prec_P2,
614 const mnt6_ate_G2_precomp &prec_Q2)
615{
616 enter_block("Call to mnt6_ate_double_miller_loop");
617
618 mnt6_Fq3 L1_coeff1 = mnt6_Fq3(prec_P1.PX, mnt6_Fq::zero(), mnt6_Fq::zero()) - prec_Q1.QX_over_twist;
619 mnt6_Fq3 L1_coeff2 = mnt6_Fq3(prec_P2.PX, mnt6_Fq::zero(), mnt6_Fq::zero()) - prec_Q2.QX_over_twist;
620
622
623 bool found_one = false;
624 size_t dbl_idx = 0;
625 size_t add_idx = 0;
626
628
629 for (long i = loop_count.max_bits() - 1; i >= 0; --i)
630 {
631 const bool bit = loop_count.test_bit(i);
632
633 if (!found_one)
634 {
635 /* this skips the MSB itself */
636 found_one |= bit;
637 continue;
638 }
639
640 /* code below gets executed for all bits (EXCEPT the MSB itself) of
641 mnt6_param_p (skipping leading zeros) in MSB to LSB
642 order */
643 mnt6_ate_dbl_coeffs dc1 = prec_Q1.dbl_coeffs[dbl_idx];
644 mnt6_ate_dbl_coeffs dc2 = prec_Q2.dbl_coeffs[dbl_idx];
645 ++dbl_idx;
646
647 mnt6_Fq6 g_RR_at_P1 = mnt6_Fq6(- dc1.c_4C - dc1.c_J * prec_P1.PX_twist + dc1.c_L,
648 dc1.c_H * prec_P1.PY_twist);
649
650 mnt6_Fq6 g_RR_at_P2 = mnt6_Fq6(- dc2.c_4C - dc2.c_J * prec_P2.PX_twist + dc2.c_L,
651 dc2.c_H * prec_P2.PY_twist);
652
653 f = f.squared() * g_RR_at_P1 * g_RR_at_P2;
654
655 if (bit)
656 {
657 mnt6_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
658 mnt6_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
659 ++add_idx;
660
661 mnt6_Fq6 g_RQ_at_P1 = mnt6_Fq6(ac1.c_RZ * prec_P1.PY_twist,
662 -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
663 mnt6_Fq6 g_RQ_at_P2 = mnt6_Fq6(ac2.c_RZ * prec_P2.PY_twist,
664 -(prec_Q2.QY_over_twist * ac2.c_RZ + L1_coeff2 * ac2.c_L1));
665
666 f = f * g_RQ_at_P1 * g_RQ_at_P2;
667 }
668 }
669
671 {
672 mnt6_ate_add_coeffs ac1 = prec_Q1.add_coeffs[add_idx];
673 mnt6_ate_add_coeffs ac2 = prec_Q2.add_coeffs[add_idx];
674 ++add_idx;
675 mnt6_Fq6 g_RnegR_at_P1 = mnt6_Fq6(ac1.c_RZ * prec_P1.PY_twist,
676 -(prec_Q1.QY_over_twist * ac1.c_RZ + L1_coeff1 * ac1.c_L1));
677 mnt6_Fq6 g_RnegR_at_P2 = mnt6_Fq6(ac2.c_RZ * prec_P2.PY_twist,
678 -(prec_Q2.QY_over_twist * ac2.c_RZ + L1_coeff2 * ac2.c_L1));
679
680 f = (f * g_RnegR_at_P1 * g_RnegR_at_P2).inverse();
681 }
682
683 leave_block("Call to mnt6_ate_double_miller_loop");
684
685 return f;
686}
687
689{
690 enter_block("Call to mnt6_ate_pairing");
693 mnt6_Fq6 result = mnt6_ate_miller_loop(prec_P, prec_Q);
694 leave_block("Call to mnt6_ate_pairing");
695 return result;
696}
697
699{
700 enter_block("Call to mnt6_ate_reduced_pairing");
701 const mnt6_Fq6 f = mnt6_ate_pairing(P, Q);
702 const mnt6_GT result = mnt6_final_exponentiation(f);
703 leave_block("Call to mnt6_ate_reduced_pairing");
704 return result;
705}
706
711
716
718 const mnt6_G2_precomp &prec_Q)
719{
720 return mnt6_ate_miller_loop(prec_P, prec_Q);
721}
722
724 const mnt6_G2_precomp &prec_Q1,
725 const mnt6_G1_precomp &prec_P2,
726 const mnt6_G2_precomp &prec_Q2)
727{
728 return mnt6_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
729}
730
732 const mnt6_G2 &Q)
733{
734 return mnt6_ate_pairing(P, Q);
735}
736
738 const mnt6_G2 &Q)
739{
740 return mnt6_ate_reduced_pairing(P, Q);
741}
742
752
753} // libff
Fp3_model inverse() const
Fp3_model squared() const
static Fp3_model< n, modulus > one()
void print() const
Definition fp3.hpp:55
Fp6_2over3_model inverse() const
Fp6_2over3_model cyclotomic_exp(const bigint< m > &exponent) const
static Fp6_2over3_model< n, modulus > one()
Fp6_2over3_model Frobenius_map(unsigned long power) const
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 mnt6_g1.cpp:72
mnt6_Fq3 X
Definition mnt6_g2.hpp:45
mnt6_Fq3 Y
Definition mnt6_g2.hpp:45
void to_affine_coordinates()
Definition mnt6_g2.cpp:93
#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
Fp6_2over3_model< mnt6_q_limbs, mnt6_modulus_q > mnt6_Fq6
Definition mnt6_init.hpp:38
mnt6_GT mnt6_final_exponentiation(const mnt6_Fq6 &elt)
mnt6_Fq6 mnt6_ate_miller_loop(const mnt6_ate_G1_precomp &prec_P, const mnt6_ate_G2_precomp &prec_Q)
void consume_OUTPUT_NEWLINE(std::istream &in)
bigint< mnt6_q_limbs > mnt6_final_exponent_last_chunk_abs_of_w0
Definition mnt6_init.cpp:38
mnt6_Fq6 mnt6_final_exponentiation_last_chunk(const mnt6_Fq6 &elt, const mnt6_Fq6 &elt_inv)
mnt6_ate_G1_precomp mnt6_ate_precompute_G1(const mnt6_G1 &P)
mnt6_GT mnt6_ate_reduced_pairing(const mnt6_G1 &P, const mnt6_G2 &Q)
mnt6_ate_G2_precomp mnt6_ate_precompute_G2(const mnt6_G2 &Q)
mnt6_GT mnt6_reduced_pairing(const mnt6_G1 &P, const mnt6_G2 &Q)
std::istream & operator>>(std::istream &in, alt_bn128_G1 &g)
mnt6_Fq6 mnt6_miller_loop(const mnt6_G1_precomp &prec_P, const mnt6_G2_precomp &prec_Q)
void consume_OUTPUT_SEPARATOR(std::istream &in)
std::ostream & operator<<(std::ostream &out, const alt_bn128_G1 &g)
bool mnt6_final_exponent_last_chunk_is_w0_neg
Definition mnt6_init.cpp:39
void enter_block(const std::string &msg, const bool indent)
mnt6_Fq6 mnt6_double_miller_loop(const mnt6_G1_precomp &prec_P1, const mnt6_G2_precomp &prec_Q1, const mnt6_G1_precomp &prec_P2, const mnt6_G2_precomp &prec_Q2)
void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
mnt6_Fq6 mnt6_ate_pairing(const mnt6_G1 &P, const mnt6_G2 &Q)
bigint< mnt6_q_limbs > mnt6_final_exponent_last_chunk_w1
Definition mnt6_init.cpp:40
mnt6_Fq6 mnt6_pairing(const mnt6_G1 &P, const mnt6_G2 &Q)
Fp_model< mnt6_q_limbs, mnt6_modulus_q > mnt6_Fq
Definition mnt6_init.hpp:36
mnt6_Fq6 mnt6_final_exponentiation_first_chunk(const mnt6_Fq6 &elt, const mnt6_Fq6 &elt_inv)
mnt6_Fq3 mnt6_twist
Definition mnt6_init.cpp:23
std::vector< long > find_wnaf(const size_t window_size, const bigint< n > &scalar)
mnt6_Fq6 mnt6_ate_double_miller_loop(const mnt6_ate_G1_precomp &prec_P1, const mnt6_ate_G2_precomp &prec_Q1, const mnt6_ate_G1_precomp &prec_P2, const mnt6_ate_G2_precomp &prec_Q2)
bool mnt6_ate_is_loop_count_neg
Definition mnt6_init.cpp:36
mnt6_affine_ate_G1_precomputation mnt6_affine_ate_precompute_G1(const mnt6_G1 &P)
mnt6_Fq3 mnt6_twist_coeff_a
Definition mnt6_init.cpp:24
void leave_block(const std::string &msg, const bool indent)
Fp3_model< mnt6_q_limbs, mnt6_modulus_q > mnt6_Fq3
Definition mnt6_init.hpp:37
mnt6_GT mnt6_affine_reduced_pairing(const mnt6_G1 &P, const mnt6_G2 &Q)
mnt6_G1_precomp mnt6_precompute_G1(const mnt6_G1 &P)
void consume_newline(std::istream &in)
mnt6_Fq6 mnt6_affine_ate_miller_loop(const mnt6_affine_ate_G1_precomputation &prec_P, const mnt6_affine_ate_G2_precomputation &prec_Q)
mnt6_affine_ate_G2_precomputation mnt6_affine_ate_precompute_G2(const mnt6_G2 &Q)
bigint< mnt6_q_limbs > mnt6_ate_loop_count
Definition mnt6_init.cpp:35
mnt6_G2_precomp mnt6_precompute_G2(const mnt6_G2 &Q)
void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base, alt_bn128_G2 &current, alt_bn128_ate_ell_coeffs &c)
#define T(meth, val, expected)
Definition test_zm.cpp:19
Definition lib.h:43
std::vector< mnt6_affine_ate_coeffs > coeffs
bool operator==(const mnt6_ate_G1_precomp &other) const
std::vector< mnt6_ate_add_coeffs > add_coeffs
bool operator==(const mnt6_ate_G2_precomp &other) const
std::vector< mnt6_ate_dbl_coeffs > dbl_coeffs
bool operator==(const mnt6_ate_add_coeffs &other) const
bool operator==(const mnt6_ate_dbl_coeffs &other) const
#define R
#define A
int bit
Definition yubihsm.h:566