1use alloc::vec::Vec;
2
3use crate::{
4 arith::U256,
5 fields::{FieldElement, Fq, Fq2, Fq12, Fr, const_fq, fq2_nonresidue},
6};
7use core::{
8 fmt,
9 ops::{Add, Mul, Neg, Sub},
10};
11use rand::Rng;
12
13#[cfg(feature = "rustc-serialize")]
14use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
15
16const ATE_LOOP_COUNT_NAF: [u8; 64] = [
22 1, 0, 1, 0, 0, 0, 3, 0, 3, 0, 0, 0, 3, 0, 1, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 1, 0,
23 0, 3, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 3, 0, 3, 0, 0, 1, 0, 0, 0, 3, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0,
24];
25
26pub trait GroupElement:
27 Sized
28 + Copy
29 + Clone
30 + PartialEq
31 + Eq
32 + fmt::Debug
33 + Add<Output = Self>
34 + Sub<Output = Self>
35 + Neg<Output = Self>
36 + Mul<Fr, Output = Self>
37{
38 fn zero() -> Self;
39 fn one() -> Self;
40 fn random<R: Rng>(rng: &mut R) -> Self;
41 fn is_zero(&self) -> bool;
42 fn double(&self) -> Self;
43}
44
45pub trait GroupParams: Sized + fmt::Debug {
46 #[cfg(feature = "rustc-serialize")]
47 type Base: FieldElement + Decodable + Encodable;
48 #[cfg(not(feature = "rustc-serialize"))]
49 type Base: FieldElement;
50
51 fn name() -> &'static str;
52 fn one() -> G<Self>;
53 fn coeff_b() -> Self::Base;
54 fn check_order() -> bool {
55 false
56 }
57}
58
59#[repr(C)]
60pub struct G<P: GroupParams> {
61 x: P::Base,
62 y: P::Base,
63 z: P::Base,
64}
65
66impl<P: GroupParams> G<P> {
67 pub fn new(x: P::Base, y: P::Base, z: P::Base) -> Self {
68 G { x, y, z }
69 }
70
71 pub fn x(&self) -> &P::Base {
72 &self.x
73 }
74
75 pub fn x_mut(&mut self) -> &mut P::Base {
76 &mut self.x
77 }
78
79 pub fn y(&self) -> &P::Base {
80 &self.y
81 }
82
83 pub fn y_mut(&mut self) -> &mut P::Base {
84 &mut self.y
85 }
86
87 pub fn z(&self) -> &P::Base {
88 &self.z
89 }
90
91 pub fn z_mut(&mut self) -> &mut P::Base {
92 &mut self.z
93 }
94}
95
96#[derive(Debug)]
97pub struct AffineG<P: GroupParams> {
98 x: P::Base,
99 y: P::Base,
100}
101
102#[derive(Debug)]
103pub enum Error {
104 NotOnCurve,
105 NotInSubgroup,
106}
107
108impl<P: GroupParams> AffineG<P> {
109 pub fn new(x: P::Base, y: P::Base) -> Result<Self, Error> {
110 if y.squared() == (x.squared() * x) + P::coeff_b() {
111 if P::check_order() {
112 let p: G<P> = G {
113 x,
114 y,
115 z: P::Base::one(),
116 };
117
118 if (p * (-Fr::one())) + p != G::zero() {
119 return Err(Error::NotInSubgroup);
120 }
121 }
122
123 Ok(AffineG { x, y })
124 } else {
125 Err(Error::NotOnCurve)
126 }
127 }
128
129 pub fn x(&self) -> &P::Base {
130 &self.x
131 }
132
133 pub fn x_mut(&mut self) -> &mut P::Base {
134 &mut self.x
135 }
136
137 pub fn y(&self) -> &P::Base {
138 &self.y
139 }
140
141 pub fn y_mut(&mut self) -> &mut P::Base {
142 &mut self.y
143 }
144}
145
146impl<P: GroupParams> PartialEq for AffineG<P> {
147 fn eq(&self, other: &Self) -> bool {
148 self.x == other.x && self.y == other.y
149 }
150}
151
152impl<P: GroupParams> Eq for AffineG<P> {}
153
154impl<P: GroupParams> fmt::Debug for G<P> {
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 write!(f, "{}({:?}, {:?}, {:?})", P::name(), self.x, self.y, self.z)
157 }
158}
159
160impl<P: GroupParams> Clone for G<P> {
161 fn clone(&self) -> Self {
162 *self
163 }
164}
165
166impl<P: GroupParams> Copy for G<P> {}
167
168impl<P: GroupParams> Clone for AffineG<P> {
169 fn clone(&self) -> Self {
170 *self
171 }
172}
173
174impl<P: GroupParams> Copy for AffineG<P> {}
175
176impl<P: GroupParams> PartialEq for G<P> {
177 fn eq(&self, other: &Self) -> bool {
178 if self.is_zero() {
179 return other.is_zero();
180 }
181
182 if other.is_zero() {
183 return false;
184 }
185
186 let z1_squared = self.z.squared();
187 let z2_squared = other.z.squared();
188
189 if self.x * z2_squared != other.x * z1_squared {
190 return false;
191 }
192
193 let z1_cubed = self.z * z1_squared;
194 let z2_cubed = other.z * z2_squared;
195
196 if self.y * z2_cubed != other.y * z1_cubed {
197 return false;
198 }
199
200 true
201 }
202}
203impl<P: GroupParams> Eq for G<P> {}
204
205impl<P: GroupParams> G<P> {
206 pub fn to_affine(self) -> Option<AffineG<P>> {
207 if self.z.is_zero() {
208 None
209 } else if self.z == P::Base::one() {
210 Some(AffineG {
211 x: self.x,
212 y: self.y,
213 })
214 } else {
215 let zinv = self.z.inverse().unwrap();
216 let zinv_squared = zinv.squared();
217
218 Some(AffineG {
219 x: self.x * zinv_squared,
220 y: self.y * (zinv_squared * zinv),
221 })
222 }
223 }
224}
225
226impl<P: GroupParams> AffineG<P> {
227 pub fn to_jacobian(self) -> G<P> {
228 G {
229 x: self.x,
230 y: self.y,
231 z: P::Base::one(),
232 }
233 }
234}
235
236#[cfg(feature = "rustc-serialize")]
237impl<P: GroupParams> Encodable for G<P> {
238 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
239 if self.is_zero() {
240 let l: u8 = 0;
241 l.encode(s)
242 } else {
243 let l: u8 = 4;
244 l.encode(s)?;
245 self.to_affine().unwrap().encode(s)
246 }
247 }
248}
249
250#[cfg(feature = "rustc-serialize")]
251impl<P: GroupParams> Encodable for AffineG<P> {
252 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
253 self.x.encode(s)?;
254 self.y.encode(s)?;
255
256 Ok(())
257 }
258}
259
260#[cfg(feature = "rustc-serialize")]
261impl<P: GroupParams> Decodable for G<P> {
262 fn decode<S: Decoder>(s: &mut S) -> Result<G<P>, S::Error> {
263 let l = u8::decode(s)?;
264 if l == 0 {
265 Ok(G::zero())
266 } else if l == 4 {
267 Ok(AffineG::decode(s)?.to_jacobian())
268 } else {
269 Err(s.error("invalid leading byte for uncompressed group element"))
270 }
271 }
272}
273
274#[cfg(feature = "rustc-serialize")]
275impl<P: GroupParams> Decodable for AffineG<P> {
276 fn decode<S: Decoder>(s: &mut S) -> Result<AffineG<P>, S::Error> {
277 let x = P::Base::decode(s)?;
278 let y = P::Base::decode(s)?;
279
280 Self::new(x, y).map_err(|e| match e {
281 Error::NotOnCurve => s.error("point is not on the curve"),
282 Error::NotInSubgroup => s.error("point is not in the subgroup"),
283 })
284 }
285}
286
287impl<P: GroupParams> GroupElement for G<P> {
288 fn zero() -> Self {
289 G {
290 x: P::Base::zero(),
291 y: P::Base::one(),
292 z: P::Base::zero(),
293 }
294 }
295
296 fn one() -> Self {
297 P::one()
298 }
299
300 fn random<R: Rng>(rng: &mut R) -> Self {
301 P::one() * Fr::random(rng)
302 }
303
304 fn is_zero(&self) -> bool {
305 self.z.is_zero()
306 }
307
308 fn double(&self) -> Self {
309 let a = self.x.squared();
310 let b = self.y.squared();
311 let c = b.squared();
312 let mut d = (self.x + b).squared() - a - c;
313 d = d + d;
314 let e = a + a + a;
315 let f = e.squared();
316 let x3 = f - (d + d);
317 let mut eight_c = c + c;
318 eight_c = eight_c + eight_c;
319 eight_c = eight_c + eight_c;
320 let y1z1 = self.y * self.z;
321
322 G {
323 x: x3,
324 y: e * (d - x3) - eight_c,
325 z: y1z1 + y1z1,
326 }
327 }
328}
329
330#[allow(clippy::suspicious_arithmetic_impl)]
331impl<P: GroupParams> Mul<Fr> for G<P> {
332 type Output = G<P>;
333
334 fn mul(self, other: Fr) -> G<P> {
335 let mut res = G::zero();
336 let mut found_one = false;
337
338 for i in U256::from(other).bits() {
339 if found_one {
340 res = res.double();
341 }
342
343 if i {
344 found_one = true;
345 res = res + self;
346 }
347 }
348
349 res
350 }
351}
352
353impl<P: GroupParams> Add<G<P>> for G<P> {
354 type Output = G<P>;
355
356 fn add(self, other: G<P>) -> G<P> {
357 if self.is_zero() {
358 return other;
359 }
360
361 if other.is_zero() {
362 return self;
363 }
364
365 let z1_squared = self.z.squared();
366 let z2_squared = other.z.squared();
367 let u1 = self.x * z2_squared;
368 let u2 = other.x * z1_squared;
369 let z1_cubed = self.z * z1_squared;
370 let z2_cubed = other.z * z2_squared;
371 let s1 = self.y * z2_cubed;
372 let s2 = other.y * z1_cubed;
373
374 if u1 == u2 && s1 == s2 {
375 self.double()
376 } else {
377 let h = u2 - u1;
378 let s2_minus_s1 = s2 - s1;
379 let i = (h + h).squared();
380 let j = h * i;
381 let r = s2_minus_s1 + s2_minus_s1;
382 let v = u1 * i;
383 let s1_j = s1 * j;
384 let x3 = r.squared() - j - (v + v);
385
386 G {
387 x: x3,
388 y: r * (v - x3) - (s1_j + s1_j),
389 z: ((self.z + other.z).squared() - z1_squared - z2_squared) * h,
390 }
391 }
392 }
393}
394
395impl<P: GroupParams> Neg for G<P> {
396 type Output = G<P>;
397
398 fn neg(self) -> G<P> {
399 if self.is_zero() {
400 self
401 } else {
402 G {
403 x: self.x,
404 y: -self.y,
405 z: self.z,
406 }
407 }
408 }
409}
410
411impl<P: GroupParams> Neg for AffineG<P> {
412 type Output = AffineG<P>;
413
414 fn neg(self) -> AffineG<P> {
415 AffineG {
416 x: self.x,
417 y: -self.y,
418 }
419 }
420}
421
422impl<P: GroupParams> Sub<G<P>> for G<P> {
423 type Output = G<P>;
424
425 fn sub(self, other: G<P>) -> G<P> {
426 self + (-other)
427 }
428}
429
430#[derive(Debug)]
431pub struct G1Params;
432
433impl GroupParams for G1Params {
434 type Base = Fq;
435
436 fn name() -> &'static str {
437 "G1"
438 }
439
440 fn one() -> G<Self> {
441 G {
442 x: Fq::one(),
443 y: const_fq([
444 0xa6ba871b8b1e1b3a,
445 0x14f1d651eb8e167b,
446 0xccdd46def0f28c58,
447 0x1c14ef83340fbe5e,
448 ]),
449 z: Fq::one(),
450 }
451 }
452
453 fn coeff_b() -> Fq {
454 const_fq([
455 0x7a17caa950ad28d7,
456 0x1f6ac17ae15521b9,
457 0x334bea4e696bd284,
458 0x2a1f6744ce179d8e,
459 ])
460 }
461}
462
463pub type G1 = G<G1Params>;
464
465pub type AffineG1 = AffineG<G1Params>;
466
467#[derive(Debug)]
468pub struct G2Params;
469
470impl GroupParams for G2Params {
471 type Base = Fq2;
472
473 fn name() -> &'static str {
474 "G2"
475 }
476
477 fn one() -> G<Self> {
478 G {
479 x: Fq2::new(
480 const_fq([
481 0x8e83b5d102bc2026,
482 0xdceb1935497b0172,
483 0xfbb8264797811adf,
484 0x19573841af96503b,
485 ]),
486 const_fq([
487 0xafb4737da84c6140,
488 0x6043dd5a5802d8c4,
489 0x09e950fc52a02f86,
490 0x14fef0833aea7b6b,
491 ]),
492 ),
493 y: Fq2::new(
494 const_fq([
495 0x619dfa9d886be9f6,
496 0xfe7fd297f59e9b78,
497 0xff9e1a62231b7dfe,
498 0x28fd7eebae9e4206,
499 ]),
500 const_fq([
501 0x64095b56c71856ee,
502 0xdc57f922327d3cbb,
503 0x55f935be33351076,
504 0x0da4a0e693fd6482,
505 ]),
506 ),
507 z: Fq2::one(),
508 }
509 }
510
511 fn coeff_b() -> Fq2 {
512 Fq2::new(
513 const_fq([
514 0x3bf938e377b802a8,
515 0x020b1b273633535d,
516 0x26b7edf049755260,
517 0x2514c6324384a86d,
518 ]),
519 const_fq([
520 0x38e7ecccd1dcff67,
521 0x65f0b37d93ce0d3e,
522 0xd749d0dd22ac00aa,
523 0x0141b9ce4a688d4d,
524 ]),
525 )
526 }
527
528 fn check_order() -> bool {
529 true
530 }
531}
532
533pub type G2 = G<G2Params>;
534
535pub type AffineG2 = AffineG<G2Params>;
536
537#[cfg(test)]
538mod tests;
539
540#[test]
541fn test_g1() {
542 tests::group_trials::<G1>();
543}
544
545#[test]
546fn test_g2() {
547 tests::group_trials::<G2>();
548}
549
550#[test]
551fn test_affine_jacobian_conversion() {
552 let rng = &mut ::rand::rng();
553
554 assert!(G1::zero().to_affine().is_none());
555 assert!(G2::zero().to_affine().is_none());
556
557 for _ in 0..1000 {
558 let a = G1::one() * Fr::random(rng);
559 let b = a.to_affine().unwrap();
560 let c = b.to_jacobian();
561
562 assert_eq!(a, c);
563 }
564
565 for _ in 0..1000 {
566 let a = G2::one() * Fr::random(rng);
567 let b = a.to_affine().unwrap();
568 let c = b.to_jacobian();
569
570 assert_eq!(a, c);
571 }
572}
573
574#[inline]
575fn twist() -> Fq2 {
576 fq2_nonresidue()
577}
578
579#[inline]
580fn two_inv() -> Fq {
581 const_fq([
582 9781510331150239090,
583 15059239858463337189,
584 10331104244869713732,
585 2249375503248834476,
586 ])
587}
588
589#[inline]
590fn twist_mul_by_q_x() -> Fq2 {
591 Fq2::new(
592 const_fq([
593 13075984984163199792,
594 3782902503040509012,
595 8791150885551868305,
596 1825854335138010348,
597 ]),
598 const_fq([
599 7963664994991228759,
600 12257807996192067905,
601 13179524609921305146,
602 2767831111890561987,
603 ]),
604 )
605}
606
607#[inline]
608fn twist_mul_by_q_y() -> Fq2 {
609 Fq2::new(
610 const_fq([
611 16482010305593259561,
612 13488546290961988299,
613 3578621962720924518,
614 2681173117283399901,
615 ]),
616 const_fq([
617 11661927080404088775,
618 553939530661941723,
619 7860678177968807019,
620 3208568454732775116,
621 ]),
622 )
623}
624
625#[derive(PartialEq, Eq)]
626pub struct EllCoeffs {
627 pub ell_0: Fq2,
628 pub ell_vw: Fq2,
629 pub ell_vv: Fq2,
630}
631
632#[derive(PartialEq, Eq)]
633pub struct G2Precomp {
634 pub q: AffineG<G2Params>,
635 pub coeffs: Vec<EllCoeffs>,
636}
637
638impl G2Precomp {
639 pub fn miller_loop(&self, g1: &AffineG<G1Params>) -> Fq12 {
640 let mut f = Fq12::one();
641
642 let mut idx = 0;
643
644 for i in ATE_LOOP_COUNT_NAF.iter() {
645 let c = &self.coeffs[idx];
646 idx += 1;
647 f = f
648 .squared()
649 .mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
650
651 if *i != 0 {
652 let c = &self.coeffs[idx];
653 idx += 1;
654 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
655 }
656 }
657
658 let c = &self.coeffs[idx];
659 idx += 1;
660 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
661
662 let c = &self.coeffs[idx];
663 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
664
665 f
666 }
667}
668
669pub fn miller_loop_batch(g2_precomputes: &[G2Precomp], g1_vec: &[AffineG<G1Params>]) -> Fq12 {
670 let mut f = Fq12::one();
671
672 let mut idx = 0;
673
674 for i in ATE_LOOP_COUNT_NAF.iter() {
675 f = f.squared();
676 for (g2_precompute, g1) in g2_precomputes.iter().zip(g1_vec.iter()) {
677 let c = &g2_precompute.coeffs[idx];
678 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
679 }
680 idx += 1;
681 if *i != 0 {
682 for (g2_precompute, g1) in g2_precomputes.iter().zip(g1_vec.iter()) {
683 let c = &g2_precompute.coeffs[idx];
684 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
685 }
686 idx += 1;
687 }
688 }
689
690 for (g2_precompute, g1) in g2_precomputes.iter().zip(g1_vec.iter()) {
691 let c = &g2_precompute.coeffs[idx];
692 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
693 }
694 idx += 1;
695 for (g2_precompute, g1) in g2_precomputes.iter().zip(g1_vec.iter()) {
696 let c = &g2_precompute.coeffs[idx];
697 f = f.mul_by_024(c.ell_0, c.ell_vw.scale(g1.y), c.ell_vv.scale(g1.x));
698 }
699 f
700}
701
702#[test]
703fn test_miller_loop() {
704 use crate::fields::Fq6;
705
706 let g1 = G1::one()
707 * Fr::from_str(
708 "18097487326282793650237947474982649264364522469319914492172746413872781676",
709 )
710 .unwrap();
711 let g2 = G2::one()
712 * Fr::from_str(
713 "20390255904278144451778773028944684152769293537511418234311120800877067946",
714 )
715 .unwrap();
716
717 let g1_pre = g1.to_affine().unwrap();
718 let g2_pre = g2.to_affine().unwrap().precompute();
719
720 let gt = g2_pre.miller_loop(&g1_pre);
721
722 let expected: Fq12 = Fq12::new(
723 Fq6::new(
724 Fq2::new(
725 Fq::new(U256([
726 51910954035973319022896381997847359481,
727 49070349125448662928383548013678560320,
728 ]))
729 .unwrap(),
730 Fq::new(U256([
731 150594250655925940766158230906714822921,
732 45067780486977162411874315270532662559,
733 ]))
734 .unwrap(),
735 ),
736 Fq2::new(
737 Fq::new(U256([
738 293313211826787380313097274184299135668,
739 28033688961864567415258173424862015279,
740 ]))
741 .unwrap(),
742 Fq::new(U256([
743 167463228417728651969785007140185669229,
744 7077084888790581611350259269763958251,
745 ]))
746 .unwrap(),
747 ),
748 Fq2::new(
749 Fq::new(U256([
750 166574695108782631900870170909221310910,
751 36301755601680728879208628452507017454,
752 ]))
753 .unwrap(),
754 Fq::new(U256([
755 61790765844042689836493058059938629070,
756 8459680572251855304146082351314233167,
757 ]))
758 .unwrap(),
759 ),
760 ),
761 Fq6::new(
762 Fq2::new(
763 Fq::new(U256([
764 274725556782132290265566702453516000786,
765 47645385003117491559484060631887523335,
766 ]))
767 .unwrap(),
768 Fq::new(U256([
769 218741759704184655717004970623859820160,
770 5768209145436844234600983552836237590,
771 ]))
772 .unwrap(),
773 ),
774 Fq2::new(
775 Fq::new(U256([
776 166365676746880051357185694330614395245,
777 44422629177536239628987108174157680084,
778 ]))
779 .unwrap(),
780 Fq::new(U256([
781 188797990739833756731082975171894736944,
782 643465180603364587407484249282263717,
783 ]))
784 .unwrap(),
785 ),
786 Fq2::new(
787 Fq::new(U256([
788 271144479861903489720584548513988144824,
789 10463758518630442972881156820224659715,
790 ]))
791 .unwrap(),
792 Fq::new(U256([
793 214759070354702766397810519515686065785,
794 63150584453541665372008601383729030318,
795 ]))
796 .unwrap(),
797 ),
798 ),
799 );
800 assert_eq!(gt, expected);
801}
802
803impl AffineG<G2Params> {
804 fn mul_by_q(&self) -> Self {
805 AffineG {
806 x: twist_mul_by_q_x() * self.x.frobenius_map(1),
807 y: twist_mul_by_q_y() * self.y.frobenius_map(1),
808 }
809 }
810
811 pub fn precompute(&self) -> G2Precomp {
812 let mut r = self.to_jacobian();
813
814 let mut coeffs = Vec::with_capacity(102);
815
816 let q_neg = self.neg();
817 for i in ATE_LOOP_COUNT_NAF.iter() {
818 coeffs.push(r.doubling_step_for_flipped_miller_loop());
819
820 if *i == 1 {
821 coeffs.push(r.mixed_addition_step_for_flipped_miller_loop(self));
822 }
823 if *i == 3 {
824 coeffs.push(r.mixed_addition_step_for_flipped_miller_loop(&q_neg));
825 }
826 }
827 let q1 = self.mul_by_q();
828 let q2 = -(q1.mul_by_q());
829
830 coeffs.push(r.mixed_addition_step_for_flipped_miller_loop(&q1));
831 coeffs.push(r.mixed_addition_step_for_flipped_miller_loop(&q2));
832
833 G2Precomp { q: *self, coeffs }
834 }
835}
836
837impl G2 {
838 fn mixed_addition_step_for_flipped_miller_loop(
839 &mut self,
840 base: &AffineG<G2Params>,
841 ) -> EllCoeffs {
842 let d = self.x - self.z * base.x;
843 let e = self.y - self.z * base.y;
844 let f = d.squared();
845 let g = e.squared();
846 let h = d * f;
847 let i = self.x * f;
848 let j = self.z * g + h - (i + i);
849
850 self.x = d * j;
851 self.y = e * (i - j) - h * self.y;
852 self.z = self.z * h;
853
854 EllCoeffs {
855 ell_0: twist() * (e * base.x - d * base.y),
856 ell_vv: e.neg(),
857 ell_vw: d,
858 }
859 }
860
861 fn doubling_step_for_flipped_miller_loop(&mut self) -> EllCoeffs {
862 let a = (self.x * self.y).scale(two_inv());
863 let b = self.y.squared();
864 let c = self.z.squared();
865 let d = c + c + c;
866 let e = G2Params::coeff_b() * d;
867 let f = e + e + e;
868 let g = (b + f).scale(two_inv());
869 let h = (self.y + self.z).squared() - (b + c);
870 let i = e - b;
871 let j = self.x.squared();
872 let e_sq = e.squared();
873
874 self.x = a * (b - f);
875 self.y = g.squared() - (e_sq + e_sq + e_sq);
876 self.z = b * h;
877
878 EllCoeffs {
879 ell_0: twist() * i,
880 ell_vw: h.neg(),
881 ell_vv: j + j + j,
882 }
883 }
884}
885
886#[test]
887fn test_prepared_g2() {
888 let g2 = G2::one()
889 * Fr::from_str(
890 "20390255904278144451778773028944684152769293537511418234311120800877067946",
891 )
892 .unwrap();
893
894 let g2_p = g2.to_affine().unwrap().precompute();
895
896 let expected_g2_p = G2Precomp {
897 q: AffineG {
898 x: Fq2::new(
899 Fq::new(U256([
900 286108132425575157823044300810193365120,
901 40955922372263072279965766273066553545,
902 ]))
903 .unwrap(),
904 Fq::new(U256([
905 51787456028377068413742525949644831103,
906 18727496177066613612143648473641354138,
907 ]))
908 .unwrap(),
909 ),
910 y: Fq2::new(
911 Fq::new(U256([
912 105235307093009526756443741536710213857,
913 56697136982397507595538316605420403515,
914 ]))
915 .unwrap(),
916 Fq::new(U256([
917 329285813328264858787093963282305459902,
918 40620233227497131789363095249389429612,
919 ]))
920 .unwrap(),
921 ),
922 },
923 coeffs: Vec::from([
924 EllCoeffs {
925 ell_0: Fq2::new(
926 Fq::new(U256([
927 145915152615018094207274265949237364577,
928 7720188347992263845704223037750674843,
929 ]))
930 .unwrap(),
931 Fq::new(U256([
932 1642602221754736777334297091439332137,
933 43455737427254701713230610624368790806,
934 ]))
935 .unwrap(),
936 ),
937 ell_vw: Fq2::new(
938 Fq::new(U256([
939 192300176042178641247789718482757908684,
940 15253255261571338892647481759611271748,
941 ]))
942 .unwrap(),
943 Fq::new(U256([
944 84481530492606440649863882423335628050,
945 47407062771372090504997924471673219553,
946 ]))
947 .unwrap(),
948 ),
949 ell_vv: Fq2::new(
950 Fq::new(U256([
951 232941999867492381013751617901190279960,
952 33161335727531633874118709394498248694,
953 ]))
954 .unwrap(),
955 Fq::new(U256([
956 205159091107726234051689046255658875895,
957 18784742195738106358087607099254122817,
958 ]))
959 .unwrap(),
960 ),
961 },
962 EllCoeffs {
963 ell_0: Fq2::new(
964 Fq::new(U256([
965 44903717410722925336080339155272113598,
966 2432148164440313442445265360131108750,
967 ]))
968 .unwrap(),
969 Fq::new(U256([
970 115058944839679151514931430187558137193,
971 19913547532675326995005163334665928687,
972 ]))
973 .unwrap(),
974 ),
975 ell_vw: Fq2::new(
976 Fq::new(U256([
977 162225342243516818284353803749727397649,
978 2902812998987289816105769597190405892,
979 ]))
980 .unwrap(),
981 Fq::new(U256([
982 280882305470180330735174149091034017688,
983 45000755139204939118391532933575113126,
984 ]))
985 .unwrap(),
986 ),
987 ell_vv: Fq2::new(
988 Fq::new(U256([
989 81439170073299243743458979294198176188,
990 8269567577349210062003854855333109246,
991 ]))
992 .unwrap(),
993 Fq::new(U256([
994 229588642195598894684486216729209468602,
995 50120631775179825949138513731773141671,
996 ]))
997 .unwrap(),
998 ),
999 },
1000 EllCoeffs {
1001 ell_0: Fq2::new(
1002 Fq::new(U256([
1003 62571086408084349816772432183764211635,
1004 50233214695378430835319156584725532968,
1005 ]))
1006 .unwrap(),
1007 Fq::new(U256([
1008 187531012616569709709565459550531626708,
1009 25399966597901061874032352675540749982,
1010 ]))
1011 .unwrap(),
1012 ),
1013 ell_vw: Fq2::new(
1014 Fq::new(U256([
1015 125202410210363842487043120679844927964,
1016 32132029049461004568346717732357115368,
1017 ]))
1018 .unwrap(),
1019 Fq::new(U256([
1020 40047990517661970904320150752358301419,
1021 29547330482153702904408059941549019061,
1022 ]))
1023 .unwrap(),
1024 ),
1025 ell_vv: Fq2::new(
1026 Fq::new(U256([
1027 72725441636162608820485881978479394755,
1028 4335829118654814821890758647864621059,
1029 ]))
1030 .unwrap(),
1031 Fq::new(U256([
1032 3808530996119731737716737121624391430,
1033 14840119309897919310042357130477699760,
1034 ]))
1035 .unwrap(),
1036 ),
1037 },
1038 EllCoeffs {
1039 ell_0: Fq2::new(
1040 Fq::new(U256([
1041 230923838046707456761202857863657685779,
1042 30663581424308030115949734185266015957,
1043 ]))
1044 .unwrap(),
1045 Fq::new(U256([
1046 75804784823545649980980649059385057066,
1047 40783805432413650791639865054248573254,
1048 ]))
1049 .unwrap(),
1050 ),
1051 ell_vw: Fq2::new(
1052 Fq::new(U256([
1053 220403174695454806701510356109644664970,
1054 61694366506643321007589345694791625235,
1055 ]))
1056 .unwrap(),
1057 Fq::new(U256([
1058 111050616308506297168851165107648527276,
1059 29953858315513175963460036136567176100,
1060 ]))
1061 .unwrap(),
1062 ),
1063 ell_vv: Fq2::new(
1064 Fq::new(U256([
1065 339360714692284035291265180647668192278,
1066 51066683198194726198561068977822786062,
1067 ]))
1068 .unwrap(),
1069 Fq::new(U256([
1070 20532264324124291215869821260466642056,
1071 53772344434441015474139364759811842825,
1072 ]))
1073 .unwrap(),
1074 ),
1075 },
1076 EllCoeffs {
1077 ell_0: Fq2::new(
1078 Fq::new(U256([
1079 53390632401876602131528763251836289052,
1080 7039696239984002955384050250007606842,
1081 ]))
1082 .unwrap(),
1083 Fq::new(U256([
1084 120756148133186395786471763371515340851,
1085 62560956052144901655506280432592733452,
1086 ]))
1087 .unwrap(),
1088 ),
1089 ell_vw: Fq2::new(
1090 Fq::new(U256([
1091 308576049186755490218939550330371718607,
1092 60158766280438165965298754059752443327,
1093 ]))
1094 .unwrap(),
1095 Fq::new(U256([
1096 36519660971413271753359371158311247925,
1097 33166369001790145692925310192829466902,
1098 ]))
1099 .unwrap(),
1100 ),
1101 ell_vv: Fq2::new(
1102 Fq::new(U256([
1103 178902296336418821251231963767960641976,
1104 54039139529656231144797458475123200306,
1105 ]))
1106 .unwrap(),
1107 Fq::new(U256([
1108 327709063289359470903820254941214044104,
1109 29921523827667065809753199129798632038,
1110 ]))
1111 .unwrap(),
1112 ),
1113 },
1114 EllCoeffs {
1115 ell_0: Fq2::new(
1116 Fq::new(U256([
1117 293947345738284310028696202770439717312,
1118 23629199470233866978708839571836323911,
1119 ]))
1120 .unwrap(),
1121 Fq::new(U256([
1122 270255405451020462647135094276398320650,
1123 10214498461032217021941670870340839535,
1124 ]))
1125 .unwrap(),
1126 ),
1127 ell_vw: Fq2::new(
1128 Fq::new(U256([
1129 159737597162744224577379609113239040296,
1130 42414292048147664393527940182644080820,
1131 ]))
1132 .unwrap(),
1133 Fq::new(U256([
1134 319166235401593060755720596880844332847,
1135 23942967675619615172318074973192451617,
1136 ]))
1137 .unwrap(),
1138 ),
1139 ell_vv: Fq2::new(
1140 Fq::new(U256([
1141 322582854267025287594765649802803266076,
1142 43815838906866149475744535388480851056,
1143 ]))
1144 .unwrap(),
1145 Fq::new(U256([
1146 194731262617323725381582694441938082298,
1147 6318043913263416116808511289860376787,
1148 ]))
1149 .unwrap(),
1150 ),
1151 },
1152 EllCoeffs {
1153 ell_0: Fq2::new(
1154 Fq::new(U256([
1155 340258202167813930211448229264749672038,
1156 49309561646299510355653200516855272117,
1157 ]))
1158 .unwrap(),
1159 Fq::new(U256([
1160 314009511129121341897071879080163927420,
1161 46733418159091100849346822998375177924,
1162 ]))
1163 .unwrap(),
1164 ),
1165 ell_vw: Fq2::new(
1166 Fq::new(U256([
1167 296127326349185873181435771941022502705,
1168 27092339993712929447599322475752229815,
1169 ]))
1170 .unwrap(),
1171 Fq::new(U256([
1172 14090774041595571810302865485069892149,
1173 9416959189726308679959984066033622764,
1174 ]))
1175 .unwrap(),
1176 ),
1177 ell_vv: Fq2::new(
1178 Fq::new(U256([
1179 331192186309261416893996962356905314610,
1180 6133490180262551399580874298514378708,
1181 ]))
1182 .unwrap(),
1183 Fq::new(U256([
1184 52146008553438513232574426823996261862,
1185 51692389190081578424424830745703412620,
1186 ]))
1187 .unwrap(),
1188 ),
1189 },
1190 EllCoeffs {
1191 ell_0: Fq2::new(
1192 Fq::new(U256([
1193 304886724958645105936240400377782311329,
1194 24452949520921718326419149662293231897,
1195 ]))
1196 .unwrap(),
1197 Fq::new(U256([
1198 191644523888771552477578834463319391872,
1199 21762407072532056308389337796258587948,
1200 ]))
1201 .unwrap(),
1202 ),
1203 ell_vw: Fq2::new(
1204 Fq::new(U256([
1205 131875657381595539531276734057336373872,
1206 46145756403556903236477737806904884925,
1207 ]))
1208 .unwrap(),
1209 Fq::new(U256([
1210 15513558811446045405402043661936649706,
1211 6164660913794769127674854991137805768,
1212 ]))
1213 .unwrap(),
1214 ),
1215 ell_vv: Fq2::new(
1216 Fq::new(U256([
1217 37628908878688989915703006228108158588,
1218 32333568458099455743134394992114761192,
1219 ]))
1220 .unwrap(),
1221 Fq::new(U256([
1222 310028653933656868572053471966984499925,
1223 50927285178735796712220443510555951806,
1224 ]))
1225 .unwrap(),
1226 ),
1227 },
1228 EllCoeffs {
1229 ell_0: Fq2::new(
1230 Fq::new(U256([
1231 323579290279633699483736616036574636320,
1232 26462458255852549637810201830373030787,
1233 ]))
1234 .unwrap(),
1235 Fq::new(U256([
1236 212356178148004645362110693008071812466,
1237 7147771462841335914859391157142419270,
1238 ]))
1239 .unwrap(),
1240 ),
1241 ell_vw: Fq2::new(
1242 Fq::new(U256([
1243 33793486114682505251748396905247663179,
1244 12971208030293312519168903516345112146,
1245 ]))
1246 .unwrap(),
1247 Fq::new(U256([
1248 105470215179403498779276452125929471612,
1249 13243999928262666388833873861601164323,
1250 ]))
1251 .unwrap(),
1252 ),
1253 ell_vv: Fq2::new(
1254 Fq::new(U256([
1255 336774965397927402479055329499391144750,
1256 14092422716202439890370586466555281245,
1257 ]))
1258 .unwrap(),
1259 Fq::new(U256([
1260 128524990965480598411024491536330888971,
1261 16339349487558512101009117692791080358,
1262 ]))
1263 .unwrap(),
1264 ),
1265 },
1266 EllCoeffs {
1267 ell_0: Fq2::new(
1268 Fq::new(U256([
1269 308807709363499650659552856561459119304,
1270 20549512613498060437905021698882254003,
1271 ]))
1272 .unwrap(),
1273 Fq::new(U256([
1274 296831825878801592442122280385770051837,
1275 12999356604250035352468537408632919011,
1276 ]))
1277 .unwrap(),
1278 ),
1279 ell_vw: Fq2::new(
1280 Fq::new(U256([
1281 6416952549311962005690662486801715420,
1282 6562024922514861810686738146979657369,
1283 ]))
1284 .unwrap(),
1285 Fq::new(U256([
1286 208034701293282569885312328681897330015,
1287 32565296199581814532888690261728578093,
1288 ]))
1289 .unwrap(),
1290 ),
1291 ell_vv: Fq2::new(
1292 Fq::new(U256([
1293 158821090683358871468006667057662171383,
1294 43639936137708212270934870661514052516,
1295 ]))
1296 .unwrap(),
1297 Fq::new(U256([
1298 273462267971100585683746592136866263017,
1299 33686004986452254374790215788772597950,
1300 ]))
1301 .unwrap(),
1302 ),
1303 },
1304 EllCoeffs {
1305 ell_0: Fq2::new(
1306 Fq::new(U256([
1307 239050458738191424179259026508283200850,
1308 59033062634877072212375745660456082761,
1309 ]))
1310 .unwrap(),
1311 Fq::new(U256([
1312 42735232027681689333255156554135804585,
1313 3645324355274008091830665999900460711,
1314 ]))
1315 .unwrap(),
1316 ),
1317 ell_vw: Fq2::new(
1318 Fq::new(U256([
1319 108736755942765297679539162065532976047,
1320 53005795603772553534072950762621113576,
1321 ]))
1322 .unwrap(),
1323 Fq::new(U256([
1324 161143215360647768117453097687908448132,
1325 47995551574176504820342605188594172079,
1326 ]))
1327 .unwrap(),
1328 ),
1329 ell_vv: Fq2::new(
1330 Fq::new(U256([
1331 6657347986892301669776633258074701543,
1332 11902481233202623619409687758723915636,
1333 ]))
1334 .unwrap(),
1335 Fq::new(U256([
1336 222956595276083444090603007056080975801,
1337 36382879863546362219365726153085767156,
1338 ]))
1339 .unwrap(),
1340 ),
1341 },
1342 EllCoeffs {
1343 ell_0: Fq2::new(
1344 Fq::new(U256([
1345 313682093040115002688525404999246872446,
1346 42956501626298358982264420981703353471,
1347 ]))
1348 .unwrap(),
1349 Fq::new(U256([
1350 16910327688907897736932577003378075753,
1351 1359671211117678708781834746493106650,
1352 ]))
1353 .unwrap(),
1354 ),
1355 ell_vw: Fq2::new(
1356 Fq::new(U256([
1357 6643221945930263241861939865579251413,
1358 53936065521860576156419486432192485437,
1359 ]))
1360 .unwrap(),
1361 Fq::new(U256([
1362 309056291241266457640134736864478816427,
1363 37247957207987268075661977484645707642,
1364 ]))
1365 .unwrap(),
1366 ),
1367 ell_vv: Fq2::new(
1368 Fq::new(U256([
1369 222157301260856896664619946160442713805,
1370 49516872999212369072183141842522894943,
1371 ]))
1372 .unwrap(),
1373 Fq::new(U256([
1374 205513791444704603844975928062124661076,
1375 57468270224470125473802906477068197830,
1376 ]))
1377 .unwrap(),
1378 ),
1379 },
1380 EllCoeffs {
1381 ell_0: Fq2::new(
1382 Fq::new(U256([
1383 8285963000933560101573593109316673578,
1384 14786122523410515396563958444109027710,
1385 ]))
1386 .unwrap(),
1387 Fq::new(U256([
1388 122158657553570962061566147876423950513,
1389 52139940048286310424786112221915773798,
1390 ]))
1391 .unwrap(),
1392 ),
1393 ell_vw: Fq2::new(
1394 Fq::new(U256([
1395 334881138980927901869290199603379387015,
1396 25426740963889929124688873103192284934,
1397 ]))
1398 .unwrap(),
1399 Fq::new(U256([
1400 15041987314727689102877759056668987416,
1401 53279076961030137249765180937167164331,
1402 ]))
1403 .unwrap(),
1404 ),
1405 ell_vv: Fq2::new(
1406 Fq::new(U256([
1407 219851721339103004718273461131600868626,
1408 36871882814964809764289908414024625695,
1409 ]))
1410 .unwrap(),
1411 Fq::new(U256([
1412 131269942067631553063094618567097759738,
1413 53556533347945713183394135477679452243,
1414 ]))
1415 .unwrap(),
1416 ),
1417 },
1418 EllCoeffs {
1419 ell_0: Fq2::new(
1420 Fq::new(U256([
1421 303322002694907044040904386256578801369,
1422 47818402373691165133570276489205539247,
1423 ]))
1424 .unwrap(),
1425 Fq::new(U256([
1426 23840328058016663665484464556433078317,
1427 57137757685631244994429644684135564308,
1428 ]))
1429 .unwrap(),
1430 ),
1431 ell_vw: Fq2::new(
1432 Fq::new(U256([
1433 313347268925459844355339673983448992252,
1434 63059125438530014597733264556246943889,
1435 ]))
1436 .unwrap(),
1437 Fq::new(U256([
1438 332951624867081114956044501931839262097,
1439 21446965953220512177611603903918604526,
1440 ]))
1441 .unwrap(),
1442 ),
1443 ell_vv: Fq2::new(
1444 Fq::new(U256([
1445 43308962429154740283739513584277671586,
1446 36726788540078024416606994278261486896,
1447 ]))
1448 .unwrap(),
1449 Fq::new(U256([
1450 201462004284693135670392448782496773481,
1451 37361169637624833127302583281977615660,
1452 ]))
1453 .unwrap(),
1454 ),
1455 },
1456 EllCoeffs {
1457 ell_0: Fq2::new(
1458 Fq::new(U256([
1459 23765318454509223469921591210222962901,
1460 44990033695398054388153021046567582164,
1461 ]))
1462 .unwrap(),
1463 Fq::new(U256([
1464 31305053791054889490552967007711680166,
1465 27103171064041391806294729422128985527,
1466 ]))
1467 .unwrap(),
1468 ),
1469 ell_vw: Fq2::new(
1470 Fq::new(U256([
1471 276126480562835962332188871122724756846,
1472 16736136826306680287985573076016202896,
1473 ]))
1474 .unwrap(),
1475 Fq::new(U256([
1476 4414319697794720805306194236550991584,
1477 62019193108561650400059767099940339027,
1478 ]))
1479 .unwrap(),
1480 ),
1481 ell_vv: Fq2::new(
1482 Fq::new(U256([
1483 264396677944255651896935058261233808058,
1484 56759185289081036894005736531633938393,
1485 ]))
1486 .unwrap(),
1487 Fq::new(U256([
1488 203628704629834831927134686796555271069,
1489 48471469187143841926703236705753907861,
1490 ]))
1491 .unwrap(),
1492 ),
1493 },
1494 EllCoeffs {
1495 ell_0: Fq2::new(
1496 Fq::new(U256([
1497 239115594351165984647685996782641428320,
1498 44545149465284571473177119694335581490,
1499 ]))
1500 .unwrap(),
1501 Fq::new(U256([
1502 213078788930221853484251159402089402698,
1503 16763897914971151155224113448725254022,
1504 ]))
1505 .unwrap(),
1506 ),
1507 ell_vw: Fq2::new(
1508 Fq::new(U256([
1509 114008097138551618719252989046711208100,
1510 59881147407771812558336453348641148192,
1511 ]))
1512 .unwrap(),
1513 Fq::new(U256([
1514 73126778233281675579715222201222232223,
1515 38826300453213723195010574430400377747,
1516 ]))
1517 .unwrap(),
1518 ),
1519 ell_vv: Fq2::new(
1520 Fq::new(U256([
1521 241042448915505783580706972981273226980,
1522 56417003146210087305012985177072964806,
1523 ]))
1524 .unwrap(),
1525 Fq::new(U256([
1526 169177487653248888684114813249577243086,
1527 32380354283087538368804702239086564787,
1528 ]))
1529 .unwrap(),
1530 ),
1531 },
1532 EllCoeffs {
1533 ell_0: Fq2::new(
1534 Fq::new(U256([
1535 158019800920508883600584012748066500495,
1536 26898142140797843980908437809386681141,
1537 ]))
1538 .unwrap(),
1539 Fq::new(U256([
1540 306502797874464726523541130582372927512,
1541 24906313146242057911294566839234262300,
1542 ]))
1543 .unwrap(),
1544 ),
1545 ell_vw: Fq2::new(
1546 Fq::new(U256([
1547 285760763932996537001129740504018931266,
1548 61805280449958461312688755177468072593,
1549 ]))
1550 .unwrap(),
1551 Fq::new(U256([
1552 135545131264687967800977791145788692523,
1553 58139772512775079850670752006123037712,
1554 ]))
1555 .unwrap(),
1556 ),
1557 ell_vv: Fq2::new(
1558 Fq::new(U256([
1559 70329035009259499088740735594160571447,
1560 39714506367478198523957872987679138518,
1561 ]))
1562 .unwrap(),
1563 Fq::new(U256([
1564 140879819390078281356249388675648473246,
1565 43854973736398482797037510623636581696,
1566 ]))
1567 .unwrap(),
1568 ),
1569 },
1570 EllCoeffs {
1571 ell_0: Fq2::new(
1572 Fq::new(U256([
1573 38618198701391964654224360704900902096,
1574 38909748519501972274789640400408937483,
1575 ]))
1576 .unwrap(),
1577 Fq::new(U256([
1578 180923031305898977193921630254659948144,
1579 27460338595509200370239569387614912648,
1580 ]))
1581 .unwrap(),
1582 ),
1583 ell_vw: Fq2::new(
1584 Fq::new(U256([
1585 70057505024221161194312385639309591716,
1586 18962666975131076741596858262806841593,
1587 ]))
1588 .unwrap(),
1589 Fq::new(U256([
1590 214987899942827030987983709303642547609,
1591 7354730872853772995022889424236171557,
1592 ]))
1593 .unwrap(),
1594 ),
1595 ell_vv: Fq2::new(
1596 Fq::new(U256([
1597 915509610432328048899540473086774484,
1598 34629556430715177067961193484853677166,
1599 ]))
1600 .unwrap(),
1601 Fq::new(U256([
1602 210548802885276746342162088554780886285,
1603 59946451357630926783981469963615555141,
1604 ]))
1605 .unwrap(),
1606 ),
1607 },
1608 EllCoeffs {
1609 ell_0: Fq2::new(
1610 Fq::new(U256([
1611 192587880731165909190755427373555634019,
1612 10976459312692912490911357520717353871,
1613 ]))
1614 .unwrap(),
1615 Fq::new(U256([
1616 167196051583193420579377374296283755878,
1617 49401460467894024879692901111127305932,
1618 ]))
1619 .unwrap(),
1620 ),
1621 ell_vw: Fq2::new(
1622 Fq::new(U256([
1623 280565789968090605174946518022513606221,
1624 37294483328987043033011583201807512274,
1625 ]))
1626 .unwrap(),
1627 Fq::new(U256([
1628 43162969061744994465193287354736460751,
1629 22121767444104992380234797550707180209,
1630 ]))
1631 .unwrap(),
1632 ),
1633 ell_vv: Fq2::new(
1634 Fq::new(U256([
1635 253802905125777094707425424576407998829,
1636 61686094369188045360896737944218403088,
1637 ]))
1638 .unwrap(),
1639 Fq::new(U256([
1640 182974256593102716284343824242596548794,
1641 7848028085342627691056691434137748535,
1642 ]))
1643 .unwrap(),
1644 ),
1645 },
1646 EllCoeffs {
1647 ell_0: Fq2::new(
1648 Fq::new(U256([
1649 84344031984214336466355469526466525167,
1650 27093607600401090432285884248864703045,
1651 ]))
1652 .unwrap(),
1653 Fq::new(U256([
1654 149328956099164822232925589118520984554,
1655 2238105695079930209978670615986667957,
1656 ]))
1657 .unwrap(),
1658 ),
1659 ell_vw: Fq2::new(
1660 Fq::new(U256([
1661 164524345257317963111443719298495629688,
1662 60976929030698527695079882388987310770,
1663 ]))
1664 .unwrap(),
1665 Fq::new(U256([
1666 306918226890341242065585311833805224781,
1667 55722896155980110701397483880645840750,
1668 ]))
1669 .unwrap(),
1670 ),
1671 ell_vv: Fq2::new(
1672 Fq::new(U256([
1673 93128913154066328529254602049518310767,
1674 33148637643432199376041913783211199036,
1675 ]))
1676 .unwrap(),
1677 Fq::new(U256([
1678 232426184416524951250597496934702636450,
1679 43720696322889678655980069182616949616,
1680 ]))
1681 .unwrap(),
1682 ),
1683 },
1684 EllCoeffs {
1685 ell_0: Fq2::new(
1686 Fq::new(U256([
1687 102654491688396809766739755399745558766,
1688 38605113922396003219627575078289843591,
1689 ]))
1690 .unwrap(),
1691 Fq::new(U256([
1692 19593962899181063954599229676070513364,
1693 60350965404501231355169027639339453296,
1694 ]))
1695 .unwrap(),
1696 ),
1697 ell_vw: Fq2::new(
1698 Fq::new(U256([
1699 159636507003615123705820979675398042179,
1700 54313579941440479276773225578829814974,
1701 ]))
1702 .unwrap(),
1703 Fq::new(U256([
1704 119356164563490256235392395335237959869,
1705 39953340372362730589797197026608570557,
1706 ]))
1707 .unwrap(),
1708 ),
1709 ell_vv: Fq2::new(
1710 Fq::new(U256([
1711 63485981942258213001157530320762394972,
1712 31200716913018312733656963741875248687,
1713 ]))
1714 .unwrap(),
1715 Fq::new(U256([
1716 12902614517986449375080893856817237357,
1717 18985985729109591831690040180758616083,
1718 ]))
1719 .unwrap(),
1720 ),
1721 },
1722 EllCoeffs {
1723 ell_0: Fq2::new(
1724 Fq::new(U256([
1725 42308655177239821867892255001741444297,
1726 48752963962065714616191625548108808,
1727 ]))
1728 .unwrap(),
1729 Fq::new(U256([
1730 128521931437576558829282023068349026555,
1731 41085812991756679343188097975462933419,
1732 ]))
1733 .unwrap(),
1734 ),
1735 ell_vw: Fq2::new(
1736 Fq::new(U256([
1737 10035402786640614748259945360125292132,
1738 38557266307605033249489727552659930268,
1739 ]))
1740 .unwrap(),
1741 Fq::new(U256([
1742 261287166540169381393014929830322479654,
1743 42514049292646924562828996896910004962,
1744 ]))
1745 .unwrap(),
1746 ),
1747 ell_vv: Fq2::new(
1748 Fq::new(U256([
1749 56319885731071444245573249522306017699,
1750 53577564523791470572591472840806985932,
1751 ]))
1752 .unwrap(),
1753 Fq::new(U256([
1754 124520094647080351085028512262335797477,
1755 34908241061842840630524194497782012074,
1756 ]))
1757 .unwrap(),
1758 ),
1759 },
1760 EllCoeffs {
1761 ell_0: Fq2::new(
1762 Fq::new(U256([
1763 126634618253919797596379978688751079772,
1764 52145187142657016821034369446677208400,
1765 ]))
1766 .unwrap(),
1767 Fq::new(U256([
1768 331622287147942589908508350657315302543,
1769 33514242158733995981408830992771427380,
1770 ]))
1771 .unwrap(),
1772 ),
1773 ell_vw: Fq2::new(
1774 Fq::new(U256([
1775 120940515437555419164907643421042686361,
1776 17509271053436215565086784812667241751,
1777 ]))
1778 .unwrap(),
1779 Fq::new(U256([
1780 115780741523467210253488502554959480585,
1781 32352495928341192491861819481034439523,
1782 ]))
1783 .unwrap(),
1784 ),
1785 ell_vv: Fq2::new(
1786 Fq::new(U256([
1787 3619315753849520875056567968398971518,
1788 24276420029996570458336249792816120452,
1789 ]))
1790 .unwrap(),
1791 Fq::new(U256([
1792 211494135803191326215038551543926917828,
1793 43184746342435212339590913052197238451,
1794 ]))
1795 .unwrap(),
1796 ),
1797 },
1798 EllCoeffs {
1799 ell_0: Fq2::new(
1800 Fq::new(U256([
1801 299074873552726234274845052736068685064,
1802 17100980781941753342716208137755315141,
1803 ]))
1804 .unwrap(),
1805 Fq::new(U256([
1806 132717845842422445158092928854959930670,
1807 44970515850781790514922204901459656647,
1808 ]))
1809 .unwrap(),
1810 ),
1811 ell_vw: Fq2::new(
1812 Fq::new(U256([
1813 216867730679061124743178802618784487478,
1814 57695717306148677588162001948381364803,
1815 ]))
1816 .unwrap(),
1817 Fq::new(U256([
1818 270218131380365097755408360718075538527,
1819 57477676726794026534017337223493668494,
1820 ]))
1821 .unwrap(),
1822 ),
1823 ell_vv: Fq2::new(
1824 Fq::new(U256([
1825 165279544895097377741304748618110436848,
1826 20425223618131822879513743747480509436,
1827 ]))
1828 .unwrap(),
1829 Fq::new(U256([
1830 74939006713979852471760437945055491248,
1831 13009460391442509409368588074771283312,
1832 ]))
1833 .unwrap(),
1834 ),
1835 },
1836 EllCoeffs {
1837 ell_0: Fq2::new(
1838 Fq::new(U256([
1839 66759827770349370888034213457290956508,
1840 9005955800938032302448930728853089346,
1841 ]))
1842 .unwrap(),
1843 Fq::new(U256([
1844 132741330683696165661450722498530220360,
1845 7366906791443646993778243377846220425,
1846 ]))
1847 .unwrap(),
1848 ),
1849 ell_vw: Fq2::new(
1850 Fq::new(U256([
1851 253540438895289112523278690834655986794,
1852 6116090159416232554407405788526490758,
1853 ]))
1854 .unwrap(),
1855 Fq::new(U256([
1856 30829083910163512740218467627901622426,
1857 55620601051021580444864016142195538972,
1858 ]))
1859 .unwrap(),
1860 ),
1861 ell_vv: Fq2::new(
1862 Fq::new(U256([
1863 250454368142865329167214266233567636554,
1864 62357304312342518984982585510065736692,
1865 ]))
1866 .unwrap(),
1867 Fq::new(U256([
1868 188759902529624961292182168219378957599,
1869 46090313440960353890072197786322881372,
1870 ]))
1871 .unwrap(),
1872 ),
1873 },
1874 EllCoeffs {
1875 ell_0: Fq2::new(
1876 Fq::new(U256([
1877 273524456438634570870477083331972978477,
1878 9134704483036112456254510849911524401,
1879 ]))
1880 .unwrap(),
1881 Fq::new(U256([
1882 67478468272116511526567438494812739067,
1883 25741563822514337717816912706935692500,
1884 ]))
1885 .unwrap(),
1886 ),
1887 ell_vw: Fq2::new(
1888 Fq::new(U256([
1889 116593352960394465976476340555861894686,
1890 41112534697095493718894382902662572752,
1891 ]))
1892 .unwrap(),
1893 Fq::new(U256([
1894 120743240887113383410964567068981375379,
1895 38598788085595749947162720656886407615,
1896 ]))
1897 .unwrap(),
1898 ),
1899 ell_vv: Fq2::new(
1900 Fq::new(U256([
1901 312187803926537773957821532171857044863,
1902 19370576499152094014450666672812249236,
1903 ]))
1904 .unwrap(),
1905 Fq::new(U256([
1906 240827398452930199439299722869808431504,
1907 49509218268486878713361004562421178491,
1908 ]))
1909 .unwrap(),
1910 ),
1911 },
1912 EllCoeffs {
1913 ell_0: Fq2::new(
1914 Fq::new(U256([
1915 290888165778751654611450374067314903262,
1916 37392757737237359968235356696866333927,
1917 ]))
1918 .unwrap(),
1919 Fq::new(U256([
1920 252204440608865557722718990121112495320,
1921 55975286037277175922442767802285953079,
1922 ]))
1923 .unwrap(),
1924 ),
1925 ell_vw: Fq2::new(
1926 Fq::new(U256([
1927 270039432299546232993592658461203399951,
1928 60656209400809596126720306545905143183,
1929 ]))
1930 .unwrap(),
1931 Fq::new(U256([
1932 285724268091089729569589544862374658568,
1933 31963711474983717334851248248346512047,
1934 ]))
1935 .unwrap(),
1936 ),
1937 ell_vv: Fq2::new(
1938 Fq::new(U256([
1939 3884505529011790540935411500477268151,
1940 13223063167340752683657032423528371760,
1941 ]))
1942 .unwrap(),
1943 Fq::new(U256([
1944 159305752483642939978115090933392332739,
1945 7151624608160356980135319367119889070,
1946 ]))
1947 .unwrap(),
1948 ),
1949 },
1950 EllCoeffs {
1951 ell_0: Fq2::new(
1952 Fq::new(U256([
1953 272676514700352082082833454466828720931,
1954 25063412692149354657238579769317314943,
1955 ]))
1956 .unwrap(),
1957 Fq::new(U256([
1958 293621566718932528694833049559922653569,
1959 45585304922174719737960365050252747127,
1960 ]))
1961 .unwrap(),
1962 ),
1963 ell_vw: Fq2::new(
1964 Fq::new(U256([
1965 54835393883782456964222308618682542993,
1966 37980634195943561261187934261099825702,
1967 ]))
1968 .unwrap(),
1969 Fq::new(U256([
1970 59974402342646963556531661011524247325,
1971 35696051147487701670582425632191066303,
1972 ]))
1973 .unwrap(),
1974 ),
1975 ell_vv: Fq2::new(
1976 Fq::new(U256([
1977 259456005420154607862207518414346338959,
1978 26130920677564288823895676956971235383,
1979 ]))
1980 .unwrap(),
1981 Fq::new(U256([
1982 116130095060524137327607346021153250193,
1983 10807286360635090367088053443993301396,
1984 ]))
1985 .unwrap(),
1986 ),
1987 },
1988 EllCoeffs {
1989 ell_0: Fq2::new(
1990 Fq::new(U256([
1991 49392952615759746255132704409838115781,
1992 47072336582571607445080612120532993304,
1993 ]))
1994 .unwrap(),
1995 Fq::new(U256([
1996 176567394438796320529775330793638953568,
1997 28322815468520297894419530294472748019,
1998 ]))
1999 .unwrap(),
2000 ),
2001 ell_vw: Fq2::new(
2002 Fq::new(U256([
2003 80922979608932498062547214350892680237,
2004 39454405473363814575369344229244849847,
2005 ]))
2006 .unwrap(),
2007 Fq::new(U256([
2008 91401220192762005776280059066692026476,
2009 15657465297119889794043496656394015039,
2010 ]))
2011 .unwrap(),
2012 ),
2013 ell_vv: Fq2::new(
2014 Fq::new(U256([
2015 66039352326985904039959490473173702089,
2016 53019684969492620390541557616482571566,
2017 ]))
2018 .unwrap(),
2019 Fq::new(U256([
2020 241714503488139707849386627025007386925,
2021 26075944201145781355709956722513636060,
2022 ]))
2023 .unwrap(),
2024 ),
2025 },
2026 EllCoeffs {
2027 ell_0: Fq2::new(
2028 Fq::new(U256([
2029 282595284318374809009793390206732488298,
2030 45748314157085313197379566607025256839,
2031 ]))
2032 .unwrap(),
2033 Fq::new(U256([
2034 270827203295353120306891953779231995484,
2035 2061164657869992110070755346638481586,
2036 ]))
2037 .unwrap(),
2038 ),
2039 ell_vw: Fq2::new(
2040 Fq::new(U256([
2041 122772591180024083766405253289036218458,
2042 22573428243213343555967649475581629995,
2043 ]))
2044 .unwrap(),
2045 Fq::new(U256([
2046 335389040951271989935196787085438096490,
2047 19801736168278388699669751501679386348,
2048 ]))
2049 .unwrap(),
2050 ),
2051 ell_vv: Fq2::new(
2052 Fq::new(U256([
2053 339013185026928567100232707644090060309,
2054 19772463825247091662201186215246641510,
2055 ]))
2056 .unwrap(),
2057 Fq::new(U256([
2058 4804384610649622501550615795150497154,
2059 23912076036945346828195974346279787457,
2060 ]))
2061 .unwrap(),
2062 ),
2063 },
2064 EllCoeffs {
2065 ell_0: Fq2::new(
2066 Fq::new(U256([
2067 214353258010296277687883233632193811097,
2068 5219474783704014986415232032947372339,
2069 ]))
2070 .unwrap(),
2071 Fq::new(U256([
2072 79624479932762034850342328421303227111,
2073 56787485322265889115274972394242117773,
2074 ]))
2075 .unwrap(),
2076 ),
2077 ell_vw: Fq2::new(
2078 Fq::new(U256([
2079 184200025840089548499823017798379240877,
2080 48381517011877532244879858559402925202,
2081 ]))
2082 .unwrap(),
2083 Fq::new(U256([
2084 107565933978602112957892502247036378430,
2085 45988606090744912079186414974711188065,
2086 ]))
2087 .unwrap(),
2088 ),
2089 ell_vv: Fq2::new(
2090 Fq::new(U256([
2091 110593764674444376346243358175616189408,
2092 35712801833060284055338218769830573236,
2093 ]))
2094 .unwrap(),
2095 Fq::new(U256([
2096 151909254176585476474604484796159407774,
2097 47158276852552318249500199498589330637,
2098 ]))
2099 .unwrap(),
2100 ),
2101 },
2102 EllCoeffs {
2103 ell_0: Fq2::new(
2104 Fq::new(U256([
2105 322742519015404082194067614300530448854,
2106 59892171075434557254836830922854923608,
2107 ]))
2108 .unwrap(),
2109 Fq::new(U256([
2110 32065386578298932256366582168915019527,
2111 26752577181504287044232901657950904669,
2112 ]))
2113 .unwrap(),
2114 ),
2115 ell_vw: Fq2::new(
2116 Fq::new(U256([
2117 174803672897784440584915958306641383601,
2118 41091446500573741637560530719439634516,
2119 ]))
2120 .unwrap(),
2121 Fq::new(U256([
2122 209867082646016733058415245870200692364,
2123 62329211607238784395268250532556435532,
2124 ]))
2125 .unwrap(),
2126 ),
2127 ell_vv: Fq2::new(
2128 Fq::new(U256([
2129 306258598889945544178464082933019504953,
2130 54721033386841216374878966418312958051,
2131 ]))
2132 .unwrap(),
2133 Fq::new(U256([
2134 60603024880089835430212078876452798438,
2135 46149383487322374768616169869877411190,
2136 ]))
2137 .unwrap(),
2138 ),
2139 },
2140 EllCoeffs {
2141 ell_0: Fq2::new(
2142 Fq::new(U256([
2143 217026022228859342220342856144348485905,
2144 57413523264998851221438276699831981764,
2145 ]))
2146 .unwrap(),
2147 Fq::new(U256([
2148 124187198815039194427087238512103681551,
2149 5443344443330946400667796667492661757,
2150 ]))
2151 .unwrap(),
2152 ),
2153 ell_vw: Fq2::new(
2154 Fq::new(U256([
2155 329826946228202959132718054863501702187,
2156 48520872455619090037740041830322500851,
2157 ]))
2158 .unwrap(),
2159 Fq::new(U256([
2160 84830400552123989859098307569998867522,
2161 48734171266537512281517863759978814030,
2162 ]))
2163 .unwrap(),
2164 ),
2165 ell_vv: Fq2::new(
2166 Fq::new(U256([
2167 223121539165880683751973996773385673012,
2168 25883364325220384256766392563193579368,
2169 ]))
2170 .unwrap(),
2171 Fq::new(U256([
2172 299825902106679285294937343573961127742,
2173 60789713632874624396137039249203910802,
2174 ]))
2175 .unwrap(),
2176 ),
2177 },
2178 EllCoeffs {
2179 ell_0: Fq2::new(
2180 Fq::new(U256([
2181 256516074149138488025765885988857744378,
2182 14065986710590565469822003697004376208,
2183 ]))
2184 .unwrap(),
2185 Fq::new(U256([
2186 234079806620020815932181140203001517322,
2187 23367862088314049165195572485764983176,
2188 ]))
2189 .unwrap(),
2190 ),
2191 ell_vw: Fq2::new(
2192 Fq::new(U256([
2193 196437028129330799836797952742061629213,
2194 48672430434915053819319219832418834574,
2195 ]))
2196 .unwrap(),
2197 Fq::new(U256([
2198 325437437809364731749456582922626432887,
2199 48166506837989600793252437510600468487,
2200 ]))
2201 .unwrap(),
2202 ),
2203 ell_vv: Fq2::new(
2204 Fq::new(U256([
2205 159308630334191903727834955555702331135,
2206 62436879262294424125843661083177310796,
2207 ]))
2208 .unwrap(),
2209 Fq::new(U256([
2210 36766573815532717355926225449599862176,
2211 45422312033048180700369981630678147962,
2212 ]))
2213 .unwrap(),
2214 ),
2215 },
2216 EllCoeffs {
2217 ell_0: Fq2::new(
2218 Fq::new(U256([
2219 242582781609674647644149440448686667005,
2220 38749506523024653240132899426202698768,
2221 ]))
2222 .unwrap(),
2223 Fq::new(U256([
2224 175781266358339061379292613713370680613,
2225 18670420110220807116103915283744134837,
2226 ]))
2227 .unwrap(),
2228 ),
2229 ell_vw: Fq2::new(
2230 Fq::new(U256([
2231 330308428247032904787707230285980997411,
2232 57858504610626027326513601505745660271,
2233 ]))
2234 .unwrap(),
2235 Fq::new(U256([
2236 137930876960001856905683673437505764610,
2237 51655613850377410017968900339454298922,
2238 ]))
2239 .unwrap(),
2240 ),
2241 ell_vv: Fq2::new(
2242 Fq::new(U256([
2243 313120701922067853802383887994976410392,
2244 45975781155280265622735990880466050470,
2245 ]))
2246 .unwrap(),
2247 Fq::new(U256([
2248 335042362116388769047290965043326509112,
2249 60559196975175152299532260702584038813,
2250 ]))
2251 .unwrap(),
2252 ),
2253 },
2254 EllCoeffs {
2255 ell_0: Fq2::new(
2256 Fq::new(U256([
2257 168129439507943874458360855948848921748,
2258 49297302702020077848733359456178701712,
2259 ]))
2260 .unwrap(),
2261 Fq::new(U256([
2262 269089028431861389215030548077466532939,
2263 39860705713699087717989916919780377864,
2264 ]))
2265 .unwrap(),
2266 ),
2267 ell_vw: Fq2::new(
2268 Fq::new(U256([
2269 13752419440807207645064267622022228455,
2270 58622973202646179187733854793315255353,
2271 ]))
2272 .unwrap(),
2273 Fq::new(U256([
2274 214305013520593573583121266790878302778,
2275 38633624705329558986475404541639527124,
2276 ]))
2277 .unwrap(),
2278 ),
2279 ell_vv: Fq2::new(
2280 Fq::new(U256([
2281 149534517263071862076005511513725705381,
2282 33923419970735724678578488530397069094,
2283 ]))
2284 .unwrap(),
2285 Fq::new(U256([
2286 52240222008682291290000393139971676649,
2287 13553337484321113195355299279586301175,
2288 ]))
2289 .unwrap(),
2290 ),
2291 },
2292 EllCoeffs {
2293 ell_0: Fq2::new(
2294 Fq::new(U256([
2295 272900340425393991345320871434898164480,
2296 38006376657960211098766747755417992280,
2297 ]))
2298 .unwrap(),
2299 Fq::new(U256([
2300 261987172512287267237176115671442326513,
2301 8128050373266945066047548013741537435,
2302 ]))
2303 .unwrap(),
2304 ),
2305 ell_vw: Fq2::new(
2306 Fq::new(U256([
2307 262663552198367871113333688806502970707,
2308 16999213382693802141971886256404278345,
2309 ]))
2310 .unwrap(),
2311 Fq::new(U256([
2312 82246501115823748400993076962512494264,
2313 9513280785331020628797944368204762745,
2314 ]))
2315 .unwrap(),
2316 ),
2317 ell_vv: Fq2::new(
2318 Fq::new(U256([
2319 68225301292307439157467124956340428751,
2320 23984526331358356113154550150873972672,
2321 ]))
2322 .unwrap(),
2323 Fq::new(U256([
2324 322267803776402446716363035932937663522,
2325 7643551605057856674267205902314118400,
2326 ]))
2327 .unwrap(),
2328 ),
2329 },
2330 EllCoeffs {
2331 ell_0: Fq2::new(
2332 Fq::new(U256([
2333 226851502497426762485425012577563658166,
2334 33899046058167810318161894461593654070,
2335 ]))
2336 .unwrap(),
2337 Fq::new(U256([
2338 106137231667287271021611800141669940221,
2339 38201180579053106362613109983520968531,
2340 ]))
2341 .unwrap(),
2342 ),
2343 ell_vw: Fq2::new(
2344 Fq::new(U256([
2345 75276265667487657641526123222570637963,
2346 18790008468742777802887427569490235644,
2347 ]))
2348 .unwrap(),
2349 Fq::new(U256([
2350 236348579709234796216705203173042603149,
2351 51488118889105930334369568118204095717,
2352 ]))
2353 .unwrap(),
2354 ),
2355 ell_vv: Fq2::new(
2356 Fq::new(U256([
2357 70847827090593073015786004614483673839,
2358 3475230874891506896203634678143642692,
2359 ]))
2360 .unwrap(),
2361 Fq::new(U256([
2362 8314731801106602343291488634630259831,
2363 3521008420700564106163167660007668706,
2364 ]))
2365 .unwrap(),
2366 ),
2367 },
2368 EllCoeffs {
2369 ell_0: Fq2::new(
2370 Fq::new(U256([
2371 92354268952660546820822603858288251059,
2372 19778715140389467112147527814081030657,
2373 ]))
2374 .unwrap(),
2375 Fq::new(U256([
2376 329385425284714431570594794971018721246,
2377 60587846563454266929636649850787073194,
2378 ]))
2379 .unwrap(),
2380 ),
2381 ell_vw: Fq2::new(
2382 Fq::new(U256([
2383 288633840471857542459144118014949000217,
2384 51605528849039220650036727626483827846,
2385 ]))
2386 .unwrap(),
2387 Fq::new(U256([
2388 251176740648089198193669671101929833609,
2389 48200613470991338988108533743364275499,
2390 ]))
2391 .unwrap(),
2392 ),
2393 ell_vv: Fq2::new(
2394 Fq::new(U256([
2395 329193234492690486040808567065220826749,
2396 21378867659438236011740749197423248550,
2397 ]))
2398 .unwrap(),
2399 Fq::new(U256([
2400 285725508694128806244839238836446595834,
2401 16111887615812423492270406970991867951,
2402 ]))
2403 .unwrap(),
2404 ),
2405 },
2406 EllCoeffs {
2407 ell_0: Fq2::new(
2408 Fq::new(U256([
2409 152431519506548878061194990588057484057,
2410 49184327280433466363535994383523121304,
2411 ]))
2412 .unwrap(),
2413 Fq::new(U256([
2414 176897083100713735838942116510311567986,
2415 37010995217032206230292299420436992452,
2416 ]))
2417 .unwrap(),
2418 ),
2419 ell_vw: Fq2::new(
2420 Fq::new(U256([
2421 130722401240365261778198584122678322362,
2422 19293082368638790806988358431355209633,
2423 ]))
2424 .unwrap(),
2425 Fq::new(U256([
2426 336032502313799023638100083369289206306,
2427 31063427179065887680551186789065013379,
2428 ]))
2429 .unwrap(),
2430 ),
2431 ell_vv: Fq2::new(
2432 Fq::new(U256([
2433 313119215174514058940660103265063450959,
2434 25103967051083955792570154250792420707,
2435 ]))
2436 .unwrap(),
2437 Fq::new(U256([
2438 31520718700780462452153016807890400365,
2439 3961179668062303572693429066523266858,
2440 ]))
2441 .unwrap(),
2442 ),
2443 },
2444 EllCoeffs {
2445 ell_0: Fq2::new(
2446 Fq::new(U256([
2447 36667789591031625960240713279402427923,
2448 5637784774941607531109129433890086293,
2449 ]))
2450 .unwrap(),
2451 Fq::new(U256([
2452 286537786902526732905389646221547183400,
2453 56733382321156059969864849624810202662,
2454 ]))
2455 .unwrap(),
2456 ),
2457 ell_vw: Fq2::new(
2458 Fq::new(U256([
2459 318803650206508773198520172514605937449,
2460 26727846312556415159035648438885744059,
2461 ]))
2462 .unwrap(),
2463 Fq::new(U256([
2464 296466727057750056890238712141155450998,
2465 27938872020780344351123790536034462604,
2466 ]))
2467 .unwrap(),
2468 ),
2469 ell_vv: Fq2::new(
2470 Fq::new(U256([
2471 324800882000687209140271724886698306645,
2472 44039571306759586933457684739133508444,
2473 ]))
2474 .unwrap(),
2475 Fq::new(U256([
2476 47608245752536926992583482090528259005,
2477 47831283599118732387313994410846427415,
2478 ]))
2479 .unwrap(),
2480 ),
2481 },
2482 EllCoeffs {
2483 ell_0: Fq2::new(
2484 Fq::new(U256([
2485 234409386597337888556308771844488457344,
2486 12956567414802650084616113864217789370,
2487 ]))
2488 .unwrap(),
2489 Fq::new(U256([
2490 54897214305565100948138138335662741789,
2491 15577398627840234231085370089137424292,
2492 ]))
2493 .unwrap(),
2494 ),
2495 ell_vw: Fq2::new(
2496 Fq::new(U256([
2497 133034516621699526624516176710921958663,
2498 21900941110792896857560826682314104825,
2499 ]))
2500 .unwrap(),
2501 Fq::new(U256([
2502 91786723574963827227124861422083359642,
2503 15631994703072556950984703411138300334,
2504 ]))
2505 .unwrap(),
2506 ),
2507 ell_vv: Fq2::new(
2508 Fq::new(U256([
2509 61994842824519647915165015802348883298,
2510 3606506510538278544457628965895793792,
2511 ]))
2512 .unwrap(),
2513 Fq::new(U256([
2514 176676927874382884508332121131239871282,
2515 40115823781693004388411447312641595826,
2516 ]))
2517 .unwrap(),
2518 ),
2519 },
2520 EllCoeffs {
2521 ell_0: Fq2::new(
2522 Fq::new(U256([
2523 16486756791893393092802670694010735350,
2524 51213785425023838862657045286249924761,
2525 ]))
2526 .unwrap(),
2527 Fq::new(U256([
2528 127374475998848055784786954745585192546,
2529 61927128032062116041960763307324749312,
2530 ]))
2531 .unwrap(),
2532 ),
2533 ell_vw: Fq2::new(
2534 Fq::new(U256([
2535 57390628646817442883586335851238696952,
2536 1896752620999083872406878608493454725,
2537 ]))
2538 .unwrap(),
2539 Fq::new(U256([
2540 221112496886805666932828220912733522283,
2541 2796002105546343313342619098780470642,
2542 ]))
2543 .unwrap(),
2544 ),
2545 ell_vv: Fq2::new(
2546 Fq::new(U256([
2547 126113866998638086000522716026151108800,
2548 58788515162206661637618804912085907736,
2549 ]))
2550 .unwrap(),
2551 Fq::new(U256([
2552 19079621171649876430748555077055696995,
2553 46826087543975014201271501761421031441,
2554 ]))
2555 .unwrap(),
2556 ),
2557 },
2558 EllCoeffs {
2559 ell_0: Fq2::new(
2560 Fq::new(U256([
2561 287527947651847089840085422221128698763,
2562 3282429064220775329203352366444259855,
2563 ]))
2564 .unwrap(),
2565 Fq::new(U256([
2566 307065141447870398567299540185758941637,
2567 48193280250277647112409463651594786821,
2568 ]))
2569 .unwrap(),
2570 ),
2571 ell_vw: Fq2::new(
2572 Fq::new(U256([
2573 39874018308944266937776827490734641649,
2574 37791912819895325896728519088674532352,
2575 ]))
2576 .unwrap(),
2577 Fq::new(U256([
2578 11619188332176047954604673895207823813,
2579 12983193006960451462302777892755566431,
2580 ]))
2581 .unwrap(),
2582 ),
2583 ell_vv: Fq2::new(
2584 Fq::new(U256([
2585 76045219079383487030610001932731241273,
2586 16472513195230803643409094386807276517,
2587 ]))
2588 .unwrap(),
2589 Fq::new(U256([
2590 244195048886093761135684126358283143738,
2591 19479715688038787901591036330200598003,
2592 ]))
2593 .unwrap(),
2594 ),
2595 },
2596 EllCoeffs {
2597 ell_0: Fq2::new(
2598 Fq::new(U256([
2599 10563934263428977131610186732868968998,
2600 14179527485555674710937849675581267906,
2601 ]))
2602 .unwrap(),
2603 Fq::new(U256([
2604 257836314204976892854269567329818300595,
2605 50763620022812667001295845381267741649,
2606 ]))
2607 .unwrap(),
2608 ),
2609 ell_vw: Fq2::new(
2610 Fq::new(U256([
2611 160125271831790681583846356333205971645,
2612 38979573670559551140762745448476278558,
2613 ]))
2614 .unwrap(),
2615 Fq::new(U256([
2616 258822435332825467396267733276444939733,
2617 19361127335094998017975714923507638644,
2618 ]))
2619 .unwrap(),
2620 ),
2621 ell_vv: Fq2::new(
2622 Fq::new(U256([
2623 5086484109635987997951722709219418410,
2624 11993539151823720275736182499510363133,
2625 ]))
2626 .unwrap(),
2627 Fq::new(U256([
2628 171423009691627362399764794909459189507,
2629 20404136165000279368092981943358482669,
2630 ]))
2631 .unwrap(),
2632 ),
2633 },
2634 EllCoeffs {
2635 ell_0: Fq2::new(
2636 Fq::new(U256([
2637 249500614137833023351305910264605008487,
2638 42310425481082032237299673828774704531,
2639 ]))
2640 .unwrap(),
2641 Fq::new(U256([
2642 253496613223900195266106558972296162241,
2643 19046240361322320039639197826388768369,
2644 ]))
2645 .unwrap(),
2646 ),
2647 ell_vw: Fq2::new(
2648 Fq::new(U256([
2649 72263736846331351747703353269055941107,
2650 19969702258117494907412570199791763548,
2651 ]))
2652 .unwrap(),
2653 Fq::new(U256([
2654 126173921786290239044307538655562024455,
2655 18006158804314393556918633600879748967,
2656 ]))
2657 .unwrap(),
2658 ),
2659 ell_vv: Fq2::new(
2660 Fq::new(U256([
2661 16201000244836956196708576962189993382,
2662 32135871927111623648702296852432295139,
2663 ]))
2664 .unwrap(),
2665 Fq::new(U256([
2666 186963801770492707056456887595022261993,
2667 2392014174637078162701730926122882282,
2668 ]))
2669 .unwrap(),
2670 ),
2671 },
2672 EllCoeffs {
2673 ell_0: Fq2::new(
2674 Fq::new(U256([
2675 8922998024015454766590940715881630670,
2676 55567280047347356367358986337109964651,
2677 ]))
2678 .unwrap(),
2679 Fq::new(U256([
2680 313173491437683437471834863194199707492,
2681 3438176908844635046641649505356812159,
2682 ]))
2683 .unwrap(),
2684 ),
2685 ell_vw: Fq2::new(
2686 Fq::new(U256([
2687 276513541262028309851175912267910407247,
2688 11212571122829858982221117734299851084,
2689 ]))
2690 .unwrap(),
2691 Fq::new(U256([
2692 259509606552160006313745402323745013955,
2693 43114059504717558659877851383190095613,
2694 ]))
2695 .unwrap(),
2696 ),
2697 ell_vv: Fq2::new(
2698 Fq::new(U256([
2699 28098698558455079499553496395853067214,
2700 2999821831816440733771768849050005165,
2701 ]))
2702 .unwrap(),
2703 Fq::new(U256([
2704 334260605709723946550826958885726232933,
2705 11843826148467149350077605819950881153,
2706 ]))
2707 .unwrap(),
2708 ),
2709 },
2710 EllCoeffs {
2711 ell_0: Fq2::new(
2712 Fq::new(U256([
2713 283455530950531157108702282345810919101,
2714 52521643621580203161269969006017546759,
2715 ]))
2716 .unwrap(),
2717 Fq::new(U256([
2718 118200123115287742628646618978307449884,
2719 14795263733303838767894982171654042612,
2720 ]))
2721 .unwrap(),
2722 ),
2723 ell_vw: Fq2::new(
2724 Fq::new(U256([
2725 132641709504834974317245159550618583253,
2726 28570895840581787308435502085893978558,
2727 ]))
2728 .unwrap(),
2729 Fq::new(U256([
2730 229949535634549796967397304164923056337,
2731 42352202734287711800564772982472784839,
2732 ]))
2733 .unwrap(),
2734 ),
2735 ell_vv: Fq2::new(
2736 Fq::new(U256([
2737 128199924683494278990710814519750517837,
2738 58638050185358930355922065483565476451,
2739 ]))
2740 .unwrap(),
2741 Fq::new(U256([
2742 4192016302378839786647752861109219112,
2743 61114929591783829703998838288847230811,
2744 ]))
2745 .unwrap(),
2746 ),
2747 },
2748 EllCoeffs {
2749 ell_0: Fq2::new(
2750 Fq::new(U256([
2751 113754079486581376183180167710451964178,
2752 25998717875687967363117010408717972365,
2753 ]))
2754 .unwrap(),
2755 Fq::new(U256([
2756 133697001740616163002906224555636440440,
2757 23546896556625148713807775573505304385,
2758 ]))
2759 .unwrap(),
2760 ),
2761 ell_vw: Fq2::new(
2762 Fq::new(U256([
2763 227150749988479615370826356819617461792,
2764 41368715815045829029754124051658999245,
2765 ]))
2766 .unwrap(),
2767 Fq::new(U256([
2768 222514455614853854819390285868145864687,
2769 27579121989432504016710179821357885225,
2770 ]))
2771 .unwrap(),
2772 ),
2773 ell_vv: Fq2::new(
2774 Fq::new(U256([
2775 128433415390196263739951350076595027296,
2776 55636438757722652255615208065796848545,
2777 ]))
2778 .unwrap(),
2779 Fq::new(U256([
2780 94671524825895380554049635623924644741,
2781 9791488862788864605119131922310440121,
2782 ]))
2783 .unwrap(),
2784 ),
2785 },
2786 EllCoeffs {
2787 ell_0: Fq2::new(
2788 Fq::new(U256([
2789 153881172058568095361353223261899310845,
2790 17156484263879687903526208855029043640,
2791 ]))
2792 .unwrap(),
2793 Fq::new(U256([
2794 192077265925835218260989605323461142787,
2795 32318605747689071742310867751273886645,
2796 ]))
2797 .unwrap(),
2798 ),
2799 ell_vw: Fq2::new(
2800 Fq::new(U256([
2801 317408271159096505221916390262196469787,
2802 49717575675851229633286204770028665263,
2803 ]))
2804 .unwrap(),
2805 Fq::new(U256([
2806 230095008714744652782426759714312292445,
2807 34768179553549400629211217553610554586,
2808 ]))
2809 .unwrap(),
2810 ),
2811 ell_vv: Fq2::new(
2812 Fq::new(U256([
2813 259609023305192462223688164733847327699,
2814 55498873698881710203435569648274404478,
2815 ]))
2816 .unwrap(),
2817 Fq::new(U256([
2818 256325550082466559964506871761831536884,
2819 46357653853657184428683736043713888406,
2820 ]))
2821 .unwrap(),
2822 ),
2823 },
2824 EllCoeffs {
2825 ell_0: Fq2::new(
2826 Fq::new(U256([
2827 174577378801081039438668831531067795857,
2828 53157547858752109585449689851969780390,
2829 ]))
2830 .unwrap(),
2831 Fq::new(U256([
2832 82151408345597494862089436182070514285,
2833 16466308473185906030465208465158400278,
2834 ]))
2835 .unwrap(),
2836 ),
2837 ell_vw: Fq2::new(
2838 Fq::new(U256([
2839 245839213042247079917412337301921026922,
2840 22457019238909031929740892448482221879,
2841 ]))
2842 .unwrap(),
2843 Fq::new(U256([
2844 109513130235370254599453293800543710331,
2845 47936140417415756744920707247895308699,
2846 ]))
2847 .unwrap(),
2848 ),
2849 ell_vv: Fq2::new(
2850 Fq::new(U256([
2851 10776161146456696103487000724300150234,
2852 21638563281306406703950273508675616623,
2853 ]))
2854 .unwrap(),
2855 Fq::new(U256([
2856 207085916216710302318982426148546767798,
2857 7534717897684081051796825732586695012,
2858 ]))
2859 .unwrap(),
2860 ),
2861 },
2862 EllCoeffs {
2863 ell_0: Fq2::new(
2864 Fq::new(U256([
2865 155690435801319682239901337205468120840,
2866 57696234800836220244083348626584391674,
2867 ]))
2868 .unwrap(),
2869 Fq::new(U256([
2870 126757665472044690642504190674454727065,
2871 27689844381974512633117281405461511493,
2872 ]))
2873 .unwrap(),
2874 ),
2875 ell_vw: Fq2::new(
2876 Fq::new(U256([
2877 111371524430469273469505773333501881358,
2878 41915381107432591576214180621073813739,
2879 ]))
2880 .unwrap(),
2881 Fq::new(U256([
2882 8591307386286176660318558848651389629,
2883 19322060932256059989553597776338707006,
2884 ]))
2885 .unwrap(),
2886 ),
2887 ell_vv: Fq2::new(
2888 Fq::new(U256([
2889 34843642275668259465089406915935512474,
2890 25199006933559492770352887141455099490,
2891 ]))
2892 .unwrap(),
2893 Fq::new(U256([
2894 10645844381812821922686446509476566858,
2895 35688555865712593739042131731320400759,
2896 ]))
2897 .unwrap(),
2898 ),
2899 },
2900 EllCoeffs {
2901 ell_0: Fq2::new(
2902 Fq::new(U256([
2903 189947043026848705532544415056376972054,
2904 16798314122488336019972329871173393651,
2905 ]))
2906 .unwrap(),
2907 Fq::new(U256([
2908 308591971026665862143792543801958855960,
2909 31580607213628921122716343407923691193,
2910 ]))
2911 .unwrap(),
2912 ),
2913 ell_vw: Fq2::new(
2914 Fq::new(U256([
2915 163093806147198705684115256712150030567,
2916 61044717475711501197927838344963107641,
2917 ]))
2918 .unwrap(),
2919 Fq::new(U256([
2920 307478741843426518207523544103444625011,
2921 32813498165003357356133773951397928550,
2922 ]))
2923 .unwrap(),
2924 ),
2925 ell_vv: Fq2::new(
2926 Fq::new(U256([
2927 95291548361985054080716711033104720817,
2928 32740343556226865497613504752972186774,
2929 ]))
2930 .unwrap(),
2931 Fq::new(U256([
2932 99656074525833092595857684423204299816,
2933 52556239373424263650635019541397500598,
2934 ]))
2935 .unwrap(),
2936 ),
2937 },
2938 EllCoeffs {
2939 ell_0: Fq2::new(
2940 Fq::new(U256([
2941 131443621763425639580622258813874957855,
2942 17694455882904396881053896673232601550,
2943 ]))
2944 .unwrap(),
2945 Fq::new(U256([
2946 57787363176533727883752817750279248594,
2947 1322856562657561354884935596241784834,
2948 ]))
2949 .unwrap(),
2950 ),
2951 ell_vw: Fq2::new(
2952 Fq::new(U256([
2953 41788280636884607828680584839495219344,
2954 51762903848994175839707598487572362464,
2955 ]))
2956 .unwrap(),
2957 Fq::new(U256([
2958 327908654890111464339978492292915303796,
2959 47344360741808824501224988176645616993,
2960 ]))
2961 .unwrap(),
2962 ),
2963 ell_vv: Fq2::new(
2964 Fq::new(U256([
2965 263873593879772810642440946076120656306,
2966 60210233792451977377881584251511840173,
2967 ]))
2968 .unwrap(),
2969 Fq::new(U256([
2970 77405826008973124400288647208797749719,
2971 53019697808811506999139211676029205579,
2972 ]))
2973 .unwrap(),
2974 ),
2975 },
2976 EllCoeffs {
2977 ell_0: Fq2::new(
2978 Fq::new(U256([
2979 254578463202394703187741702356839561011,
2980 21096342408485278014732435848864790919,
2981 ]))
2982 .unwrap(),
2983 Fq::new(U256([
2984 230473548197181635567135409745417796610,
2985 22147822186055995413422331229074559071,
2986 ]))
2987 .unwrap(),
2988 ),
2989 ell_vw: Fq2::new(
2990 Fq::new(U256([
2991 336878015160301245042116518989872047941,
2992 3472301140759760061593082376347546380,
2993 ]))
2994 .unwrap(),
2995 Fq::new(U256([
2996 16684778019642037346902548590480489922,
2997 63174559216409847644418505532384053845,
2998 ]))
2999 .unwrap(),
3000 ),
3001 ell_vv: Fq2::new(
3002 Fq::new(U256([
3003 7942031074055265340884029455787976403,
3004 46511448608441944387405531466341650044,
3005 ]))
3006 .unwrap(),
3007 Fq::new(U256([
3008 201615416576767918339868727158350994412,
3009 64255187168173681561527383354144167567,
3010 ]))
3011 .unwrap(),
3012 ),
3013 },
3014 EllCoeffs {
3015 ell_0: Fq2::new(
3016 Fq::new(U256([
3017 243308496406996226443557446925779452296,
3018 45849597498959240205941430238383669623,
3019 ]))
3020 .unwrap(),
3021 Fq::new(U256([
3022 48147614977633577164856356428453305437,
3023 24480032415168951986931189038013914221,
3024 ]))
3025 .unwrap(),
3026 ),
3027 ell_vw: Fq2::new(
3028 Fq::new(U256([
3029 74830884455458736654394458059429787198,
3030 19093844097308332947749289150298249126,
3031 ]))
3032 .unwrap(),
3033 Fq::new(U256([
3034 33643899737753431509498018706471379301,
3035 1054576208141392093174173023229894557,
3036 ]))
3037 .unwrap(),
3038 ),
3039 ell_vv: Fq2::new(
3040 Fq::new(U256([
3041 25010096200987042473393926604632958161,
3042 36666296164531908118513449509789076579,
3043 ]))
3044 .unwrap(),
3045 Fq::new(U256([
3046 33471717379111372311065514803349918045,
3047 39155528164590001712332400960607038189,
3048 ]))
3049 .unwrap(),
3050 ),
3051 },
3052 EllCoeffs {
3053 ell_0: Fq2::new(
3054 Fq::new(U256([
3055 130247467451091212947023092388792369109,
3056 5581090585326037371051920053369586280,
3057 ]))
3058 .unwrap(),
3059 Fq::new(U256([
3060 322360327312842929444256001314179239601,
3061 39584478520709259399389327249557202594,
3062 ]))
3063 .unwrap(),
3064 ),
3065 ell_vw: Fq2::new(
3066 Fq::new(U256([
3067 109138162516199992788447200019766811785,
3068 47525457821584643247627414608651841972,
3069 ]))
3070 .unwrap(),
3071 Fq::new(U256([
3072 76309968110600274074720854748516338453,
3073 54739068402347163521228676077893779893,
3074 ]))
3075 .unwrap(),
3076 ),
3077 ell_vv: Fq2::new(
3078 Fq::new(U256([
3079 42180409310074737345249452446852603163,
3080 4374831491626595184699821621506201010,
3081 ]))
3082 .unwrap(),
3083 Fq::new(U256([
3084 130057601620482713644106051600317093239,
3085 12010679381934251249551375242240386988,
3086 ]))
3087 .unwrap(),
3088 ),
3089 },
3090 EllCoeffs {
3091 ell_0: Fq2::new(
3092 Fq::new(U256([
3093 203271863519350650976092478448210829293,
3094 52275506975977654460248547356331731574,
3095 ]))
3096 .unwrap(),
3097 Fq::new(U256([
3098 87019891938199989232789187109647269328,
3099 44030460834732836505939430240249354505,
3100 ]))
3101 .unwrap(),
3102 ),
3103 ell_vw: Fq2::new(
3104 Fq::new(U256([
3105 110171920943726136564495503552694726540,
3106 18110786866783187141705660513534498930,
3107 ]))
3108 .unwrap(),
3109 Fq::new(U256([
3110 86561692963802460817471572747090778194,
3111 16449770553500671507593674575394564582,
3112 ]))
3113 .unwrap(),
3114 ),
3115 ell_vv: Fq2::new(
3116 Fq::new(U256([
3117 221876651023252602014468911202182579931,
3118 20555077542463658872780769250687782117,
3119 ]))
3120 .unwrap(),
3121 Fq::new(U256([
3122 121263539082468326970413896423548540112,
3123 61907715120666399953423277772754945448,
3124 ]))
3125 .unwrap(),
3126 ),
3127 },
3128 EllCoeffs {
3129 ell_0: Fq2::new(
3130 Fq::new(U256([
3131 290357192776207049084050762947655748975,
3132 57738753410091871200747406135207764151,
3133 ]))
3134 .unwrap(),
3135 Fq::new(U256([
3136 135358190114239175182066780052123869069,
3137 56081507988571629614406051210751609147,
3138 ]))
3139 .unwrap(),
3140 ),
3141 ell_vw: Fq2::new(
3142 Fq::new(U256([
3143 195622544431419990666685034787625747326,
3144 54874770374981417815900652767969731611,
3145 ]))
3146 .unwrap(),
3147 Fq::new(U256([
3148 6243075893789260529022348241785972764,
3149 56521196313521047823704039910006760241,
3150 ]))
3151 .unwrap(),
3152 ),
3153 ell_vv: Fq2::new(
3154 Fq::new(U256([
3155 243495103440406073534289072917982313090,
3156 57589106164518822864160786869003317813,
3157 ]))
3158 .unwrap(),
3159 Fq::new(U256([
3160 235848100009165241948327269818774314127,
3161 37511141642844469126769577281189903937,
3162 ]))
3163 .unwrap(),
3164 ),
3165 },
3166 EllCoeffs {
3167 ell_0: Fq2::new(
3168 Fq::new(U256([
3169 78592775623001882471215007061407141105,
3170 34941191764695857355641077076235001298,
3171 ]))
3172 .unwrap(),
3173 Fq::new(U256([
3174 267356444067983260493350102628306009780,
3175 28391440678450825886400816194304466425,
3176 ]))
3177 .unwrap(),
3178 ),
3179 ell_vw: Fq2::new(
3180 Fq::new(U256([
3181 315751120363918319477358949808863604966,
3182 2531298718421943078485957285990819438,
3183 ]))
3184 .unwrap(),
3185 Fq::new(U256([
3186 242692025957487623878146464744369629015,
3187 52949313651228011397330521709355671746,
3188 ]))
3189 .unwrap(),
3190 ),
3191 ell_vv: Fq2::new(
3192 Fq::new(U256([
3193 223701370913329345484604486557612973051,
3194 34658421329859066183602046886271845301,
3195 ]))
3196 .unwrap(),
3197 Fq::new(U256([
3198 239281725801587867757289553693045231533,
3199 14055606950515704853984812857124180593,
3200 ]))
3201 .unwrap(),
3202 ),
3203 },
3204 EllCoeffs {
3205 ell_0: Fq2::new(
3206 Fq::new(U256([
3207 321292144065398009067550865125623060600,
3208 18828918489183113618746569726487918435,
3209 ]))
3210 .unwrap(),
3211 Fq::new(U256([
3212 44953266506250560322305758112518632685,
3213 12818035770624926325618902943072758802,
3214 ]))
3215 .unwrap(),
3216 ),
3217 ell_vw: Fq2::new(
3218 Fq::new(U256([
3219 198712001500603483304766131655796332238,
3220 37755493054877351200992330081944773222,
3221 ]))
3222 .unwrap(),
3223 Fq::new(U256([
3224 203494901390506520787336076745404879355,
3225 9719695048988798612029815523720059188,
3226 ]))
3227 .unwrap(),
3228 ),
3229 ell_vv: Fq2::new(
3230 Fq::new(U256([
3231 324082713664478232334150476671698670935,
3232 57968755532718074766231332303127747698,
3233 ]))
3234 .unwrap(),
3235 Fq::new(U256([
3236 172967914786650717580471091827836918517,
3237 39836011047291872323399953583350854813,
3238 ]))
3239 .unwrap(),
3240 ),
3241 },
3242 EllCoeffs {
3243 ell_0: Fq2::new(
3244 Fq::new(U256([
3245 104693003047177326696685168159983773290,
3246 21362453846755563999603040010467525220,
3247 ]))
3248 .unwrap(),
3249 Fq::new(U256([
3250 56374029098225126238873495696162227687,
3251 61374137561202742141169238350854689065,
3252 ]))
3253 .unwrap(),
3254 ),
3255 ell_vw: Fq2::new(
3256 Fq::new(U256([
3257 158941255788517659316631775720407312680,
3258 2477940982651390357755438379586767771,
3259 ]))
3260 .unwrap(),
3261 Fq::new(U256([
3262 212374631437158170731256215648153937637,
3263 51786402687200191668238627015343248084,
3264 ]))
3265 .unwrap(),
3266 ),
3267 ell_vv: Fq2::new(
3268 Fq::new(U256([
3269 67431426417348416607065438525684723676,
3270 59371917376780773574999923335758781547,
3271 ]))
3272 .unwrap(),
3273 Fq::new(U256([
3274 329921395426288970367695061271959172005,
3275 18586382421107856878975478269722973139,
3276 ]))
3277 .unwrap(),
3278 ),
3279 },
3280 EllCoeffs {
3281 ell_0: Fq2::new(
3282 Fq::new(U256([
3283 207312856868420470351121539398556490708,
3284 6749469271717320482346458817170377645,
3285 ]))
3286 .unwrap(),
3287 Fq::new(U256([
3288 297463942398989836675066926378547228117,
3289 42180709737629195771943741993025816145,
3290 ]))
3291 .unwrap(),
3292 ),
3293 ell_vw: Fq2::new(
3294 Fq::new(U256([
3295 294946811578231549301710677543341218799,
3296 20992621396953319301177509266206083412,
3297 ]))
3298 .unwrap(),
3299 Fq::new(U256([
3300 334489506001987366917405458471890123881,
3301 5644882162624043756459843063788196004,
3302 ]))
3303 .unwrap(),
3304 ),
3305 ell_vv: Fq2::new(
3306 Fq::new(U256([
3307 339439573540481749394421794993912483199,
3308 45246606008318294125455064627263238236,
3309 ]))
3310 .unwrap(),
3311 Fq::new(U256([
3312 270454941633781906426514756020454116063,
3313 13672349860189847846584888881208438638,
3314 ]))
3315 .unwrap(),
3316 ),
3317 },
3318 EllCoeffs {
3319 ell_0: Fq2::new(
3320 Fq::new(U256([
3321 184109810967303467375292693011959132443,
3322 22047527326459095654736206729881706277,
3323 ]))
3324 .unwrap(),
3325 Fq::new(U256([
3326 306855976122543936818762044270256507301,
3327 13817693020515802987708208420701920996,
3328 ]))
3329 .unwrap(),
3330 ),
3331 ell_vw: Fq2::new(
3332 Fq::new(U256([
3333 18944943876649574380290951381571111173,
3334 54681599103691370082120691137707858843,
3335 ]))
3336 .unwrap(),
3337 Fq::new(U256([
3338 274481158071926596330090943889570839876,
3339 27656594457831811691825162550052997369,
3340 ]))
3341 .unwrap(),
3342 ),
3343 ell_vv: Fq2::new(
3344 Fq::new(U256([
3345 72068179718393541085353916977402777797,
3346 23085120169523399820600846468009840798,
3347 ]))
3348 .unwrap(),
3349 Fq::new(U256([
3350 39623239893391127442673085065505018616,
3351 49714238177847283522861975755429582165,
3352 ]))
3353 .unwrap(),
3354 ),
3355 },
3356 EllCoeffs {
3357 ell_0: Fq2::new(
3358 Fq::new(U256([
3359 326109292257788796875387755492793672492,
3360 38017828106840559651298055936334805586,
3361 ]))
3362 .unwrap(),
3363 Fq::new(U256([
3364 300970874956733001966255469483871058465,
3365 61693366793354972449623979259561628170,
3366 ]))
3367 .unwrap(),
3368 ),
3369 ell_vw: Fq2::new(
3370 Fq::new(U256([
3371 247117608403708963869106314083852845952,
3372 6270392892469923670893298889464309224,
3373 ]))
3374 .unwrap(),
3375 Fq::new(U256([
3376 85229127169148541816114014402805254942,
3377 23692121466582475015916841187427174063,
3378 ]))
3379 .unwrap(),
3380 ),
3381 ell_vv: Fq2::new(
3382 Fq::new(U256([
3383 322377160078698123442118813943355848949,
3384 44790955831224275605828973863316334451,
3385 ]))
3386 .unwrap(),
3387 Fq::new(U256([
3388 246121457999548771204074791900055840778,
3389 36237050391238930724599650306620108395,
3390 ]))
3391 .unwrap(),
3392 ),
3393 },
3394 EllCoeffs {
3395 ell_0: Fq2::new(
3396 Fq::new(U256([
3397 6479203335512729615298164829455402801,
3398 18899857059703106109444283718983930606,
3399 ]))
3400 .unwrap(),
3401 Fq::new(U256([
3402 307909459343553081188134777979054198524,
3403 23104930848877581327335450138633822165,
3404 ]))
3405 .unwrap(),
3406 ),
3407 ell_vw: Fq2::new(
3408 Fq::new(U256([
3409 117408687141894236273811591312978416850,
3410 27064268635283187986411799061361560149,
3411 ]))
3412 .unwrap(),
3413 Fq::new(U256([
3414 89156958054425667145216654832344296184,
3415 28498155840544447742658664925302722255,
3416 ]))
3417 .unwrap(),
3418 ),
3419 ell_vv: Fq2::new(
3420 Fq::new(U256([
3421 264148561516468171084137463578412456470,
3422 56169366101528802291286278394614323282,
3423 ]))
3424 .unwrap(),
3425 Fq::new(U256([
3426 80748178838045963455037482306103002135,
3427 31627837956246452962075717178352705444,
3428 ]))
3429 .unwrap(),
3430 ),
3431 },
3432 EllCoeffs {
3433 ell_0: Fq2::new(
3434 Fq::new(U256([
3435 228462396223758741175275124462032775241,
3436 541217865154375519097785562072294622,
3437 ]))
3438 .unwrap(),
3439 Fq::new(U256([
3440 147690209661782719555035340726175029695,
3441 47332569057322758675859735205860987883,
3442 ]))
3443 .unwrap(),
3444 ),
3445 ell_vw: Fq2::new(
3446 Fq::new(U256([
3447 332785070356059610611838282826287767824,
3448 28411804506527712891888004500289036321,
3449 ]))
3450 .unwrap(),
3451 Fq::new(U256([
3452 80347503246503526995863756906237840538,
3453 40694963808412110626720215103350226072,
3454 ]))
3455 .unwrap(),
3456 ),
3457 ell_vv: Fq2::new(
3458 Fq::new(U256([
3459 73246772632733278293170183313248743910,
3460 51739954405360462951359314934075204478,
3461 ]))
3462 .unwrap(),
3463 Fq::new(U256([
3464 323288654986485051471927026636004277374,
3465 55328786519754064217639655113348868700,
3466 ]))
3467 .unwrap(),
3468 ),
3469 },
3470 EllCoeffs {
3471 ell_0: Fq2::new(
3472 Fq::new(U256([
3473 107183915141555030394480811055835932411,
3474 28743337205734819613101267731330261274,
3475 ]))
3476 .unwrap(),
3477 Fq::new(U256([
3478 265627562010734120334801493421007962860,
3479 21113833505065027987742094370311235794,
3480 ]))
3481 .unwrap(),
3482 ),
3483 ell_vw: Fq2::new(
3484 Fq::new(U256([
3485 145390576010968264278778301175950417032,
3486 25603093564950634850451680305056487937,
3487 ]))
3488 .unwrap(),
3489 Fq::new(U256([
3490 171224041010792018070371064846900704811,
3491 50628689539088695975060303147297926726,
3492 ]))
3493 .unwrap(),
3494 ),
3495 ell_vv: Fq2::new(
3496 Fq::new(U256([
3497 181636860313080877557100227907605412643,
3498 19106550849436726002022081116470620327,
3499 ]))
3500 .unwrap(),
3501 Fq::new(U256([
3502 97037887458346176230370696042525047476,
3503 38315199704917257726469887714210863756,
3504 ]))
3505 .unwrap(),
3506 ),
3507 },
3508 EllCoeffs {
3509 ell_0: Fq2::new(
3510 Fq::new(U256([
3511 165755565692898412861884552154775259871,
3512 23293168176203049828541858307098176114,
3513 ]))
3514 .unwrap(),
3515 Fq::new(U256([
3516 111579679857180892572143097811395790681,
3517 21526844626039124934190021704344618627,
3518 ]))
3519 .unwrap(),
3520 ),
3521 ell_vw: Fq2::new(
3522 Fq::new(U256([
3523 335258764315672309726009417334449368453,
3524 103404408330729181499563204707141002,
3525 ]))
3526 .unwrap(),
3527 Fq::new(U256([
3528 191071126894978514432059671553769626880,
3529 5078535341242500657674641815850178322,
3530 ]))
3531 .unwrap(),
3532 ),
3533 ell_vv: Fq2::new(
3534 Fq::new(U256([
3535 72579254643315478022492189073789591450,
3536 44167090301255006150406576419615402343,
3537 ]))
3538 .unwrap(),
3539 Fq::new(U256([
3540 183377394594390630206602640102963629039,
3541 23990882412966103396841140729654425350,
3542 ]))
3543 .unwrap(),
3544 ),
3545 },
3546 EllCoeffs {
3547 ell_0: Fq2::new(
3548 Fq::new(U256([
3549 66679892701097417538832992488778691458,
3550 58183623071000462877229489086029090922,
3551 ]))
3552 .unwrap(),
3553 Fq::new(U256([
3554 294287188350011499287443971281382798030,
3555 18151493196929461249661140690411179165,
3556 ]))
3557 .unwrap(),
3558 ),
3559 ell_vw: Fq2::new(
3560 Fq::new(U256([
3561 74805142807574287323605988196524192535,
3562 18100483139591925759594156937304667397,
3563 ]))
3564 .unwrap(),
3565 Fq::new(U256([
3566 139120256621259665435015294709846943744,
3567 33412960622211929574259219789625651855,
3568 ]))
3569 .unwrap(),
3570 ),
3571 ell_vv: Fq2::new(
3572 Fq::new(U256([
3573 220224993980394484792559335583346867939,
3574 59970476024877867633551960552156066815,
3575 ]))
3576 .unwrap(),
3577 Fq::new(U256([
3578 165016476912320413641798011850430383400,
3579 40087637389842239140931509158661317913,
3580 ]))
3581 .unwrap(),
3582 ),
3583 },
3584 EllCoeffs {
3585 ell_0: Fq2::new(
3586 Fq::new(U256([
3587 26669149284356063486638395246213038984,
3588 48932308059862148467989673144064276455,
3589 ]))
3590 .unwrap(),
3591 Fq::new(U256([
3592 112017260916309235481572722060511554523,
3593 1292432061742789600481111238179731344,
3594 ]))
3595 .unwrap(),
3596 ),
3597 ell_vw: Fq2::new(
3598 Fq::new(U256([
3599 162967204317649679020730851544536806310,
3600 32746563765578881184210706548921981702,
3601 ]))
3602 .unwrap(),
3603 Fq::new(U256([
3604 337655071624981772776297963145482993016,
3605 33145701869840355692613219913227327224,
3606 ]))
3607 .unwrap(),
3608 ),
3609 ell_vv: Fq2::new(
3610 Fq::new(U256([
3611 116821007696021810040981824168902376385,
3612 46826353416371587869648603174437608629,
3613 ]))
3614 .unwrap(),
3615 Fq::new(U256([
3616 286148963257224477643539266261574758187,
3617 20903220425259595580283778435979469601,
3618 ]))
3619 .unwrap(),
3620 ),
3621 },
3622 EllCoeffs {
3623 ell_0: Fq2::new(
3624 Fq::new(U256([
3625 265822762895337622674318289864003560145,
3626 62593533822281897460585212079268870737,
3627 ]))
3628 .unwrap(),
3629 Fq::new(U256([
3630 180099245396770402139578639916315358651,
3631 5289891249371566111607452004558281256,
3632 ]))
3633 .unwrap(),
3634 ),
3635 ell_vw: Fq2::new(
3636 Fq::new(U256([
3637 215101732208902323596827687492609836402,
3638 60151379040875297433910120987825047988,
3639 ]))
3640 .unwrap(),
3641 Fq::new(U256([
3642 200376206977547885622799626268846642009,
3643 36107786828287031009478318323095814795,
3644 ]))
3645 .unwrap(),
3646 ),
3647 ell_vv: Fq2::new(
3648 Fq::new(U256([
3649 228632312969356396843036040954049410317,
3650 29609317291386275502321244693464627541,
3651 ]))
3652 .unwrap(),
3653 Fq::new(U256([
3654 250663071554126685512943663183005740350,
3655 26707628083885320745488595167117920892,
3656 ]))
3657 .unwrap(),
3658 ),
3659 },
3660 EllCoeffs {
3661 ell_0: Fq2::new(
3662 Fq::new(U256([
3663 167686658731994607869572641962208584698,
3664 32951815034866853047881968952398296677,
3665 ]))
3666 .unwrap(),
3667 Fq::new(U256([
3668 59732843077777643290110085014121270991,
3669 19690792480201713304572701985281652804,
3670 ]))
3671 .unwrap(),
3672 ),
3673 ell_vw: Fq2::new(
3674 Fq::new(U256([
3675 231501326469976058677041937508913323742,
3676 58052555179693233540250119022219467367,
3677 ]))
3678 .unwrap(),
3679 Fq::new(U256([
3680 268839178939407644460103390562050250791,
3681 51244123519915889574699519125947948433,
3682 ]))
3683 .unwrap(),
3684 ),
3685 ell_vv: Fq2::new(
3686 Fq::new(U256([
3687 15335721378364717505397406493265760457,
3688 50543654003772338617069451450467156120,
3689 ]))
3690 .unwrap(),
3691 Fq::new(U256([
3692 147668560194510325215853847922114742688,
3693 63436405408432434981818242494869996954,
3694 ]))
3695 .unwrap(),
3696 ),
3697 },
3698 EllCoeffs {
3699 ell_0: Fq2::new(
3700 Fq::new(U256([
3701 324251215335356818847634371978327094047,
3702 53597895382917031159515977918983297046,
3703 ]))
3704 .unwrap(),
3705 Fq::new(U256([
3706 336456284126450597413571076848285070208,
3707 9834107003348358663468869495065030828,
3708 ]))
3709 .unwrap(),
3710 ),
3711 ell_vw: Fq2::new(
3712 Fq::new(U256([
3713 4893147365574829346121011245181836636,
3714 48500338802265501645481354399443896938,
3715 ]))
3716 .unwrap(),
3717 Fq::new(U256([
3718 242843203647079174857073639694991742532,
3719 39587639177217829196831837775949647839,
3720 ]))
3721 .unwrap(),
3722 ),
3723 ell_vv: Fq2::new(
3724 Fq::new(U256([
3725 260649755517395052354543412976006056345,
3726 41595453161552128661866319661777368912,
3727 ]))
3728 .unwrap(),
3729 Fq::new(U256([
3730 186473459113497941493205881377276393540,
3731 10232971634855792150439771169030969984,
3732 ]))
3733 .unwrap(),
3734 ),
3735 },
3736 EllCoeffs {
3737 ell_0: Fq2::new(
3738 Fq::new(U256([
3739 153156583597535672033657311231041916285,
3740 12870713391441384499488044032601826356,
3741 ]))
3742 .unwrap(),
3743 Fq::new(U256([
3744 160011046903032247780660416127755862604,
3745 59740658966179967701258870119449151446,
3746 ]))
3747 .unwrap(),
3748 ),
3749 ell_vw: Fq2::new(
3750 Fq::new(U256([
3751 53781592683706300755113958689829175735,
3752 5160246898475719650527746461036900035,
3753 ]))
3754 .unwrap(),
3755 Fq::new(U256([
3756 127406077100448076503048857464807666048,
3757 5027357614298608514576108334690214373,
3758 ]))
3759 .unwrap(),
3760 ),
3761 ell_vv: Fq2::new(
3762 Fq::new(U256([
3763 123323183388079598137911866134337668968,
3764 30831375761327507469744048674597209517,
3765 ]))
3766 .unwrap(),
3767 Fq::new(U256([
3768 282757148554018853521114389661374143994,
3769 41725892078174834143829265912887863334,
3770 ]))
3771 .unwrap(),
3772 ),
3773 },
3774 EllCoeffs {
3775 ell_0: Fq2::new(
3776 Fq::new(U256([
3777 231142251602796484920728141361531696801,
3778 43369687276260799996121293373394088506,
3779 ]))
3780 .unwrap(),
3781 Fq::new(U256([
3782 193386979673076292922455602081629373614,
3783 13517077812823754339540367661413555482,
3784 ]))
3785 .unwrap(),
3786 ),
3787 ell_vw: Fq2::new(
3788 Fq::new(U256([
3789 32945933209167472962271089890685376310,
3790 23645956766949617286909797728539496219,
3791 ]))
3792 .unwrap(),
3793 Fq::new(U256([
3794 128873344219688070096765758438736759675,
3795 54069131826062143440208582926638727688,
3796 ]))
3797 .unwrap(),
3798 ),
3799 ell_vv: Fq2::new(
3800 Fq::new(U256([
3801 307107650784744827303698892877513591771,
3802 60627460508970098579939906160617347629,
3803 ]))
3804 .unwrap(),
3805 Fq::new(U256([
3806 12937320851881845879608263929438137281,
3807 2854427512588805421842219517935335360,
3808 ]))
3809 .unwrap(),
3810 ),
3811 },
3812 EllCoeffs {
3813 ell_0: Fq2::new(
3814 Fq::new(U256([
3815 262645642925640470181426114122199935672,
3816 23413555848620303130105885294683582394,
3817 ]))
3818 .unwrap(),
3819 Fq::new(U256([
3820 23944562046020585348174388998952320194,
3821 45084472027505841447432550475379032518,
3822 ]))
3823 .unwrap(),
3824 ),
3825 ell_vw: Fq2::new(
3826 Fq::new(U256([
3827 270949855981998457946423634423510659239,
3828 52707980377915683827433393510154134085,
3829 ]))
3830 .unwrap(),
3831 Fq::new(U256([
3832 171166926104504281831828631675145047352,
3833 56745888676097625411354427758332611365,
3834 ]))
3835 .unwrap(),
3836 ),
3837 ell_vv: Fq2::new(
3838 Fq::new(U256([
3839 185108543406354812098225836322332681649,
3840 38838551534016041901193249287881822376,
3841 ]))
3842 .unwrap(),
3843 Fq::new(U256([
3844 220861944829798693206584739921489268335,
3845 13318922669002030127185287983351463417,
3846 ]))
3847 .unwrap(),
3848 ),
3849 },
3850 EllCoeffs {
3851 ell_0: Fq2::new(
3852 Fq::new(U256([
3853 262922874647306006405720155830997014046,
3854 60319938491997842161822791958118330349,
3855 ]))
3856 .unwrap(),
3857 Fq::new(U256([
3858 267514688756785010198929321975858316586,
3859 13431251784763107399729556927577885114,
3860 ]))
3861 .unwrap(),
3862 ),
3863 ell_vw: Fq2::new(
3864 Fq::new(U256([
3865 305051645126359797430782278231595423685,
3866 47480212315012773203275805598650271426,
3867 ]))
3868 .unwrap(),
3869 Fq::new(U256([
3870 61134576323692903306240935503639110628,
3871 44357224521089864059608299955085658945,
3872 ]))
3873 .unwrap(),
3874 ),
3875 ell_vv: Fq2::new(
3876 Fq::new(U256([
3877 288996190497897556231840221598596395445,
3878 7566958477031738465971309099100507442,
3879 ]))
3880 .unwrap(),
3881 Fq::new(U256([
3882 133814060971580680876860604680251720534,
3883 59538638355154696335532006425868258220,
3884 ]))
3885 .unwrap(),
3886 ),
3887 },
3888 EllCoeffs {
3889 ell_0: Fq2::new(
3890 Fq::new(U256([
3891 255893828824714285725760712618255298338,
3892 62054226651551009305279711173141456137,
3893 ]))
3894 .unwrap(),
3895 Fq::new(U256([
3896 278488875745654026562827558863613836490,
3897 21008509582420141439141693540430274581,
3898 ]))
3899 .unwrap(),
3900 ),
3901 ell_vw: Fq2::new(
3902 Fq::new(U256([
3903 275369357162135051507223962619748317962,
3904 42306683939383379782070254815636483252,
3905 ]))
3906 .unwrap(),
3907 Fq::new(U256([
3908 33692084190064829046021773249716169044,
3909 16341905693988596015816579527114077079,
3910 ]))
3911 .unwrap(),
3912 ),
3913 ell_vv: Fq2::new(
3914 Fq::new(U256([
3915 50744916563901235043837175537752247974,
3916 10172930551818555335663216915059687204,
3917 ]))
3918 .unwrap(),
3919 Fq::new(U256([
3920 130434124352272975884189586048532260990,
3921 23515228462564504103971218058319726320,
3922 ]))
3923 .unwrap(),
3924 ),
3925 },
3926 EllCoeffs {
3927 ell_0: Fq2::new(
3928 Fq::new(U256([
3929 315580665939248091007437797584737352150,
3930 29708290546079112870849940807626622733,
3931 ]))
3932 .unwrap(),
3933 Fq::new(U256([
3934 74442409874403535705044740324158268395,
3935 1505199293980260993350511103843027993,
3936 ]))
3937 .unwrap(),
3938 ),
3939 ell_vw: Fq2::new(
3940 Fq::new(U256([
3941 250928935731107472086814134230515792409,
3942 5910959187805062997477270179924851551,
3943 ]))
3944 .unwrap(),
3945 Fq::new(U256([
3946 280398933657384735588696583124789483429,
3947 54783439113329460653893087793006061735,
3948 ]))
3949 .unwrap(),
3950 ),
3951 ell_vv: Fq2::new(
3952 Fq::new(U256([
3953 251724005393716093632013371894721049773,
3954 58848512269437108583523559065211202801,
3955 ]))
3956 .unwrap(),
3957 Fq::new(U256([
3958 31822195116686689031909059702809975955,
3959 24789755710735999475756589726034740758,
3960 ]))
3961 .unwrap(),
3962 ),
3963 },
3964 EllCoeffs {
3965 ell_0: Fq2::new(
3966 Fq::new(U256([
3967 311444467767445140793669110935330311306,
3968 49680899512402416135008064018078765713,
3969 ]))
3970 .unwrap(),
3971 Fq::new(U256([
3972 260075513883026034919987130520464438138,
3973 71886459212490540714376620236740887,
3974 ]))
3975 .unwrap(),
3976 ),
3977 ell_vw: Fq2::new(
3978 Fq::new(U256([
3979 218811104197169142519581806122315915406,
3980 2003975639040616906277810278389252752,
3981 ]))
3982 .unwrap(),
3983 Fq::new(U256([
3984 162449781759514417953768678035934414521,
3985 20826616094394726852079185751274539294,
3986 ]))
3987 .unwrap(),
3988 ),
3989 ell_vv: Fq2::new(
3990 Fq::new(U256([
3991 50122791277121629311774878848574398797,
3992 41715208027917549489096484827508261925,
3993 ]))
3994 .unwrap(),
3995 Fq::new(U256([
3996 61219715357759165032395798940008313361,
3997 55168729445645977375765036089053114792,
3998 ]))
3999 .unwrap(),
4000 ),
4001 },
4002 EllCoeffs {
4003 ell_0: Fq2::new(
4004 Fq::new(U256([
4005 79415664581913745231517567945561341244,
4006 19961313692291707660858657690356279927,
4007 ]))
4008 .unwrap(),
4009 Fq::new(U256([
4010 169697929611525566517558862344260578764,
4011 32844991405556424161021671060175948696,
4012 ]))
4013 .unwrap(),
4014 ),
4015 ell_vw: Fq2::new(
4016 Fq::new(U256([
4017 97951068758528710273694591785781637499,
4018 18749313896215455583118043227454839626,
4019 ]))
4020 .unwrap(),
4021 Fq::new(U256([
4022 86416223342992670848217929911878122430,
4023 45508713650090104780284816480988042321,
4024 ]))
4025 .unwrap(),
4026 ),
4027 ell_vv: Fq2::new(
4028 Fq::new(U256([
4029 205166366708889542887913296220698256110,
4030 64283667930878381361054417761490454821,
4031 ]))
4032 .unwrap(),
4033 Fq::new(U256([
4034 127337780289640176933683040648197123026,
4035 45189848010560984741741084451460237213,
4036 ]))
4037 .unwrap(),
4038 ),
4039 },
4040 EllCoeffs {
4041 ell_0: Fq2::new(
4042 Fq::new(U256([
4043 339284773562100413239152438122508204497,
4044 50631498218339719105248005011418978450,
4045 ]))
4046 .unwrap(),
4047 Fq::new(U256([
4048 33417073692493560040015373020490319634,
4049 35461627756915585142929292352046627148,
4050 ]))
4051 .unwrap(),
4052 ),
4053 ell_vw: Fq2::new(
4054 Fq::new(U256([
4055 65706590332479893819786959846945487398,
4056 49780412881756049082474794087182699607,
4057 ]))
4058 .unwrap(),
4059 Fq::new(U256([
4060 52838637386752308153448355705238086197,
4061 25418435995504719731730063829115376943,
4062 ]))
4063 .unwrap(),
4064 ),
4065 ell_vv: Fq2::new(
4066 Fq::new(U256([
4067 272342513391057040499052435082268704444,
4068 40734611488359738470851428580967866388,
4069 ]))
4070 .unwrap(),
4071 Fq::new(U256([
4072 195464905670800875597868841505577455579,
4073 4567343913211817054294335942572391310,
4074 ]))
4075 .unwrap(),
4076 ),
4077 },
4078 EllCoeffs {
4079 ell_0: Fq2::new(
4080 Fq::new(U256([
4081 116585277318795490267488822790585572050,
4082 60535270002127930300661104257194060095,
4083 ]))
4084 .unwrap(),
4085 Fq::new(U256([
4086 60938698090087736292473391678184666708,
4087 13034546647626058553077909902189865751,
4088 ]))
4089 .unwrap(),
4090 ),
4091 ell_vw: Fq2::new(
4092 Fq::new(U256([
4093 173096860849358760769153772521753734944,
4094 46051492674049147015395144791836438516,
4095 ]))
4096 .unwrap(),
4097 Fq::new(U256([
4098 217847244022302146556080020387033222160,
4099 3714600728561149832835084325311638745,
4100 ]))
4101 .unwrap(),
4102 ),
4103 ell_vv: Fq2::new(
4104 Fq::new(U256([
4105 86749998713441153819371623717671780463,
4106 22072421598347798931100735874660737662,
4107 ]))
4108 .unwrap(),
4109 Fq::new(U256([
4110 318879363093875678699747171034610586590,
4111 20824335590094416898946169150944599166,
4112 ]))
4113 .unwrap(),
4114 ),
4115 },
4116 EllCoeffs {
4117 ell_0: Fq2::new(
4118 Fq::new(U256([
4119 64488889092438538888826783837043953900,
4120 37184887689753051095864638902885179863,
4121 ]))
4122 .unwrap(),
4123 Fq::new(U256([
4124 30545663928156310707528798028105042841,
4125 35594636889744346303301050561815356233,
4126 ]))
4127 .unwrap(),
4128 ),
4129 ell_vw: Fq2::new(
4130 Fq::new(U256([
4131 25983064025798529721395241242693795182,
4132 8818840193887973907465639723423785685,
4133 ]))
4134 .unwrap(),
4135 Fq::new(U256([
4136 258083038864362618956338229292791076964,
4137 59924965332411444209484507096908691451,
4138 ]))
4139 .unwrap(),
4140 ),
4141 ell_vv: Fq2::new(
4142 Fq::new(U256([
4143 220038260912754873591576914680586914279,
4144 13066051346629987308799710602199271472,
4145 ]))
4146 .unwrap(),
4147 Fq::new(U256([
4148 145490690982645862542497983334649610263,
4149 61905193484912278316593689230425266660,
4150 ]))
4151 .unwrap(),
4152 ),
4153 },
4154 EllCoeffs {
4155 ell_0: Fq2::new(
4156 Fq::new(U256([
4157 91140715068468329987534450751429662322,
4158 19286363177619277557153390898202185703,
4159 ]))
4160 .unwrap(),
4161 Fq::new(U256([
4162 93820352751188715792914230189639637744,
4163 34108640942617057347076989500332659863,
4164 ]))
4165 .unwrap(),
4166 ),
4167 ell_vw: Fq2::new(
4168 Fq::new(U256([
4169 64028159517497609933876978072339213461,
4170 15242545675596643010631683990284567829,
4171 ]))
4172 .unwrap(),
4173 Fq::new(U256([
4174 196818140250582584748747602707707107768,
4175 19674391967426090834762688793787807910,
4176 ]))
4177 .unwrap(),
4178 ),
4179 ell_vv: Fq2::new(
4180 Fq::new(U256([
4181 240272916169613868056785616677104041776,
4182 43506134861603450917738367078393340621,
4183 ]))
4184 .unwrap(),
4185 Fq::new(U256([
4186 4195648020339163006604321850508278540,
4187 4672904647050343041579830671683109182,
4188 ]))
4189 .unwrap(),
4190 ),
4191 },
4192 EllCoeffs {
4193 ell_0: Fq2::new(
4194 Fq::new(U256([
4195 76224289879065773445423898190273853011,
4196 29552147447995384759425668183293749353,
4197 ]))
4198 .unwrap(),
4199 Fq::new(U256([
4200 131775855227043960655312514543203001277,
4201 11525949759137095338012468817574456927,
4202 ]))
4203 .unwrap(),
4204 ),
4205 ell_vw: Fq2::new(
4206 Fq::new(U256([
4207 24164999216876611682317527533876599098,
4208 1468136824339634997687523096410027135,
4209 ]))
4210 .unwrap(),
4211 Fq::new(U256([
4212 287955683679784091578386069448645460818,
4213 42392463637589581183769087503942163916,
4214 ]))
4215 .unwrap(),
4216 ),
4217 ell_vv: Fq2::new(
4218 Fq::new(U256([
4219 277415168387483520146499744266583303231,
4220 43682907322954483721445867111493680565,
4221 ]))
4222 .unwrap(),
4223 Fq::new(U256([
4224 231497467135626786731515493713118585761,
4225 56904388641135605566397108514408579757,
4226 ]))
4227 .unwrap(),
4228 ),
4229 },
4230 ]),
4231 };
4232
4233 assert!(expected_g2_p == g2_p);
4234 assert!(expected_g2_p.coeffs.len() == 87);
4235}
4236
4237pub fn pairing(p: &G1, q: &G2) -> Fq12 {
4238 match (p.to_affine(), q.to_affine()) {
4239 (None, _) | (_, None) => Fq12::one(),
4240 (Some(p), Some(q)) => q
4241 .precompute()
4242 .miller_loop(&p)
4243 .final_exponentiation()
4244 .expect("miller loop cannot produce zero"),
4245 }
4246}
4247
4248pub fn pairing_batch(ps: &[G1], qs: &[G2]) -> Fq12 {
4249 let mut p_affines: Vec<AffineG<G1Params>> = Vec::new();
4250 let mut q_precomputes: Vec<G2Precomp> = Vec::new();
4251 for (p, q) in ps.iter().zip(qs.iter()) {
4252 let p_affine = p.to_affine();
4253 let q_affine = q.to_affine();
4254 let exists = match (p_affine, q_affine) {
4255 (None, _) | (_, None) => false,
4256 (Some(_p_affine), Some(_q_affine)) => true,
4257 };
4258
4259 if exists {
4260 p_affines.push(p.to_affine().unwrap());
4261 q_precomputes.push(q.to_affine().unwrap().precompute());
4262 }
4263 }
4264 if q_precomputes.is_empty() {
4265 return Fq12::one();
4266 }
4267 miller_loop_batch(&q_precomputes, &p_affines)
4268 .final_exponentiation()
4269 .expect("miller loop cannot produce zero")
4270}
4271
4272#[test]
4273fn test_reduced_pairing() {
4274 use crate::fields::Fq6;
4275
4276 let g1 = G1::one()
4277 * Fr::from_str(
4278 "18097487326282793650237947474982649264364522469319914492172746413872781676",
4279 )
4280 .unwrap();
4281 let g2 = G2::one()
4282 * Fr::from_str(
4283 "20390255904278144451778773028944684152769293537511418234311120800877067946",
4284 )
4285 .unwrap();
4286
4287 let gt = pairing(&g1, &g2);
4288
4289 let expected = Fq12::new(
4290 Fq6::new(
4291 Fq2::new(
4292 Fq::from_str(
4293 "7520311483001723614143802378045727372643587653754534704390832890681688842501",
4294 )
4295 .unwrap(),
4296 Fq::from_str(
4297 "20265650864814324826731498061022229653175757397078253377158157137251452249882",
4298 )
4299 .unwrap(),
4300 ),
4301 Fq2::new(
4302 Fq::from_str(
4303 "11942254371042183455193243679791334797733902728447312943687767053513298221130",
4304 )
4305 .unwrap(),
4306 Fq::from_str(
4307 "759657045325139626991751731924144629256296901790485373000297868065176843620",
4308 )
4309 .unwrap(),
4310 ),
4311 Fq2::new(
4312 Fq::from_str(
4313 "16045761475400271697821392803010234478356356448940805056528536884493606035236",
4314 )
4315 .unwrap(),
4316 Fq::from_str(
4317 "4715626119252431692316067698189337228571577552724976915822652894333558784086",
4318 )
4319 .unwrap(),
4320 ),
4321 ),
4322 Fq6::new(
4323 Fq2::new(
4324 Fq::from_str(
4325 "14901948363362882981706797068611719724999331551064314004234728272909570402962",
4326 )
4327 .unwrap(),
4328 Fq::from_str(
4329 "11093203747077241090565767003969726435272313921345853819385060670210834379103",
4330 )
4331 .unwrap(),
4332 ),
4333 Fq2::new(
4334 Fq::from_str(
4335 "17897835398184801202802503586172351707502775171934235751219763553166796820753",
4336 )
4337 .unwrap(),
4338 Fq::from_str(
4339 "1344517825169318161285758374052722008806261739116142912817807653057880346554",
4340 )
4341 .unwrap(),
4342 ),
4343 Fq2::new(
4344 Fq::from_str(
4345 "11123896897251094532909582772961906225000817992624500900708432321664085800838",
4346 )
4347 .unwrap(),
4348 Fq::from_str(
4349 "17453370448280081813275586256976217762629631160552329276585874071364454854650",
4350 )
4351 .unwrap(),
4352 ),
4353 ),
4354 );
4355
4356 assert_eq!(expected, gt);
4357}
4358
4359#[test]
4360fn predefined_pair() {
4361 let g1 = AffineG1::new(
4362 Fq::from_str("1").expect("Fq(1) should exist"),
4363 Fq::from_str("2").expect("Fq(2) should exist"),
4364 )
4365 .expect("Point (1,2) should exist in G1")
4366 .to_jacobian();
4367
4368 let g2 = AffineG2::new(
4369 Fq2::new(
4370 Fq::from_str("10857046999023057135944570762232829481370756359578518086990519993285655852781")
4371 .expect("a-coeff of g2 x generator is of the right order"),
4372 Fq::from_str("11559732032986387107991004021392285783925812861821192530917403151452391805634")
4373 .expect("b-coeff of g2 x generator is of the right order"),
4374 ),
4375 Fq2::new(
4376 Fq::from_str("8495653923123431417604973247489272438418190587263600148770280649306958101930")
4377 .expect("a-coeff of g2 y generator is of the right order"),
4378 Fq::from_str("4082367875863433681332203403145435568316851327593401208105741076214120093531")
4379 .expect("b-coeff of g2 y generator is of the right order"),
4380 ),
4381 ).expect("Point(11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + 10857046999023057135944570762232829481370756359578518086990519993285655852781, 4082367875863433681332203403145435568316851327593401208105741076214120093531 * i + 8495653923123431417604973247489272438418190587263600148770280649306958101930) is a valid generator for G2")
4382 .to_jacobian();
4383
4384 let p = pairing(&g1, &g2);
4385
4386 let g1_vec: Vec<G1> = Vec::from([g1, g1]);
4387 let g2_vec: Vec<G2> = Vec::from([g2, g2]);
4388 let p2 = pairing_batch(&g1_vec, &g2_vec);
4389 assert!(!p2.is_zero());
4390 assert!(!p.is_zero());
4391}
4392
4393#[test]
4394fn test_batch_bilinearity_empty() {
4395 let p_vec: Vec<G1> = Vec::new();
4396 let q_vec: Vec<G2> = Vec::new();
4397 let r = pairing_batch(&p_vec, &q_vec);
4398 assert_eq!(r, Fq12::one());
4399}
4400
4401#[test]
4402fn test_batch_bilinearity_one() {
4403 use rand::{SeedableRng, rngs::StdRng};
4404 let seed = [
4405 0, 0, 0, 0, 0, 0, 64, 13, 0, 0, 0, 0, 0, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 96, 7u8, ];
4410 let mut rng = StdRng::from_seed(seed);
4411 let p_vec: Vec<G1> = Vec::from([G1::random(&mut rng)]);
4412 let q_vec: Vec<G2> = Vec::from([G2::random(&mut rng)]);
4413 let s = Fr::random(&mut rng);
4414 let sp_vec: Vec<G1> = Vec::from([p_vec[0] * s]);
4415 let sq_vec: Vec<G2> = Vec::from([q_vec[0] * s]);
4416 let b = pairing_batch(&sp_vec, &q_vec);
4417 let c = pairing_batch(&p_vec, &sq_vec);
4418 assert_eq!(b, c);
4419}
4420
4421#[test]
4422fn test_batch_bilinearity_fifty() {
4423 use rand::{SeedableRng, rngs::StdRng};
4424 let seed = [
4425 0, 0, 0, 0, 0, 0, 64, 13, 0, 0, 0, 0, 0, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 96, 7u8, ];
4430 let mut rng = StdRng::from_seed(seed);
4431
4432 let mut p_vec: Vec<G1> = Vec::new();
4433 let mut q_vec: Vec<G2> = Vec::new();
4434 let mut sp_vec: Vec<G1> = Vec::new();
4435 let mut sq_vec: Vec<G2> = Vec::new();
4436
4437 for _ in 0..50 {
4438 let p = G1::random(&mut rng);
4439 let q = G2::random(&mut rng);
4440 let s = Fr::random(&mut rng);
4441 let sp = p * s;
4442 let sq = q * s;
4443 sp_vec.push(sp);
4444 q_vec.push(q);
4445 sq_vec.push(sq);
4446 p_vec.push(p);
4447 }
4448 let b_batch = pairing_batch(&sp_vec, &q_vec);
4449 let c_batch = pairing_batch(&p_vec, &sq_vec);
4450 assert_eq!(b_batch, c_batch);
4451}
4452
4453#[test]
4454fn test_bilinearity() {
4455 use rand::{SeedableRng, rngs::StdRng};
4456 let seed = [
4457 0, 0, 0, 0, 0, 0, 64, 13, 0, 0, 0, 0, 0, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 96, 7u8, ];
4462 let mut rng = StdRng::from_seed(seed);
4463
4464 for _ in 0..50 {
4465 let p = G1::random(&mut rng);
4466 let q = G2::random(&mut rng);
4467 let s = Fr::random(&mut rng);
4468 let sp = p * s;
4469 let sq = q * s;
4470
4471 let a = pairing(&p, &q).pow(s);
4472 let b = pairing(&sp, &q);
4473 let c = pairing(&p, &sq);
4474
4475 assert_eq!(a, b);
4476 assert_eq!(b, c);
4477
4478 let t = -Fr::one();
4479
4480 assert!(a != Fq12::one());
4481 assert_eq!((a.pow(t)) * a, Fq12::one());
4482 }
4483}
4484
4485#[test]
4486fn internals() {
4487 let test_p = G1::one();
4488
4489 let val = G1::new(test_p.x().clone(), test_p.y().clone(), test_p.z().clone());
4490
4491 let affine = val
4492 .to_affine()
4493 .expect("There should be affine coords for (0, 0)");
4494
4495 assert_eq!(affine.x(), &Fq::one());
4496}
4497
4498#[test]
4499fn affine_fail() {
4500 let res = AffineG1::new(Fq::one(), Fq::one());
4501 assert!(
4502 res.is_err(),
4503 "Affine initialization should fail because the point is not on curve"
4504 );
4505}
4506
4507#[test]
4508fn affine_ok() {
4509 let res = AffineG1::new(Fq::one(), G1Params::coeff_b());
4510 assert!(
4511 res.is_err(),
4512 "Affine initialization should be ok because the point is on the curve"
4513 );
4514}
4515
4516#[test]
4517fn test_y_at_point_at_infinity() {
4518 assert!(G1::zero().y == Fq::one());
4519 assert!((-G1::zero()).y == Fq::one());
4520
4521 assert!(G2::zero().y == Fq2::one());
4522 assert!((-G2::zero()).y == Fq2::one());
4523}