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 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 fn get_point_from_x(x: $basefield, greatest: bool) -> Option<$affine> {
103 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 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 CurveProjective for $projective {
247 type Engine = Bls12;
248 type Scalar = $scalarfield;
249 type Base = $basefield;
250 type Affine = $affine;
251
252 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 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 let mut prod = Vec::with_capacity(v.len());
283 let mut tmp = $basefield::one();
284 for g in v
285 .iter_mut()
286 .filter(|g| !g.is_normalized())
288 {
289 tmp.mul_assign(&g.z);
290 prod.push(tmp);
291 }
292
293 tmp = tmp.inverse().unwrap(); for (g, s) in v
298 .iter_mut()
299 .rev()
301 .filter(|g| !g.is_normalized())
303 .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one())))
305 {
306 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 for g in v.iter_mut().filter(|g| !g.is_normalized()) {
316 let mut z = g.z; z.square(); g.x.mul_assign(&z); z.mul_assign(&g.z); g.y.mul_assign(&z); g.z = $basefield::one(); }
323 }
324
325 fn double(&mut self) {
326 if self.is_zero() {
327 return;
328 }
329
330 let mut a = self.x;
339 a.square();
340
341 let mut b = self.y;
343 b.square();
344
345 let mut c = b;
347 c.square();
348
349 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 let mut e = a;
359 e.double();
360 e.add_assign(&a);
361
362 let mut f = e;
364 f.square();
365
366 self.z.mul_assign(&self.y);
368 self.z.double();
369
370 self.x = f;
372 self.x.sub_assign(&d);
373 self.x.sub_assign(&d);
374
375 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 let mut z1z1 = self.z;
399 z1z1.square();
400
401 let mut z2z2 = other.z;
403 z2z2.square();
404
405 let mut u1 = self.x;
407 u1.mul_assign(&z2z2);
408
409 let mut u2 = other.x;
411 u2.mul_assign(&z1z1);
412
413 let mut s1 = self.y;
415 s1.mul_assign(&other.z);
416 s1.mul_assign(&z2z2);
417
418 let mut s2 = other.y;
420 s2.mul_assign(&self.z);
421 s2.mul_assign(&z1z1);
422
423 if u1 == u2 && s1 == s2 {
424 self.double();
426 } else {
427 let mut h = u2;
431 h.sub_assign(&u1);
432
433 let mut i = h;
435 i.double();
436 i.square();
437
438 let mut j = h;
440 j.mul_assign(&i);
441
442 let mut r = s2;
444 r.sub_assign(&s1);
445 r.double();
446
447 let mut v = u1;
449 v.mul_assign(&i);
450
451 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 self.y = v;
460 self.y.sub_assign(&self.x);
461 self.y.mul_assign(&r);
462 s1.mul_assign(&j); s1.double();
464 self.y.sub_assign(&s1);
465
466 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 let mut z1z1 = self.z;
491 z1z1.square();
492
493 let mut u2 = other.x;
495 u2.mul_assign(&z1z1);
496
497 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 self.double();
505 } else {
506 let mut h = u2;
510 h.sub_assign(&self.x);
511
512 let mut hh = h;
514 hh.square();
515
516 let mut i = hh;
518 i.double();
519 i.double();
520
521 let mut j = h;
523 j.mul_assign(&i);
524
525 let mut r = s2;
527 r.sub_assign(&self.y);
528 r.double();
529
530 let mut v = self.x;
532 v.mul_assign(&i);
533
534 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 j.mul_assign(&self.y); 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 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 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 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 $affine { x: p.x, y: p.y, infinity: false }
637 } else {
638 let zinv = p.z.inverse().unwrap();
640 let mut zinv_powered = zinv;
641 zinv_powered.square();
642
643 let mut x = p.x;
645 x.mul_assign(&zinv_powered);
646
647 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 let mut copy = self.0;
747
748 if copy[0] & (1 << 7) != 0 {
749 return Err(GroupDecodingError::UnexpectedCompressionMode);
751 }
752
753 if copy[0] & (1 << 6) != 0 {
754 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 return Err(GroupDecodingError::UnexpectedInformation);
769 }
770
771 copy[0] &= 0x1f;
773
774 let mut x = FqRepr([0; 6]);
775 let mut y = FqRepr([0; 6]);
776
777 {
778 let mut reader = ©[..];
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 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 = ©[..];
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 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 let mut copy = self.0;
899
900 if copy[0] & (1 << 7) == 0 {
901 return Err(GroupDecodingError::UnexpectedCompressionMode);
903 }
904
905 if copy[0] & (1 << 6) != 0 {
906 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 let greatest = copy[0] & (1 << 5) != 0;
920
921 copy[0] &= 0x1f;
923
924 let mut x = FqRepr([0; 6]);
925
926 {
927 let mut reader = ©[..];
928
929 x.read_be(&mut reader).unwrap();
930 }
931
932 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 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 if affine.y > negy {
958 res.0[0] |= 1 << 5;
959 }
960 }
961
962 res.0[0] |= 1 << 7;
964
965 res
966 }
967 }
968
969 impl G1Affine {
970 fn scale_by_cofactor(&self) -> G1 {
971 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 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 {
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 {
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 {
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 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 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] 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 let mut copy = self.0;
1470
1471 if copy[0] & (1 << 7) != 0 {
1472 return Err(GroupDecodingError::UnexpectedCompressionMode);
1474 }
1475
1476 if copy[0] & (1 << 6) != 0 {
1477 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 return Err(GroupDecodingError::UnexpectedInformation);
1492 }
1493
1494 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 = ©[..];
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 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 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 let mut copy = self.0;
1588
1589 if copy[0] & (1 << 7) == 0 {
1590 return Err(GroupDecodingError::UnexpectedCompressionMode);
1592 }
1593
1594 if copy[0] & (1 << 6) != 0 {
1595 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 let greatest = copy[0] & (1 << 5) != 0;
1609
1610 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 = ©[..];
1618
1619 x_c1.read_be(&mut reader).unwrap();
1620 x_c0.read_be(&mut reader).unwrap();
1621 }
1622
1623 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 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 if affine.y > negy {
1653 res.0[0] |= 1 << 5;
1654 }
1655 }
1656
1657 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 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 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 {
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 {
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 {
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] 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::*;