zksync_pairing/bls12_381/
ec.rs

1macro_rules! curve_impl {
2    (
3        $name:expr,
4        $projective:ident,
5        $affine:ident,
6        $prepared:ident,
7        $basefield:ident,
8        $scalarfield:ident,
9        $uncompressed:ident,
10        $compressed:ident,
11        $pairing:ident
12    ) => {
13        #[derive(Copy, Clone, PartialEq, Eq, Debug, ::serde::Serialize, ::serde::Deserialize)]
14        pub struct $affine {
15            pub(crate) x: $basefield,
16            pub(crate) y: $basefield,
17            pub(crate) infinity: bool,
18        }
19
20        impl ::std::fmt::Display for $affine {
21            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
22                if self.infinity {
23                    write!(f, "{}(Infinity)", $name)
24                } else {
25                    write!(f, "{}(x={}, y={})", $name, self.x, self.y)
26                }
27            }
28        }
29
30        #[derive(Copy, Clone, Debug, Eq)]
31        pub struct $projective {
32            pub(crate) x: $basefield,
33            pub(crate) y: $basefield,
34            pub(crate) z: $basefield,
35        }
36
37        impl ::std::fmt::Display for $projective {
38            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
39                write!(f, "{}", self.into_affine())
40            }
41        }
42
43        impl PartialEq for $projective {
44            fn eq(&self, other: &$projective) -> bool {
45                if self.is_zero() {
46                    return other.is_zero();
47                }
48
49                if other.is_zero() {
50                    return false;
51                }
52
53                // The points (X, Y, Z) and (X', Y', Z')
54                // are equal when (X * Z^2) = (X' * Z'^2)
55                // and (Y * Z^3) = (Y' * Z'^3).
56
57                let mut z1 = self.z;
58                z1.square();
59                let mut z2 = other.z;
60                z2.square();
61
62                let mut tmp1 = self.x;
63                tmp1.mul_assign(&z2);
64
65                let mut tmp2 = other.x;
66                tmp2.mul_assign(&z1);
67
68                if tmp1 != tmp2 {
69                    return false;
70                }
71
72                z1.mul_assign(&self.z);
73                z2.mul_assign(&other.z);
74                z2.mul_assign(&self.y);
75                z1.mul_assign(&other.y);
76
77                if z1 != z2 {
78                    return false;
79                }
80
81                true
82            }
83        }
84
85        impl $affine {
86            fn mul_bits<S: AsRef<[u64]>>(&self, bits: BitIterator<S>) -> $projective {
87                let mut res = $projective::zero();
88                for i in bits {
89                    res.double();
90                    if i {
91                        res.add_assign_mixed(self)
92                    }
93                }
94                res
95            }
96
97            /// Attempts to construct an affine point given an x-coordinate. The
98            /// point is not guaranteed to be in the prime order subgroup.
99            ///
100            /// If and only if `greatest` is set will the lexicographically
101            /// largest y-coordinate be selected.
102            fn get_point_from_x(x: $basefield, greatest: bool) -> Option<$affine> {
103                // Compute x^3 + b
104                let mut x3b = x;
105                x3b.square();
106                x3b.mul_assign(&x);
107                x3b.add_assign(&$affine::get_coeff_b());
108
109                x3b.sqrt().map(|y| {
110                    let mut negy = y;
111                    negy.negate();
112
113                    $affine {
114                        x: x,
115                        y: if (y < negy) ^ greatest { y } else { negy },
116                        infinity: false,
117                    }
118                })
119            }
120
121            fn is_on_curve(&self) -> bool {
122                if self.is_zero() {
123                    true
124                } else {
125                    // Check that the point is on the curve
126                    let mut y2 = self.y;
127                    y2.square();
128
129                    let mut x3b = self.x;
130                    x3b.square();
131                    x3b.mul_assign(&self.x);
132                    x3b.add_assign(&Self::get_coeff_b());
133
134                    y2 == x3b
135                }
136            }
137
138            fn is_in_correct_subgroup_assuming_on_curve(&self) -> bool {
139                self.mul($scalarfield::char()).is_zero()
140            }
141        }
142
143        impl CurveAffine for $affine {
144            type Engine = Bls12;
145            type Scalar = $scalarfield;
146            type Base = $basefield;
147            type Prepared = $prepared;
148            type Projective = $projective;
149            type Uncompressed = $uncompressed;
150            type Compressed = $compressed;
151            type Pair = $pairing;
152            type PairingResult = Fq12;
153
154            fn zero() -> Self {
155                $affine {
156                    x: $basefield::zero(),
157                    y: $basefield::one(),
158                    infinity: true,
159                }
160            }
161
162            fn one() -> Self {
163                Self::get_generator()
164            }
165
166            fn is_zero(&self) -> bool {
167                self.infinity
168            }
169
170            fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, by: S) -> $projective {
171                let bits = BitIterator::new(by.into());
172                self.mul_bits(bits)
173            }
174
175            fn negate(&mut self) {
176                if !self.is_zero() {
177                    self.y.negate();
178                }
179            }
180
181            fn prepare(&self) -> Self::Prepared {
182                $prepared::from_affine(*self)
183            }
184
185            fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult {
186                self.perform_pairing(other)
187            }
188
189            fn into_projective(&self) -> $projective {
190                (*self).into()
191            }
192
193            #[inline(always)]
194            fn as_xy(&self) -> (&Self::Base, &Self::Base) {
195                (&self.x, &self.y)
196            }
197
198            #[inline(always)]
199            fn into_xy_unchecked(self) -> (Self::Base, Self::Base) {
200                (self.x, self.y)
201            }
202
203            #[inline(always)]
204            fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self {
205                let infinity = x.is_zero() && y.is_zero();
206                Self { x: x, y: y, infinity }
207            }
208
209            fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result<Self, GroupDecodingError> {
210                let infinity = x.is_zero() && y.is_zero();
211                let affine = Self { x: x, y: y, infinity };
212
213                if !affine.is_on_curve() {
214                    Err(GroupDecodingError::NotOnCurve)
215                } else {
216                    Ok(affine)
217                }
218            }
219
220            fn a_coeff() -> Self::Base {
221                Self::Base::zero()
222            }
223
224            fn b_coeff() -> Self::Base {
225                $affine::get_coeff_b()
226            }
227        }
228
229        // impl Rand for $projective {
230        //     fn rand<R: Rng>(rng: &mut R) -> Self {
231        //         loop {
232        //             let x = rng.gen();
233        //             let greatest = rng.gen();
234
235        //             if let Some(p) = $affine::get_point_from_x(x, greatest) {
236        //                 let p = p.scale_by_cofactor();
237
238        //                 if !p.is_zero() {
239        //                     return p;
240        //                 }
241        //             }
242        //         }
243        //     }
244        // }
245
246        impl CurveProjective for $projective {
247            type Engine = Bls12;
248            type Scalar = $scalarfield;
249            type Base = $basefield;
250            type Affine = $affine;
251
252            // The point at infinity is always represented by
253            // Z = 0.
254            fn zero() -> Self {
255                $projective {
256                    x: $basefield::zero(),
257                    y: $basefield::one(),
258                    z: $basefield::zero(),
259                }
260            }
261
262            fn one() -> Self {
263                $affine::one().into()
264            }
265
266            // The point at infinity is always represented by
267            // Z = 0.
268            fn is_zero(&self) -> bool {
269                self.z.is_zero()
270            }
271
272            fn is_normalized(&self) -> bool {
273                self.is_zero() || self.z == $basefield::one()
274            }
275
276            fn batch_normalization(v: &mut [Self]) {
277                // Montgomery’s Trick and Fast Implementation of Masked AES
278                // Genelle, Prouff and Quisquater
279                // Section 3.2
280
281                // First pass: compute [a, ab, abc, ...]
282                let mut prod = Vec::with_capacity(v.len());
283                let mut tmp = $basefield::one();
284                for g in v
285                    .iter_mut()
286                    // Ignore normalized elements
287                    .filter(|g| !g.is_normalized())
288                {
289                    tmp.mul_assign(&g.z);
290                    prod.push(tmp);
291                }
292
293                // Invert `tmp`.
294                tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero.
295
296                // Second pass: iterate backwards to compute inverses
297                for (g, s) in v
298                    .iter_mut()
299                    // Backwards
300                    .rev()
301                    // Ignore normalized elements
302                    .filter(|g| !g.is_normalized())
303                    // Backwards, skip last element, fill in one for last term.
304                    .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one())))
305                {
306                    // tmp := tmp * g.z; g.z := tmp * s = 1/z
307                    let mut newtmp = tmp;
308                    newtmp.mul_assign(&g.z);
309                    g.z = tmp;
310                    g.z.mul_assign(&s);
311                    tmp = newtmp;
312                }
313
314                // Perform affine transformations
315                for g in v.iter_mut().filter(|g| !g.is_normalized()) {
316                    let mut z = g.z; // 1/z
317                    z.square(); // 1/z^2
318                    g.x.mul_assign(&z); // x/z^2
319                    z.mul_assign(&g.z); // 1/z^3
320                    g.y.mul_assign(&z); // y/z^3
321                    g.z = $basefield::one(); // z = 1
322                }
323            }
324
325            fn double(&mut self) {
326                if self.is_zero() {
327                    return;
328                }
329
330                // Other than the point at infinity, no points on E or E'
331                // can double to equal the point at infinity, as y=0 is
332                // never true for points on the curve. (-4 and -4u-4
333                // are not cubic residue in their respective fields.)
334
335                // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
336
337                // A = X1^2
338                let mut a = self.x;
339                a.square();
340
341                // B = Y1^2
342                let mut b = self.y;
343                b.square();
344
345                // C = B^2
346                let mut c = b;
347                c.square();
348
349                // D = 2*((X1+B)2-A-C)
350                let mut d = self.x;
351                d.add_assign(&b);
352                d.square();
353                d.sub_assign(&a);
354                d.sub_assign(&c);
355                d.double();
356
357                // E = 3*A
358                let mut e = a;
359                e.double();
360                e.add_assign(&a);
361
362                // F = E^2
363                let mut f = e;
364                f.square();
365
366                // Z3 = 2*Y1*Z1
367                self.z.mul_assign(&self.y);
368                self.z.double();
369
370                // X3 = F-2*D
371                self.x = f;
372                self.x.sub_assign(&d);
373                self.x.sub_assign(&d);
374
375                // Y3 = E*(D-X3)-8*C
376                self.y = d;
377                self.y.sub_assign(&self.x);
378                self.y.mul_assign(&e);
379                c.double();
380                c.double();
381                c.double();
382                self.y.sub_assign(&c);
383            }
384
385            fn add_assign(&mut self, other: &Self) {
386                if self.is_zero() {
387                    *self = *other;
388                    return;
389                }
390
391                if other.is_zero() {
392                    return;
393                }
394
395                // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
396
397                // Z1Z1 = Z1^2
398                let mut z1z1 = self.z;
399                z1z1.square();
400
401                // Z2Z2 = Z2^2
402                let mut z2z2 = other.z;
403                z2z2.square();
404
405                // U1 = X1*Z2Z2
406                let mut u1 = self.x;
407                u1.mul_assign(&z2z2);
408
409                // U2 = X2*Z1Z1
410                let mut u2 = other.x;
411                u2.mul_assign(&z1z1);
412
413                // S1 = Y1*Z2*Z2Z2
414                let mut s1 = self.y;
415                s1.mul_assign(&other.z);
416                s1.mul_assign(&z2z2);
417
418                // S2 = Y2*Z1*Z1Z1
419                let mut s2 = other.y;
420                s2.mul_assign(&self.z);
421                s2.mul_assign(&z1z1);
422
423                if u1 == u2 && s1 == s2 {
424                    // The two points are equal, so we double.
425                    self.double();
426                } else {
427                    // If we're adding -a and a together, self.z becomes zero as H becomes zero.
428
429                    // H = U2-U1
430                    let mut h = u2;
431                    h.sub_assign(&u1);
432
433                    // I = (2*H)^2
434                    let mut i = h;
435                    i.double();
436                    i.square();
437
438                    // J = H*I
439                    let mut j = h;
440                    j.mul_assign(&i);
441
442                    // r = 2*(S2-S1)
443                    let mut r = s2;
444                    r.sub_assign(&s1);
445                    r.double();
446
447                    // V = U1*I
448                    let mut v = u1;
449                    v.mul_assign(&i);
450
451                    // X3 = r^2 - J - 2*V
452                    self.x = r;
453                    self.x.square();
454                    self.x.sub_assign(&j);
455                    self.x.sub_assign(&v);
456                    self.x.sub_assign(&v);
457
458                    // Y3 = r*(V - X3) - 2*S1*J
459                    self.y = v;
460                    self.y.sub_assign(&self.x);
461                    self.y.mul_assign(&r);
462                    s1.mul_assign(&j); // S1 = S1 * J * 2
463                    s1.double();
464                    self.y.sub_assign(&s1);
465
466                    // Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H
467                    self.z.add_assign(&other.z);
468                    self.z.square();
469                    self.z.sub_assign(&z1z1);
470                    self.z.sub_assign(&z2z2);
471                    self.z.mul_assign(&h);
472                }
473            }
474
475            fn add_assign_mixed(&mut self, other: &Self::Affine) {
476                if other.is_zero() {
477                    return;
478                }
479
480                if self.is_zero() {
481                    self.x = other.x;
482                    self.y = other.y;
483                    self.z = $basefield::one();
484                    return;
485                }
486
487                // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
488
489                // Z1Z1 = Z1^2
490                let mut z1z1 = self.z;
491                z1z1.square();
492
493                // U2 = X2*Z1Z1
494                let mut u2 = other.x;
495                u2.mul_assign(&z1z1);
496
497                // S2 = Y2*Z1*Z1Z1
498                let mut s2 = other.y;
499                s2.mul_assign(&self.z);
500                s2.mul_assign(&z1z1);
501
502                if self.x == u2 && self.y == s2 {
503                    // The two points are equal, so we double.
504                    self.double();
505                } else {
506                    // If we're adding -a and a together, self.z becomes zero as H becomes zero.
507
508                    // H = U2-X1
509                    let mut h = u2;
510                    h.sub_assign(&self.x);
511
512                    // HH = H^2
513                    let mut hh = h;
514                    hh.square();
515
516                    // I = 4*HH
517                    let mut i = hh;
518                    i.double();
519                    i.double();
520
521                    // J = H*I
522                    let mut j = h;
523                    j.mul_assign(&i);
524
525                    // r = 2*(S2-Y1)
526                    let mut r = s2;
527                    r.sub_assign(&self.y);
528                    r.double();
529
530                    // V = X1*I
531                    let mut v = self.x;
532                    v.mul_assign(&i);
533
534                    // X3 = r^2 - J - 2*V
535                    self.x = r;
536                    self.x.square();
537                    self.x.sub_assign(&j);
538                    self.x.sub_assign(&v);
539                    self.x.sub_assign(&v);
540
541                    // Y3 = r*(V-X3)-2*Y1*J
542                    j.mul_assign(&self.y); // J = 2*Y1*J
543                    j.double();
544                    self.y = v;
545                    self.y.sub_assign(&self.x);
546                    self.y.mul_assign(&r);
547                    self.y.sub_assign(&j);
548
549                    // Z3 = (Z1+H)^2-Z1Z1-HH
550                    self.z.add_assign(&h);
551                    self.z.square();
552                    self.z.sub_assign(&z1z1);
553                    self.z.sub_assign(&hh);
554                }
555            }
556
557            fn negate(&mut self) {
558                if !self.is_zero() {
559                    self.y.negate()
560                }
561            }
562
563            fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S) {
564                let mut res = Self::zero();
565
566                let mut found_one = false;
567
568                for i in BitIterator::new(other.into()) {
569                    if found_one {
570                        res.double();
571                    } else {
572                        found_one = i;
573                    }
574
575                    if i {
576                        res.add_assign(self);
577                    }
578                }
579
580                *self = res;
581            }
582
583            fn into_affine(&self) -> $affine {
584                (*self).into()
585            }
586
587            fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize {
588                Self::empirical_recommended_wnaf_for_scalar(scalar)
589            }
590
591            fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize {
592                Self::empirical_recommended_wnaf_for_num_scalars(num_scalars)
593            }
594
595            fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) {
596                (&self.x, &self.y, &self.z)
597            }
598
599            fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) {
600                (self.x, self.y, self.z)
601            }
602
603            fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self {
604                Self { x, y, z }
605            }
606
607            fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result<Self, GroupDecodingError> {
608                unimplemented!("on curve check is not implemented for BLS12-381 projective")
609            }
610        }
611
612        // The affine point X, Y is represented in the jacobian
613        // coordinates with Z = 1.
614        impl From<$affine> for $projective {
615            fn from(p: $affine) -> $projective {
616                if p.is_zero() {
617                    $projective::zero()
618                } else {
619                    $projective {
620                        x: p.x,
621                        y: p.y,
622                        z: $basefield::one(),
623                    }
624                }
625            }
626        }
627
628        // The projective point X, Y, Z is represented in the affine
629        // coordinates as X/Z^2, Y/Z^3.
630        impl From<$projective> for $affine {
631            fn from(p: $projective) -> $affine {
632                if p.is_zero() {
633                    $affine::zero()
634                } else if p.z == $basefield::one() {
635                    // If Z is one, the point is already normalized.
636                    $affine { x: p.x, y: p.y, infinity: false }
637                } else {
638                    // Z is nonzero, so it must have an inverse in a field.
639                    let zinv = p.z.inverse().unwrap();
640                    let mut zinv_powered = zinv;
641                    zinv_powered.square();
642
643                    // X/Z^2
644                    let mut x = p.x;
645                    x.mul_assign(&zinv_powered);
646
647                    // Y/Z^3
648                    let mut y = p.y;
649                    zinv_powered.mul_assign(&zinv);
650                    y.mul_assign(&zinv_powered);
651
652                    $affine { x: x, y: y, infinity: false }
653                }
654            }
655        }
656    };
657}
658
659pub mod g1 {
660    use super::super::{Bls12, Fq, Fq12, FqRepr, Fr, FrRepr};
661    use super::g2::G2Affine;
662    use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable};
663    use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
664    use rand::{Rand, Rng};
665    use std::fmt;
666
667    curve_impl!("G1", G1, G1Affine, G1Prepared, Fq, Fr, G1Uncompressed, G1Compressed, G2Affine);
668
669    #[derive(Copy, Clone)]
670    pub struct G1Uncompressed([u8; 96]);
671
672    impl Rand for G1 {
673        fn rand<R: Rng>(rng: &mut R) -> Self {
674            loop {
675                let x = rng.gen();
676                let greatest = rng.gen();
677
678                if let Some(p) = G1Affine::get_point_from_x(x, greatest) {
679                    if !p.is_zero() {
680                        if p.is_on_curve() {
681                            return p.into_projective();
682                        }
683                    }
684                }
685            }
686        }
687    }
688
689    impl Rand for G1Affine {
690        fn rand<R: Rng>(rng: &mut R) -> Self {
691            loop {
692                let x = rng.gen();
693                let greatest = rng.gen();
694
695                if let Some(p) = G1Affine::get_point_from_x(x, greatest) {
696                    if !p.is_zero() {
697                        if p.is_on_curve() {
698                            return p;
699                        }
700                    }
701                }
702            }
703        }
704    }
705
706    impl AsRef<[u8]> for G1Uncompressed {
707        fn as_ref(&self) -> &[u8] {
708            &self.0
709        }
710    }
711
712    impl AsMut<[u8]> for G1Uncompressed {
713        fn as_mut(&mut self) -> &mut [u8] {
714            &mut self.0
715        }
716    }
717
718    impl fmt::Debug for G1Uncompressed {
719        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
720            self.0[..].fmt(formatter)
721        }
722    }
723
724    impl EncodedPoint for G1Uncompressed {
725        type Affine = G1Affine;
726
727        fn empty() -> Self {
728            G1Uncompressed([0; 96])
729        }
730        fn size() -> usize {
731            96
732        }
733        fn into_affine(&self) -> Result<G1Affine, GroupDecodingError> {
734            let affine = self.into_affine_unchecked()?;
735
736            if !affine.is_on_curve() {
737                Err(GroupDecodingError::NotOnCurve)
738            } else if !affine.is_in_correct_subgroup_assuming_on_curve() {
739                Err(GroupDecodingError::NotInSubgroup)
740            } else {
741                Ok(affine)
742            }
743        }
744        fn into_affine_unchecked(&self) -> Result<G1Affine, GroupDecodingError> {
745            // Create a copy of this representation.
746            let mut copy = self.0;
747
748            if copy[0] & (1 << 7) != 0 {
749                // Distinguisher bit is set, but this should be uncompressed!
750                return Err(GroupDecodingError::UnexpectedCompressionMode);
751            }
752
753            if copy[0] & (1 << 6) != 0 {
754                // This is the point at infinity, which means that if we mask away
755                // the first two bits, the entire representation should consist
756                // of zeroes.
757                copy[0] &= 0x3f;
758
759                if copy.iter().all(|b| *b == 0) {
760                    Ok(G1Affine::zero())
761                } else {
762                    Err(GroupDecodingError::UnexpectedInformation)
763                }
764            } else {
765                if copy[0] & (1 << 5) != 0 {
766                    // The bit indicating the y-coordinate should be lexicographically
767                    // largest is set, but this is an uncompressed element.
768                    return Err(GroupDecodingError::UnexpectedInformation);
769                }
770
771                // Unset the three most significant bits.
772                copy[0] &= 0x1f;
773
774                let mut x = FqRepr([0; 6]);
775                let mut y = FqRepr([0; 6]);
776
777                {
778                    let mut reader = &copy[..];
779
780                    x.read_be(&mut reader).unwrap();
781                    y.read_be(&mut reader).unwrap();
782                }
783
784                Ok(G1Affine {
785                    x: Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?,
786                    y: Fq::from_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?,
787                    infinity: false,
788                })
789            }
790        }
791        fn from_affine(affine: G1Affine) -> Self {
792            let mut res = Self::empty();
793
794            if affine.is_zero() {
795                // Set the second-most significant bit to indicate this point
796                // is at infinity.
797                res.0[0] |= 1 << 6;
798            } else {
799                let mut writer = &mut res.0[..];
800
801                affine.x.into_repr().write_be(&mut writer).unwrap();
802                affine.y.into_repr().write_be(&mut writer).unwrap();
803            }
804
805            res
806        }
807    }
808
809    impl RawEncodable for G1Affine {
810        fn into_raw_uncompressed_le(&self) -> Self::Uncompressed {
811            let mut res = Self::Uncompressed::empty();
812            {
813                let mut writer = &mut res.0[..];
814
815                self.x.into_raw_repr().write_le(&mut writer).unwrap();
816                self.y.into_raw_repr().write_le(&mut writer).unwrap();
817            }
818
819            res
820        }
821
822        fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, _infinity: bool) -> Result<Self, GroupDecodingError> {
823            let copy = encoded.0;
824            if copy.iter().all(|b| *b == 0) {
825                return Ok(Self::zero());
826            }
827
828            let mut x = FqRepr([0; 6]);
829            let mut y = FqRepr([0; 6]);
830
831            {
832                let mut reader = &copy[..];
833                x.read_le(&mut reader).unwrap();
834                y.read_le(&mut reader).unwrap();
835            }
836
837            Ok(G1Affine {
838                x: Fq::from_raw_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?,
839                y: Fq::from_raw_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?,
840                infinity: false,
841            })
842        }
843
844        fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result<Self, GroupDecodingError> {
845            let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?;
846
847            if !affine.is_on_curve() {
848                Err(GroupDecodingError::NotOnCurve)
849            } else {
850                Ok(affine)
851            }
852        }
853    }
854
855    #[derive(Copy, Clone)]
856    pub struct G1Compressed([u8; 48]);
857
858    impl AsRef<[u8]> for G1Compressed {
859        fn as_ref(&self) -> &[u8] {
860            &self.0
861        }
862    }
863
864    impl AsMut<[u8]> for G1Compressed {
865        fn as_mut(&mut self) -> &mut [u8] {
866            &mut self.0
867        }
868    }
869
870    impl fmt::Debug for G1Compressed {
871        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
872            self.0[..].fmt(formatter)
873        }
874    }
875
876    impl EncodedPoint for G1Compressed {
877        type Affine = G1Affine;
878
879        fn empty() -> Self {
880            G1Compressed([0; 48])
881        }
882        fn size() -> usize {
883            48
884        }
885        fn into_affine(&self) -> Result<G1Affine, GroupDecodingError> {
886            let affine = self.into_affine_unchecked()?;
887
888            // NB: Decompression guarantees that it is on the curve already.
889
890            if !affine.is_in_correct_subgroup_assuming_on_curve() {
891                Err(GroupDecodingError::NotInSubgroup)
892            } else {
893                Ok(affine)
894            }
895        }
896        fn into_affine_unchecked(&self) -> Result<G1Affine, GroupDecodingError> {
897            // Create a copy of this representation.
898            let mut copy = self.0;
899
900            if copy[0] & (1 << 7) == 0 {
901                // Distinguisher bit isn't set.
902                return Err(GroupDecodingError::UnexpectedCompressionMode);
903            }
904
905            if copy[0] & (1 << 6) != 0 {
906                // This is the point at infinity, which means that if we mask away
907                // the first two bits, the entire representation should consist
908                // of zeroes.
909                copy[0] &= 0x3f;
910
911                if copy.iter().all(|b| *b == 0) {
912                    Ok(G1Affine::zero())
913                } else {
914                    Err(GroupDecodingError::UnexpectedInformation)
915                }
916            } else {
917                // Determine if the intended y coordinate must be greater
918                // lexicographically.
919                let greatest = copy[0] & (1 << 5) != 0;
920
921                // Unset the three most significant bits.
922                copy[0] &= 0x1f;
923
924                let mut x = FqRepr([0; 6]);
925
926                {
927                    let mut reader = &copy[..];
928
929                    x.read_be(&mut reader).unwrap();
930                }
931
932                // Interpret as Fq element.
933                let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?;
934
935                G1Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve)
936            }
937        }
938        fn from_affine(affine: G1Affine) -> Self {
939            let mut res = Self::empty();
940
941            if affine.is_zero() {
942                // Set the second-most significant bit to indicate this point
943                // is at infinity.
944                res.0[0] |= 1 << 6;
945            } else {
946                {
947                    let mut writer = &mut res.0[..];
948
949                    affine.x.into_repr().write_be(&mut writer).unwrap();
950                }
951
952                let mut negy = affine.y;
953                negy.negate();
954
955                // Set the third most significant bit if the correct y-coordinate
956                // is lexicographically largest.
957                if affine.y > negy {
958                    res.0[0] |= 1 << 5;
959                }
960            }
961
962            // Set highest bit to distinguish this as a compressed element.
963            res.0[0] |= 1 << 7;
964
965            res
966        }
967    }
968
969    impl G1Affine {
970        fn scale_by_cofactor(&self) -> G1 {
971            // G1 cofactor = (x - 1)^2 / 3  = 76329603384216526031706109802092473003
972            let cofactor = BitIterator::new([0x8c00aaab0000aaab, 0x396c8c005555e156]);
973            self.mul_bits(cofactor)
974        }
975
976        fn get_generator() -> Self {
977            G1Affine {
978                x: super::super::fq::G1_GENERATOR_X,
979                y: super::super::fq::G1_GENERATOR_Y,
980                infinity: false,
981            }
982        }
983
984        fn get_coeff_b() -> Fq {
985            super::super::fq::B_COEFF
986        }
987
988        fn perform_pairing(&self, other: &G2Affine) -> Fq12 {
989            super::super::Bls12::pairing(*self, *other)
990        }
991    }
992
993    impl G1 {
994        fn empirical_recommended_wnaf_for_scalar(scalar: FrRepr) -> usize {
995            let num_bits = scalar.num_bits() as usize;
996
997            if num_bits >= 130 {
998                4
999            } else if num_bits >= 34 {
1000                3
1001            } else {
1002                2
1003            }
1004        }
1005
1006        fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize {
1007            const RECOMMENDATIONS: [usize; 12] = [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569];
1008
1009            let mut ret = 4;
1010            for r in &RECOMMENDATIONS {
1011                if num_scalars > *r {
1012                    ret += 1;
1013                } else {
1014                    break;
1015                }
1016            }
1017
1018            ret
1019        }
1020    }
1021
1022    #[derive(Clone, Debug)]
1023    pub struct G1Prepared(pub(crate) G1Affine);
1024
1025    impl G1Prepared {
1026        pub fn is_zero(&self) -> bool {
1027            self.0.is_zero()
1028        }
1029
1030        pub fn from_affine(p: G1Affine) -> Self {
1031            G1Prepared(p)
1032        }
1033    }
1034
1035    #[test]
1036    fn g1_generator() {
1037        use SqrtField;
1038
1039        let mut x = Fq::zero();
1040        let mut i = 0;
1041        loop {
1042            // y^2 = x^3 + b
1043            let mut rhs = x;
1044            rhs.square();
1045            rhs.mul_assign(&x);
1046            rhs.add_assign(&G1Affine::get_coeff_b());
1047
1048            if let Some(y) = rhs.sqrt() {
1049                let yrepr = y.into_repr();
1050                let mut negy = y;
1051                negy.negate();
1052                let negyrepr = negy.into_repr();
1053
1054                let p = G1Affine {
1055                    x: x,
1056                    y: if yrepr < negyrepr { y } else { negy },
1057                    infinity: false,
1058                };
1059                assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1060
1061                let g1 = p.scale_by_cofactor();
1062                if !g1.is_zero() {
1063                    assert_eq!(i, 4);
1064                    let g1 = G1Affine::from(g1);
1065
1066                    assert!(g1.is_in_correct_subgroup_assuming_on_curve());
1067
1068                    assert_eq!(g1, G1Affine::one());
1069                    break;
1070                }
1071            }
1072
1073            i += 1;
1074            x.add_assign(&Fq::one());
1075        }
1076    }
1077
1078    #[test]
1079    fn g1_test_is_valid() {
1080        // Reject point on isomorphic twist (b = 24)
1081        {
1082            let p = G1Affine {
1083                x: Fq::from_repr(FqRepr([
1084                    0xc58d887b66c035dc,
1085                    0x10cbfd301d553822,
1086                    0xaf23e064f1131ee5,
1087                    0x9fe83b1b4a5d648d,
1088                    0xf583cc5a508f6a40,
1089                    0xc3ad2aefde0bb13,
1090                ]))
1091                .unwrap(),
1092                y: Fq::from_repr(FqRepr([
1093                    0x60aa6f9552f03aae,
1094                    0xecd01d5181300d35,
1095                    0x8af1cdb8aa8ce167,
1096                    0xe760f57922998c9d,
1097                    0x953703f5795a39e5,
1098                    0xfe3ae0922df702c,
1099                ]))
1100                .unwrap(),
1101                infinity: false,
1102            };
1103            assert!(!p.is_on_curve());
1104            assert!(p.is_in_correct_subgroup_assuming_on_curve());
1105        }
1106
1107        // Reject point on a twist (b = 3)
1108        {
1109            let p = G1Affine {
1110                x: Fq::from_repr(FqRepr([
1111                    0xee6adf83511e15f5,
1112                    0x92ddd328f27a4ba6,
1113                    0xe305bd1ac65adba7,
1114                    0xea034ee2928b30a8,
1115                    0xbd8833dc7c79a7f7,
1116                    0xe45c9f0c0438675,
1117                ]))
1118                .unwrap(),
1119                y: Fq::from_repr(FqRepr([
1120                    0x3b450eb1ab7b5dad,
1121                    0xa65cb81e975e8675,
1122                    0xaa548682b21726e5,
1123                    0x753ddf21a2601d20,
1124                    0x532d0b640bd3ff8b,
1125                    0x118d2c543f031102,
1126                ]))
1127                .unwrap(),
1128                infinity: false,
1129            };
1130            assert!(!p.is_on_curve());
1131            assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1132        }
1133
1134        // Reject point in an invalid subgroup
1135        // There is only one r-order subgroup, as r does not divide the cofactor.
1136        {
1137            let p = G1Affine {
1138                x: Fq::from_repr(FqRepr([
1139                    0x76e1c971c6db8fe8,
1140                    0xe37e1a610eff2f79,
1141                    0x88ae9c499f46f0c0,
1142                    0xf35de9ce0d6b4e84,
1143                    0x265bddd23d1dec54,
1144                    0x12a8778088458308,
1145                ]))
1146                .unwrap(),
1147                y: Fq::from_repr(FqRepr([
1148                    0x8a22defa0d526256,
1149                    0xc57ca55456fcb9ae,
1150                    0x1ba194e89bab2610,
1151                    0x921beef89d4f29df,
1152                    0x5b6fda44ad85fa78,
1153                    0xed74ab9f302cbe0,
1154                ]))
1155                .unwrap(),
1156                infinity: false,
1157            };
1158            assert!(p.is_on_curve());
1159            assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1160        }
1161    }
1162
1163    #[test]
1164    fn test_g1_addition_correctness() {
1165        let mut p = G1 {
1166            x: Fq::from_repr(FqRepr([
1167                0x47fd1f891d6e8bbf,
1168                0x79a3b0448f31a2aa,
1169                0x81f3339e5f9968f,
1170                0x485e77d50a5df10d,
1171                0x4c6fcac4b55fd479,
1172                0x86ed4d9906fb064,
1173            ]))
1174            .unwrap(),
1175            y: Fq::from_repr(FqRepr([
1176                0xd25ee6461538c65,
1177                0x9f3bbb2ecd3719b9,
1178                0xa06fd3f1e540910d,
1179                0xcefca68333c35288,
1180                0x570c8005f8573fa6,
1181                0x152ca696fe034442,
1182            ]))
1183            .unwrap(),
1184            z: Fq::one(),
1185        };
1186
1187        p.add_assign(&G1 {
1188            x: Fq::from_repr(FqRepr([
1189                0xeec78f3096213cbf,
1190                0xa12beb1fea1056e6,
1191                0xc286c0211c40dd54,
1192                0x5f44314ec5e3fb03,
1193                0x24e8538737c6e675,
1194                0x8abd623a594fba8,
1195            ]))
1196            .unwrap(),
1197            y: Fq::from_repr(FqRepr([
1198                0x6b0528f088bb7044,
1199                0x2fdeb5c82917ff9e,
1200                0x9a5181f2fac226ad,
1201                0xd65104c6f95a872a,
1202                0x1f2998a5a9c61253,
1203                0xe74846154a9e44,
1204            ]))
1205            .unwrap(),
1206            z: Fq::one(),
1207        });
1208
1209        let p = G1Affine::from(p);
1210
1211        assert_eq!(
1212            p,
1213            G1Affine {
1214                x: Fq::from_repr(FqRepr([
1215                    0x6dd3098f22235df,
1216                    0xe865d221c8090260,
1217                    0xeb96bb99fa50779f,
1218                    0xc4f9a52a428e23bb,
1219                    0xd178b28dd4f407ef,
1220                    0x17fb8905e9183c69
1221                ]))
1222                .unwrap(),
1223                y: Fq::from_repr(FqRepr([
1224                    0xd0de9d65292b7710,
1225                    0xf6a05f2bcf1d9ca7,
1226                    0x1040e27012f20b64,
1227                    0xeec8d1a5b7466c58,
1228                    0x4bc362649dce6376,
1229                    0x430cbdc5455b00a
1230                ]))
1231                .unwrap(),
1232                infinity: false,
1233            }
1234        );
1235    }
1236
1237    #[test]
1238    fn test_g1_doubling_correctness() {
1239        let mut p = G1 {
1240            x: Fq::from_repr(FqRepr([
1241                0x47fd1f891d6e8bbf,
1242                0x79a3b0448f31a2aa,
1243                0x81f3339e5f9968f,
1244                0x485e77d50a5df10d,
1245                0x4c6fcac4b55fd479,
1246                0x86ed4d9906fb064,
1247            ]))
1248            .unwrap(),
1249            y: Fq::from_repr(FqRepr([
1250                0xd25ee6461538c65,
1251                0x9f3bbb2ecd3719b9,
1252                0xa06fd3f1e540910d,
1253                0xcefca68333c35288,
1254                0x570c8005f8573fa6,
1255                0x152ca696fe034442,
1256            ]))
1257            .unwrap(),
1258            z: Fq::one(),
1259        };
1260
1261        p.double();
1262
1263        let p = G1Affine::from(p);
1264
1265        assert_eq!(
1266            p,
1267            G1Affine {
1268                x: Fq::from_repr(FqRepr([
1269                    0xf939ddfe0ead7018,
1270                    0x3b03942e732aecb,
1271                    0xce0e9c38fdb11851,
1272                    0x4b914c16687dcde0,
1273                    0x66c8baf177d20533,
1274                    0xaf960cff3d83833
1275                ]))
1276                .unwrap(),
1277                y: Fq::from_repr(FqRepr([
1278                    0x3f0675695f5177a8,
1279                    0x2b6d82ae178a1ba0,
1280                    0x9096380dd8e51b11,
1281                    0x1771a65b60572f4e,
1282                    0x8b547c1313b27555,
1283                    0x135075589a687b1e
1284                ]))
1285                .unwrap(),
1286                infinity: false,
1287            }
1288        );
1289    }
1290
1291    #[test]
1292    fn test_g1_same_y() {
1293        // Test the addition of two points with different x coordinates
1294        // but the same y coordinate.
1295
1296        // x1 = 128100205326445210408953809171070606737678357140298133325128175840781723996595026100005714405541449960643523234125
1297        // x2 = 3821408151224848222394078037104966877485040835569514006839342061575586899845797797516352881516922679872117658572470
1298        // y = 2291134451313223670499022936083127939567618746216464377735567679979105510603740918204953301371880765657042046687078
1299
1300        let a = G1Affine {
1301            x: Fq::from_repr(FqRepr([
1302                0xea431f2cc38fc94d,
1303                0x3ad2354a07f5472b,
1304                0xfe669f133f16c26a,
1305                0x71ffa8021531705,
1306                0x7418d484386d267,
1307                0xd5108d8ff1fbd6,
1308            ]))
1309            .unwrap(),
1310            y: Fq::from_repr(FqRepr([
1311                0xa776ccbfe9981766,
1312                0x255632964ff40f4a,
1313                0xc09744e650b00499,
1314                0x520f74773e74c8c3,
1315                0x484c8fc982008f0,
1316                0xee2c3d922008cc6,
1317            ]))
1318            .unwrap(),
1319            infinity: false,
1320        };
1321
1322        let b = G1Affine {
1323            x: Fq::from_repr(FqRepr([
1324                0xe06cdb156b6356b6,
1325                0xd9040b2d75448ad9,
1326                0xe702f14bb0e2aca5,
1327                0xc6e05201e5f83991,
1328                0xf7c75910816f207c,
1329                0x18d4043e78103106,
1330            ]))
1331            .unwrap(),
1332            y: Fq::from_repr(FqRepr([
1333                0xa776ccbfe9981766,
1334                0x255632964ff40f4a,
1335                0xc09744e650b00499,
1336                0x520f74773e74c8c3,
1337                0x484c8fc982008f0,
1338                0xee2c3d922008cc6,
1339            ]))
1340            .unwrap(),
1341            infinity: false,
1342        };
1343
1344        // Expected
1345        // x = 52901198670373960614757979459866672334163627229195745167587898707663026648445040826329033206551534205133090753192
1346        // y = 1711275103908443722918766889652776216989264073722543507596490456144926139887096946237734327757134898380852225872709
1347        let c = G1Affine {
1348            x: Fq::from_repr(FqRepr([
1349                0xef4f05bdd10c8aa8,
1350                0xad5bf87341a2df9,
1351                0x81c7424206b78714,
1352                0x9676ff02ec39c227,
1353                0x4c12c15d7e55b9f3,
1354                0x57fd1e317db9bd,
1355            ]))
1356            .unwrap(),
1357            y: Fq::from_repr(FqRepr([
1358                0x1288334016679345,
1359                0xf955cd68615ff0b5,
1360                0xa6998dbaa600f18a,
1361                0x1267d70db51049fb,
1362                0x4696deb9ab2ba3e7,
1363                0xb1e4e11177f59d4,
1364            ]))
1365            .unwrap(),
1366            infinity: false,
1367        };
1368
1369        assert!(a.is_on_curve() && a.is_in_correct_subgroup_assuming_on_curve());
1370        assert!(b.is_on_curve() && b.is_in_correct_subgroup_assuming_on_curve());
1371        assert!(c.is_on_curve() && c.is_in_correct_subgroup_assuming_on_curve());
1372
1373        let mut tmp1 = a.into_projective();
1374        tmp1.add_assign(&b.into_projective());
1375        assert_eq!(tmp1.into_affine(), c);
1376        assert_eq!(tmp1, c.into_projective());
1377
1378        let mut tmp2 = a.into_projective();
1379        tmp2.add_assign_mixed(&b);
1380        assert_eq!(tmp2.into_affine(), c);
1381        assert_eq!(tmp2, c.into_projective());
1382    }
1383
1384    #[test]
1385    #[ignore] // TODO(ignored-test): Failure.
1386    fn g1_curve_tests() {
1387        crate::tests::curve::curve_tests::<G1>();
1388        crate::tests::curve::random_transformation_tests_with_cofactor::<G1>();
1389    }
1390}
1391
1392pub mod g2 {
1393    use super::super::{Bls12, Fq, Fq12, Fq2, FqRepr, Fr, FrRepr};
1394    use super::g1::G1Affine;
1395    use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError};
1396    use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
1397    use rand::{Rand, Rng};
1398    use std::fmt;
1399
1400    curve_impl!("G2", G2, G2Affine, G2Prepared, Fq2, Fr, G2Uncompressed, G2Compressed, G1Affine);
1401
1402    #[derive(Copy, Clone)]
1403    pub struct G2Uncompressed([u8; 192]);
1404
1405    impl Rand for G2 {
1406        fn rand<R: Rng>(rng: &mut R) -> Self {
1407            loop {
1408                let x = rng.gen();
1409                let greatest = rng.gen();
1410
1411                if let Some(p) = G2Affine::get_point_from_x(x, greatest) {
1412                    if !p.is_zero() {
1413                        if p.is_on_curve() {
1414                            return p.scale_by_cofactor();
1415                        }
1416                    }
1417                }
1418            }
1419        }
1420    }
1421
1422    impl Rand for G2Affine {
1423        fn rand<R: Rng>(rng: &mut R) -> Self {
1424            let r = G2::rand(rng);
1425            return r.into_affine();
1426        }
1427    }
1428
1429    impl AsRef<[u8]> for G2Uncompressed {
1430        fn as_ref(&self) -> &[u8] {
1431            &self.0
1432        }
1433    }
1434
1435    impl AsMut<[u8]> for G2Uncompressed {
1436        fn as_mut(&mut self) -> &mut [u8] {
1437            &mut self.0
1438        }
1439    }
1440
1441    impl fmt::Debug for G2Uncompressed {
1442        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1443            self.0[..].fmt(formatter)
1444        }
1445    }
1446
1447    impl EncodedPoint for G2Uncompressed {
1448        type Affine = G2Affine;
1449
1450        fn empty() -> Self {
1451            G2Uncompressed([0; 192])
1452        }
1453        fn size() -> usize {
1454            192
1455        }
1456        fn into_affine(&self) -> Result<G2Affine, GroupDecodingError> {
1457            let affine = self.into_affine_unchecked()?;
1458
1459            if !affine.is_on_curve() {
1460                Err(GroupDecodingError::NotOnCurve)
1461            } else if !affine.is_in_correct_subgroup_assuming_on_curve() {
1462                Err(GroupDecodingError::NotInSubgroup)
1463            } else {
1464                Ok(affine)
1465            }
1466        }
1467        fn into_affine_unchecked(&self) -> Result<G2Affine, GroupDecodingError> {
1468            // Create a copy of this representation.
1469            let mut copy = self.0;
1470
1471            if copy[0] & (1 << 7) != 0 {
1472                // Distinguisher bit is set, but this should be uncompressed!
1473                return Err(GroupDecodingError::UnexpectedCompressionMode);
1474            }
1475
1476            if copy[0] & (1 << 6) != 0 {
1477                // This is the point at infinity, which means that if we mask away
1478                // the first two bits, the entire representation should consist
1479                // of zeroes.
1480                copy[0] &= 0x3f;
1481
1482                if copy.iter().all(|b| *b == 0) {
1483                    Ok(G2Affine::zero())
1484                } else {
1485                    Err(GroupDecodingError::UnexpectedInformation)
1486                }
1487            } else {
1488                if copy[0] & (1 << 5) != 0 {
1489                    // The bit indicating the y-coordinate should be lexicographically
1490                    // largest is set, but this is an uncompressed element.
1491                    return Err(GroupDecodingError::UnexpectedInformation);
1492                }
1493
1494                // Unset the three most significant bits.
1495                copy[0] &= 0x1f;
1496
1497                let mut x_c0 = FqRepr([0; 6]);
1498                let mut x_c1 = FqRepr([0; 6]);
1499                let mut y_c0 = FqRepr([0; 6]);
1500                let mut y_c1 = FqRepr([0; 6]);
1501
1502                {
1503                    let mut reader = &copy[..];
1504
1505                    x_c1.read_be(&mut reader).unwrap();
1506                    x_c0.read_be(&mut reader).unwrap();
1507                    y_c1.read_be(&mut reader).unwrap();
1508                    y_c0.read_be(&mut reader).unwrap();
1509                }
1510
1511                Ok(G2Affine {
1512                    x: Fq2 {
1513                        c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?,
1514                        c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?,
1515                    },
1516                    y: Fq2 {
1517                        c0: Fq::from_repr(y_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e))?,
1518                        c1: Fq::from_repr(y_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e))?,
1519                    },
1520                    infinity: false,
1521                })
1522            }
1523        }
1524        fn from_affine(affine: G2Affine) -> Self {
1525            let mut res = Self::empty();
1526
1527            if affine.is_zero() {
1528                // Set the second-most significant bit to indicate this point
1529                // is at infinity.
1530                res.0[0] |= 1 << 6;
1531            } else {
1532                let mut writer = &mut res.0[..];
1533
1534                affine.x.c1.into_repr().write_be(&mut writer).unwrap();
1535                affine.x.c0.into_repr().write_be(&mut writer).unwrap();
1536                affine.y.c1.into_repr().write_be(&mut writer).unwrap();
1537                affine.y.c0.into_repr().write_be(&mut writer).unwrap();
1538            }
1539
1540            res
1541        }
1542    }
1543
1544    #[derive(Copy, Clone)]
1545    pub struct G2Compressed([u8; 96]);
1546
1547    impl AsRef<[u8]> for G2Compressed {
1548        fn as_ref(&self) -> &[u8] {
1549            &self.0
1550        }
1551    }
1552
1553    impl AsMut<[u8]> for G2Compressed {
1554        fn as_mut(&mut self) -> &mut [u8] {
1555            &mut self.0
1556        }
1557    }
1558
1559    impl fmt::Debug for G2Compressed {
1560        fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1561            self.0[..].fmt(formatter)
1562        }
1563    }
1564
1565    impl EncodedPoint for G2Compressed {
1566        type Affine = G2Affine;
1567
1568        fn empty() -> Self {
1569            G2Compressed([0; 96])
1570        }
1571        fn size() -> usize {
1572            96
1573        }
1574        fn into_affine(&self) -> Result<G2Affine, GroupDecodingError> {
1575            let affine = self.into_affine_unchecked()?;
1576
1577            // NB: Decompression guarantees that it is on the curve already.
1578
1579            if !affine.is_in_correct_subgroup_assuming_on_curve() {
1580                Err(GroupDecodingError::NotInSubgroup)
1581            } else {
1582                Ok(affine)
1583            }
1584        }
1585        fn into_affine_unchecked(&self) -> Result<G2Affine, GroupDecodingError> {
1586            // Create a copy of this representation.
1587            let mut copy = self.0;
1588
1589            if copy[0] & (1 << 7) == 0 {
1590                // Distinguisher bit isn't set.
1591                return Err(GroupDecodingError::UnexpectedCompressionMode);
1592            }
1593
1594            if copy[0] & (1 << 6) != 0 {
1595                // This is the point at infinity, which means that if we mask away
1596                // the first two bits, the entire representation should consist
1597                // of zeroes.
1598                copy[0] &= 0x3f;
1599
1600                if copy.iter().all(|b| *b == 0) {
1601                    Ok(G2Affine::zero())
1602                } else {
1603                    Err(GroupDecodingError::UnexpectedInformation)
1604                }
1605            } else {
1606                // Determine if the intended y coordinate must be greater
1607                // lexicographically.
1608                let greatest = copy[0] & (1 << 5) != 0;
1609
1610                // Unset the three most significant bits.
1611                copy[0] &= 0x1f;
1612
1613                let mut x_c1 = FqRepr([0; 6]);
1614                let mut x_c0 = FqRepr([0; 6]);
1615
1616                {
1617                    let mut reader = &copy[..];
1618
1619                    x_c1.read_be(&mut reader).unwrap();
1620                    x_c0.read_be(&mut reader).unwrap();
1621                }
1622
1623                // Interpret as Fq element.
1624                let x = Fq2 {
1625                    c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?,
1626                    c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?,
1627                };
1628
1629                G2Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve)
1630            }
1631        }
1632        fn from_affine(affine: G2Affine) -> Self {
1633            let mut res = Self::empty();
1634
1635            if affine.is_zero() {
1636                // Set the second-most significant bit to indicate this point
1637                // is at infinity.
1638                res.0[0] |= 1 << 6;
1639            } else {
1640                {
1641                    let mut writer = &mut res.0[..];
1642
1643                    affine.x.c1.into_repr().write_be(&mut writer).unwrap();
1644                    affine.x.c0.into_repr().write_be(&mut writer).unwrap();
1645                }
1646
1647                let mut negy = affine.y;
1648                negy.negate();
1649
1650                // Set the third most significant bit if the correct y-coordinate
1651                // is lexicographically largest.
1652                if affine.y > negy {
1653                    res.0[0] |= 1 << 5;
1654                }
1655            }
1656
1657            // Set highest bit to distinguish this as a compressed element.
1658            res.0[0] |= 1 << 7;
1659
1660            res
1661        }
1662    }
1663
1664    impl G2Affine {
1665        fn get_generator() -> Self {
1666            G2Affine {
1667                x: Fq2 {
1668                    c0: super::super::fq::G2_GENERATOR_X_C0,
1669                    c1: super::super::fq::G2_GENERATOR_X_C1,
1670                },
1671                y: Fq2 {
1672                    c0: super::super::fq::G2_GENERATOR_Y_C0,
1673                    c1: super::super::fq::G2_GENERATOR_Y_C1,
1674                },
1675                infinity: false,
1676            }
1677        }
1678
1679        fn get_coeff_b() -> Fq2 {
1680            Fq2 {
1681                c0: super::super::fq::B_COEFF,
1682                c1: super::super::fq::B_COEFF,
1683            }
1684        }
1685
1686        fn scale_by_cofactor(&self) -> G2 {
1687            // G2 cofactor = (x^8 - 4 x^7 + 5 x^6) - (4 x^4 + 6 x^3 - 4 x^2 - 4 x + 13) // 9
1688            // 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5
1689            let cofactor = BitIterator::new([
1690                0xcf1c38e31c7238e5,
1691                0x1616ec6e786f0c70,
1692                0x21537e293a6691ae,
1693                0xa628f1cb4d9e82ef,
1694                0xa68a205b2e5a7ddf,
1695                0xcd91de4547085aba,
1696                0x91d50792876a202,
1697                0x5d543a95414e7f1,
1698            ]);
1699            self.mul_bits(cofactor)
1700        }
1701
1702        fn perform_pairing(&self, other: &G1Affine) -> Fq12 {
1703            super::super::Bls12::pairing(*other, *self)
1704        }
1705    }
1706
1707    impl G2 {
1708        fn empirical_recommended_wnaf_for_scalar(scalar: FrRepr) -> usize {
1709            let num_bits = scalar.num_bits() as usize;
1710
1711            if num_bits >= 103 {
1712                4
1713            } else if num_bits >= 37 {
1714                3
1715            } else {
1716                2
1717            }
1718        }
1719
1720        fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize {
1721            const RECOMMENDATIONS: [usize; 11] = [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071];
1722
1723            let mut ret = 4;
1724            for r in &RECOMMENDATIONS {
1725                if num_scalars > *r {
1726                    ret += 1;
1727                } else {
1728                    break;
1729                }
1730            }
1731
1732            ret
1733        }
1734    }
1735
1736    #[derive(Clone, Debug)]
1737    pub struct G2Prepared {
1738        pub(crate) coeffs: Vec<(Fq2, Fq2, Fq2)>,
1739        pub(crate) infinity: bool,
1740    }
1741
1742    #[test]
1743    fn g2_generator() {
1744        use SqrtField;
1745
1746        let mut x = Fq2::zero();
1747        let mut i = 0;
1748        loop {
1749            // y^2 = x^3 + b
1750            let mut rhs = x;
1751            rhs.square();
1752            rhs.mul_assign(&x);
1753            rhs.add_assign(&G2Affine::get_coeff_b());
1754
1755            if let Some(y) = rhs.sqrt() {
1756                let mut negy = y;
1757                negy.negate();
1758
1759                let p = G2Affine {
1760                    x: x,
1761                    y: if y < negy { y } else { negy },
1762                    infinity: false,
1763                };
1764
1765                assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1766
1767                let g2 = p.scale_by_cofactor();
1768                if !g2.is_zero() {
1769                    assert_eq!(i, 2);
1770                    let g2 = G2Affine::from(g2);
1771
1772                    assert!(g2.is_in_correct_subgroup_assuming_on_curve());
1773                    assert_eq!(g2, G2Affine::one());
1774                    break;
1775                }
1776            }
1777
1778            i += 1;
1779            x.add_assign(&Fq2::one());
1780        }
1781    }
1782
1783    #[test]
1784    fn g2_test_is_valid() {
1785        // Reject point on isomorphic twist (b = 3 * (u + 1))
1786        {
1787            let p = G2Affine {
1788                x: Fq2 {
1789                    c0: Fq::from_repr(FqRepr([
1790                        0xa757072d9fa35ba9,
1791                        0xae3fb2fb418f6e8a,
1792                        0xc1598ec46faa0c7c,
1793                        0x7a17a004747e3dbe,
1794                        0xcc65406a7c2e5a73,
1795                        0x10b8c03d64db4d0c,
1796                    ]))
1797                    .unwrap(),
1798                    c1: Fq::from_repr(FqRepr([
1799                        0xd30e70fe2f029778,
1800                        0xda30772df0f5212e,
1801                        0x5b47a9ff9a233a50,
1802                        0xfb777e5b9b568608,
1803                        0x789bac1fec71a2b9,
1804                        0x1342f02e2da54405,
1805                    ]))
1806                    .unwrap(),
1807                },
1808                y: Fq2 {
1809                    c0: Fq::from_repr(FqRepr([
1810                        0xfe0812043de54dca,
1811                        0xe455171a3d47a646,
1812                        0xa493f36bc20be98a,
1813                        0x663015d9410eb608,
1814                        0x78e82a79d829a544,
1815                        0x40a00545bb3c1e,
1816                    ]))
1817                    .unwrap(),
1818                    c1: Fq::from_repr(FqRepr([
1819                        0x4709802348e79377,
1820                        0xb5ac4dc9204bcfbd,
1821                        0xda361c97d02f42b2,
1822                        0x15008b1dc399e8df,
1823                        0x68128fd0548a3829,
1824                        0x16a613db5c873aaa,
1825                    ]))
1826                    .unwrap(),
1827                },
1828                infinity: false,
1829            };
1830            assert!(!p.is_on_curve());
1831            assert!(p.is_in_correct_subgroup_assuming_on_curve());
1832        }
1833
1834        // Reject point on a twist (b = 2 * (u + 1))
1835        {
1836            let p = G2Affine {
1837                x: Fq2 {
1838                    c0: Fq::from_repr(FqRepr([
1839                        0xf4fdfe95a705f917,
1840                        0xc2914df688233238,
1841                        0x37c6b12cca35a34b,
1842                        0x41abba710d6c692c,
1843                        0xffcc4b2b62ce8484,
1844                        0x6993ec01b8934ed,
1845                    ]))
1846                    .unwrap(),
1847                    c1: Fq::from_repr(FqRepr([
1848                        0xb94e92d5f874e26,
1849                        0x44516408bc115d95,
1850                        0xe93946b290caa591,
1851                        0xa5a0c2b7131f3555,
1852                        0x83800965822367e7,
1853                        0x10cf1d3ad8d90bfa,
1854                    ]))
1855                    .unwrap(),
1856                },
1857                y: Fq2 {
1858                    c0: Fq::from_repr(FqRepr([
1859                        0xbf00334c79701d97,
1860                        0x4fe714f9ff204f9a,
1861                        0xab70b28002f3d825,
1862                        0x5a9171720e73eb51,
1863                        0x38eb4fd8d658adb7,
1864                        0xb649051bbc1164d,
1865                    ]))
1866                    .unwrap(),
1867                    c1: Fq::from_repr(FqRepr([
1868                        0x9225814253d7df75,
1869                        0xc196c2513477f887,
1870                        0xe05e2fbd15a804e0,
1871                        0x55f2b8efad953e04,
1872                        0x7379345eda55265e,
1873                        0x377f2e6208fd4cb,
1874                    ]))
1875                    .unwrap(),
1876                },
1877                infinity: false,
1878            };
1879            assert!(!p.is_on_curve());
1880            assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1881        }
1882
1883        // Reject point in an invalid subgroup
1884        // There is only one r-order subgroup, as r does not divide the cofactor.
1885        {
1886            let p = G2Affine {
1887                x: Fq2 {
1888                    c0: Fq::from_repr(FqRepr([
1889                        0x262cea73ea1906c,
1890                        0x2f08540770fabd6,
1891                        0x4ceb92d0a76057be,
1892                        0x2199bc19c48c393d,
1893                        0x4a151b732a6075bf,
1894                        0x17762a3b9108c4a7,
1895                    ]))
1896                    .unwrap(),
1897                    c1: Fq::from_repr(FqRepr([
1898                        0x26f461e944bbd3d1,
1899                        0x298f3189a9cf6ed6,
1900                        0x74328ad8bc2aa150,
1901                        0x7e147f3f9e6e241,
1902                        0x72a9b63583963fff,
1903                        0x158b0083c000462,
1904                    ]))
1905                    .unwrap(),
1906                },
1907                y: Fq2 {
1908                    c0: Fq::from_repr(FqRepr([
1909                        0x91fb0b225ecf103b,
1910                        0x55d42edc1dc46ba0,
1911                        0x43939b11997b1943,
1912                        0x68cad19430706b4d,
1913                        0x3ccfb97b924dcea8,
1914                        0x1660f93434588f8d,
1915                    ]))
1916                    .unwrap(),
1917                    c1: Fq::from_repr(FqRepr([
1918                        0xaaed3985b6dcb9c7,
1919                        0xc1e985d6d898d9f4,
1920                        0x618bd2ac3271ac42,
1921                        0x3940a2dbb914b529,
1922                        0xbeb88137cf34f3e7,
1923                        0x1699ee577c61b694,
1924                    ]))
1925                    .unwrap(),
1926                },
1927                infinity: false,
1928            };
1929            assert!(p.is_on_curve());
1930            assert!(!p.is_in_correct_subgroup_assuming_on_curve());
1931        }
1932    }
1933
1934    #[test]
1935    fn test_g2_addition_correctness() {
1936        let mut p = G2 {
1937            x: Fq2 {
1938                c0: Fq::from_repr(FqRepr([
1939                    0x6c994cc1e303094e,
1940                    0xf034642d2c9e85bd,
1941                    0x275094f1352123a9,
1942                    0x72556c999f3707ac,
1943                    0x4617f2e6774e9711,
1944                    0x100b2fe5bffe030b,
1945                ]))
1946                .unwrap(),
1947                c1: Fq::from_repr(FqRepr([
1948                    0x7a33555977ec608,
1949                    0xe23039d1fe9c0881,
1950                    0x19ce4678aed4fcb5,
1951                    0x4637c4f417667e2e,
1952                    0x93ebe7c3e41f6acc,
1953                    0xde884f89a9a371b,
1954                ]))
1955                .unwrap(),
1956            },
1957            y: Fq2 {
1958                c0: Fq::from_repr(FqRepr([
1959                    0xe073119472e1eb62,
1960                    0x44fb3391fe3c9c30,
1961                    0xaa9b066d74694006,
1962                    0x25fd427b4122f231,
1963                    0xd83112aace35cae,
1964                    0x191b2432407cbb7f,
1965                ]))
1966                .unwrap(),
1967                c1: Fq::from_repr(FqRepr([
1968                    0xf68ae82fe97662f5,
1969                    0xe986057068b50b7d,
1970                    0x96c30f0411590b48,
1971                    0x9eaa6d19de569196,
1972                    0xf6a03d31e2ec2183,
1973                    0x3bdafaf7ca9b39b,
1974                ]))
1975                .unwrap(),
1976            },
1977            z: Fq2::one(),
1978        };
1979
1980        p.add_assign(&G2 {
1981            x: Fq2 {
1982                c0: Fq::from_repr(FqRepr([
1983                    0xa8c763d25910bdd3,
1984                    0x408777b30ca3add4,
1985                    0x6115fcc12e2769e,
1986                    0x8e73a96b329ad190,
1987                    0x27c546f75ee1f3ab,
1988                    0xa33d27add5e7e82,
1989                ]))
1990                .unwrap(),
1991                c1: Fq::from_repr(FqRepr([
1992                    0x93b1ebcd54870dfe,
1993                    0xf1578300e1342e11,
1994                    0x8270dca3a912407b,
1995                    0x2089faf462438296,
1996                    0x828e5848cd48ea66,
1997                    0x141ecbac1deb038b,
1998                ]))
1999                .unwrap(),
2000            },
2001            y: Fq2 {
2002                c0: Fq::from_repr(FqRepr([
2003                    0xf5d2c28857229c3f,
2004                    0x8c1574228757ca23,
2005                    0xe8d8102175f5dc19,
2006                    0x2767032fc37cc31d,
2007                    0xd5ee2aba84fd10fe,
2008                    0x16576ccd3dd0a4e8,
2009                ]))
2010                .unwrap(),
2011                c1: Fq::from_repr(FqRepr([
2012                    0x4da9b6f6a96d1dd2,
2013                    0x9657f7da77f1650e,
2014                    0xbc150712f9ffe6da,
2015                    0x31898db63f87363a,
2016                    0xabab040ddbd097cc,
2017                    0x11ad236b9ba02990,
2018                ]))
2019                .unwrap(),
2020            },
2021            z: Fq2::one(),
2022        });
2023
2024        let p = G2Affine::from(p);
2025
2026        assert_eq!(
2027            p,
2028            G2Affine {
2029                x: Fq2 {
2030                    c0: Fq::from_repr(FqRepr([
2031                        0xcde7ee8a3f2ac8af,
2032                        0xfc642eb35975b069,
2033                        0xa7de72b7dd0e64b7,
2034                        0xf1273e6406eef9cc,
2035                        0xababd760ff05cb92,
2036                        0xd7c20456617e89
2037                    ]))
2038                    .unwrap(),
2039                    c1: Fq::from_repr(FqRepr([
2040                        0xd1a50b8572cbd2b8,
2041                        0x238f0ac6119d07df,
2042                        0x4dbe924fe5fd6ac2,
2043                        0x8b203284c51edf6b,
2044                        0xc8a0b730bbb21f5e,
2045                        0x1a3b59d29a31274
2046                    ]))
2047                    .unwrap(),
2048                },
2049                y: Fq2 {
2050                    c0: Fq::from_repr(FqRepr([
2051                        0x9e709e78a8eaa4c9,
2052                        0xd30921c93ec342f4,
2053                        0x6d1ef332486f5e34,
2054                        0x64528ab3863633dc,
2055                        0x159384333d7cba97,
2056                        0x4cb84741f3cafe8
2057                    ]))
2058                    .unwrap(),
2059                    c1: Fq::from_repr(FqRepr([
2060                        0x242af0dc3640e1a4,
2061                        0xe90a73ad65c66919,
2062                        0x2bd7ca7f4346f9ec,
2063                        0x38528f92b689644d,
2064                        0xb6884deec59fb21f,
2065                        0x3c075d3ec52ba90
2066                    ]))
2067                    .unwrap(),
2068                },
2069                infinity: false,
2070            }
2071        );
2072    }
2073
2074    #[test]
2075    fn test_g2_doubling_correctness() {
2076        let mut p = G2 {
2077            x: Fq2 {
2078                c0: Fq::from_repr(FqRepr([
2079                    0x6c994cc1e303094e,
2080                    0xf034642d2c9e85bd,
2081                    0x275094f1352123a9,
2082                    0x72556c999f3707ac,
2083                    0x4617f2e6774e9711,
2084                    0x100b2fe5bffe030b,
2085                ]))
2086                .unwrap(),
2087                c1: Fq::from_repr(FqRepr([
2088                    0x7a33555977ec608,
2089                    0xe23039d1fe9c0881,
2090                    0x19ce4678aed4fcb5,
2091                    0x4637c4f417667e2e,
2092                    0x93ebe7c3e41f6acc,
2093                    0xde884f89a9a371b,
2094                ]))
2095                .unwrap(),
2096            },
2097            y: Fq2 {
2098                c0: Fq::from_repr(FqRepr([
2099                    0xe073119472e1eb62,
2100                    0x44fb3391fe3c9c30,
2101                    0xaa9b066d74694006,
2102                    0x25fd427b4122f231,
2103                    0xd83112aace35cae,
2104                    0x191b2432407cbb7f,
2105                ]))
2106                .unwrap(),
2107                c1: Fq::from_repr(FqRepr([
2108                    0xf68ae82fe97662f5,
2109                    0xe986057068b50b7d,
2110                    0x96c30f0411590b48,
2111                    0x9eaa6d19de569196,
2112                    0xf6a03d31e2ec2183,
2113                    0x3bdafaf7ca9b39b,
2114                ]))
2115                .unwrap(),
2116            },
2117            z: Fq2::one(),
2118        };
2119
2120        p.double();
2121
2122        let p = G2Affine::from(p);
2123
2124        assert_eq!(
2125            p,
2126            G2Affine {
2127                x: Fq2 {
2128                    c0: Fq::from_repr(FqRepr([
2129                        0x91ccb1292727c404,
2130                        0x91a6cb182438fad7,
2131                        0x116aee59434de902,
2132                        0xbcedcfce1e52d986,
2133                        0x9755d4a3926e9862,
2134                        0x18bab73760fd8024
2135                    ]))
2136                    .unwrap(),
2137                    c1: Fq::from_repr(FqRepr([
2138                        0x4e7c5e0a2ae5b99e,
2139                        0x96e582a27f028961,
2140                        0xc74d1cf4ef2d5926,
2141                        0xeb0cf5e610ef4fe7,
2142                        0x7b4c2bae8db6e70b,
2143                        0xf136e43909fca0
2144                    ]))
2145                    .unwrap(),
2146                },
2147                y: Fq2 {
2148                    c0: Fq::from_repr(FqRepr([
2149                        0x954d4466ab13e58,
2150                        0x3ee42eec614cf890,
2151                        0x853bb1d28877577e,
2152                        0xa5a2a51f7fde787b,
2153                        0x8b92866bc6384188,
2154                        0x81a53fe531d64ef
2155                    ]))
2156                    .unwrap(),
2157                    c1: Fq::from_repr(FqRepr([
2158                        0x4c5d607666239b34,
2159                        0xeddb5f48304d14b3,
2160                        0x337167ee6e8e3cb6,
2161                        0xb271f52f12ead742,
2162                        0x244e6c2015c83348,
2163                        0x19e2deae6eb9b441
2164                    ]))
2165                    .unwrap(),
2166                },
2167                infinity: false,
2168            }
2169        );
2170    }
2171
2172    #[test]
2173    #[ignore] // TODO(ignored-test): Timeout.
2174    fn g2_curve_tests() {
2175        crate::tests::curve::curve_tests::<G2>();
2176        crate::tests::curve::random_transformation_tests_with_cofactor::<G2>();
2177    }
2178}
2179
2180pub use self::g1::*;
2181pub use self::g2::*;