1use crate::error::{validate, Error, Result};
4use core::borrow::Borrow;
5use core::fmt;
6use core::iter::Sum;
7use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8use rand_core::RngCore;
9use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
10
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13#[cfg(feature = "alloc")]
14use alloc::vec;
15
16use super::field::fp::Fp;
17use super::Scalar;
18
19#[derive(Copy, Clone, Debug)]
21pub struct G1Affine {
22 pub(crate) x: Fp,
23 pub(crate) y: Fp,
24 infinity: Choice,
25}
26
27impl Default for G1Affine {
28 fn default() -> G1Affine {
29 G1Affine::identity()
30 }
31}
32
33#[cfg(feature = "zeroize")]
34impl zeroize::DefaultIsZeroes for G1Affine {}
35
36impl fmt::Display for G1Affine {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "{:?}", self)
39 }
40}
41
42impl<'a> From<&'a G1Projective> for G1Affine {
43 fn from(p: &'a G1Projective) -> G1Affine {
44 let zinv = p.z.invert().unwrap_or(Fp::zero());
45 let x = p.x * zinv;
46 let y = p.y * zinv;
47
48 let tmp = G1Affine {
49 x,
50 y,
51 infinity: Choice::from(0u8),
52 };
53
54 G1Affine::conditional_select(&tmp, &G1Affine::identity(), zinv.is_zero())
55 }
56}
57
58impl From<G1Projective> for G1Affine {
59 fn from(p: G1Projective) -> G1Affine {
60 G1Affine::from(&p)
61 }
62}
63
64impl ConstantTimeEq for G1Affine {
65 fn ct_eq(&self, other: &Self) -> Choice {
66 (self.infinity & other.infinity)
67 | ((!self.infinity)
68 & (!other.infinity)
69 & self.x.ct_eq(&other.x)
70 & self.y.ct_eq(&other.y))
71 }
72}
73
74impl ConditionallySelectable for G1Affine {
75 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
76 G1Affine {
77 x: Fp::conditional_select(&a.x, &b.x, choice),
78 y: Fp::conditional_select(&a.y, &b.y, choice),
79 infinity: Choice::conditional_select(&a.infinity, &b.infinity, choice),
80 }
81 }
82}
83
84impl Eq for G1Affine {}
85impl PartialEq for G1Affine {
86 #[inline]
87 fn eq(&self, other: &Self) -> bool {
88 bool::from(self.ct_eq(other))
89 }
90}
91
92impl<'a> Neg for &'a G1Affine {
93 type Output = G1Affine;
94
95 #[inline]
96 fn neg(self) -> G1Affine {
97 G1Affine {
98 x: self.x,
99 y: Fp::conditional_select(&-self.y, &Fp::one(), self.infinity),
100 infinity: self.infinity,
101 }
102 }
103}
104
105impl Neg for G1Affine {
106 type Output = G1Affine;
107
108 #[inline]
109 fn neg(self) -> G1Affine {
110 -&self
111 }
112}
113
114impl<'a, 'b> Add<&'b G1Projective> for &'a G1Affine {
115 type Output = G1Projective;
116
117 #[inline]
118 fn add(self, rhs: &'b G1Projective) -> G1Projective {
119 rhs.add_mixed(self)
120 }
121}
122
123impl<'a, 'b> Add<&'b G1Affine> for &'a G1Projective {
124 type Output = G1Projective;
125
126 #[inline]
127 fn add(self, rhs: &'b G1Affine) -> G1Projective {
128 self.add_mixed(rhs)
129 }
130}
131
132impl<'a, 'b> Sub<&'b G1Projective> for &'a G1Affine {
133 type Output = G1Projective;
134
135 #[inline]
136 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
137 self + &(-rhs)
138 }
139}
140
141impl<'a, 'b> Sub<&'b G1Affine> for &'a G1Projective {
142 type Output = G1Projective;
143
144 #[inline]
145 fn sub(self, rhs: &'b G1Affine) -> G1Projective {
146 self + &(-rhs)
147 }
148}
149
150impl<T> Sum<T> for G1Projective
151where
152 T: Borrow<G1Projective>,
153{
154 fn sum<I>(iter: I) -> Self
155 where
156 I: Iterator<Item = T>,
157 {
158 iter.fold(Self::identity(), |acc, item| acc + item.borrow())
159 }
160}
161
162impl<'b> Add<&'b G1Affine> for G1Projective {
164 type Output = G1Projective;
165 #[inline]
166 fn add(self, rhs: &'b G1Affine) -> G1Projective {
167 &self + rhs
168 }
169}
170impl<'a> Add<G1Affine> for &'a G1Projective {
171 type Output = G1Projective;
172 #[inline]
173 fn add(self, rhs: G1Affine) -> G1Projective {
174 self + &rhs
175 }
176}
177impl Add<G1Affine> for G1Projective {
178 type Output = G1Projective;
179 #[inline]
180 fn add(self, rhs: G1Affine) -> G1Projective {
181 &self + &rhs
182 }
183}
184impl<'b> Sub<&'b G1Affine> for G1Projective {
185 type Output = G1Projective;
186 #[inline]
187 fn sub(self, rhs: &'b G1Affine) -> G1Projective {
188 &self - rhs
189 }
190}
191impl<'a> Sub<G1Affine> for &'a G1Projective {
192 type Output = G1Projective;
193 #[inline]
194 fn sub(self, rhs: G1Affine) -> G1Projective {
195 self - &rhs
196 }
197}
198impl Sub<G1Affine> for G1Projective {
199 type Output = G1Projective;
200 #[inline]
201 fn sub(self, rhs: G1Affine) -> G1Projective {
202 &self - &rhs
203 }
204}
205impl SubAssign<G1Affine> for G1Projective {
206 #[inline]
207 fn sub_assign(&mut self, rhs: G1Affine) {
208 *self = &*self - &rhs;
209 }
210}
211impl AddAssign<G1Affine> for G1Projective {
212 #[inline]
213 fn add_assign(&mut self, rhs: G1Affine) {
214 *self = &*self + &rhs;
215 }
216}
217impl<'b> SubAssign<&'b G1Affine> for G1Projective {
218 #[inline]
219 fn sub_assign(&mut self, rhs: &'b G1Affine) {
220 *self = &*self - rhs;
221 }
222}
223impl<'b> AddAssign<&'b G1Affine> for G1Projective {
224 #[inline]
225 fn add_assign(&mut self, rhs: &'b G1Affine) {
226 *self = &*self + rhs;
227 }
228}
229
230impl<'b> Add<&'b G1Projective> for G1Affine {
232 type Output = G1Projective;
233 #[inline]
234 fn add(self, rhs: &'b G1Projective) -> G1Projective {
235 &self + rhs
236 }
237}
238impl<'a> Add<G1Projective> for &'a G1Affine {
239 type Output = G1Projective;
240 #[inline]
241 fn add(self, rhs: G1Projective) -> G1Projective {
242 self + &rhs
243 }
244}
245impl Add<G1Projective> for G1Affine {
246 type Output = G1Projective;
247 #[inline]
248 fn add(self, rhs: G1Projective) -> G1Projective {
249 &self + &rhs
250 }
251}
252impl<'b> Sub<&'b G1Projective> for G1Affine {
253 type Output = G1Projective;
254 #[inline]
255 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
256 &self - rhs
257 }
258}
259impl<'a> Sub<G1Projective> for &'a G1Affine {
260 type Output = G1Projective;
261 #[inline]
262 fn sub(self, rhs: G1Projective) -> G1Projective {
263 self - &rhs
264 }
265}
266impl Sub<G1Projective> for G1Affine {
267 type Output = G1Projective;
268 #[inline]
269 fn sub(self, rhs: G1Projective) -> G1Projective {
270 &self - &rhs
271 }
272}
273
274const B: Fp = Fp::from_raw_unchecked([
276 0xaa27_0000_000c_fff3,
277 0x53cc_0032_fc34_000a,
278 0x478f_e97a_6b0a_807f,
279 0xb1d3_7ebe_e6ba_24d7,
280 0x8ec9_733b_bf78_ab2f,
281 0x09d6_4551_3d83_de7e,
282]);
283
284pub const BETA: Fp = Fp::from_raw_unchecked([
286 0x30f1_361b_798a_64e8,
287 0xf3b8_ddab_7ece_5a2a,
288 0x16a8_ca3a_c615_77f7,
289 0xc26a_2ff8_74fd_029b,
290 0x3636_b766_6070_1c6e,
291 0x051b_a4ab_241b_6160,
292]);
293
294fn endomorphism(p: &G1Affine) -> G1Affine {
295 let mut res = *p;
296 res.x *= BETA;
297 res
298}
299
300impl G1Affine {
301 pub fn identity() -> G1Affine {
303 G1Affine {
304 x: Fp::zero(),
305 y: Fp::one(),
306 infinity: Choice::from(1u8),
307 }
308 }
309
310 pub fn generator() -> G1Affine {
312 G1Affine {
313 x: Fp::from_raw_unchecked([
314 0x5cb3_8790_fd53_0c16,
315 0x7817_fc67_9976_fff5,
316 0x154f_95c7_143b_a1c1,
317 0xf0ae_6acd_f3d0_e747,
318 0xedce_6ecc_21db_f440,
319 0x1201_7741_9e0b_fb75,
320 ]),
321 y: Fp::from_raw_unchecked([
322 0xbaac_93d5_0ce7_2271,
323 0x8c22_631a_7918_fd8e,
324 0xdd59_5f13_5707_25ce,
325 0x51ac_5829_5040_5194,
326 0x0e1c_8c3f_ad00_59c0,
327 0x0bbc_3efc_5008_a26a,
328 ]),
329 infinity: Choice::from(0u8),
330 }
331 }
332
333 #[inline]
335 pub fn is_identity(&self) -> Choice {
336 self.infinity
337 }
338
339 pub fn is_on_curve(&self) -> Choice {
341 (self.y.square() - (self.x.square() * self.x)).ct_eq(&B) | self.infinity
342 }
343
344 pub fn is_torsion_free(&self) -> Choice {
346 let minus_x_squared_times_p = G1Projective::from(self).mul_by_x().mul_by_x().neg();
347 let endomorphism_p = endomorphism(self);
348 minus_x_squared_times_p.ct_eq(&G1Projective::from(endomorphism_p))
349 }
350
351 pub fn to_compressed(&self) -> [u8; 48] {
353 let mut res = Fp::conditional_select(&self.x, &Fp::zero(), self.infinity).to_bytes();
354 res[0] |= 1u8 << 7; res[0] |= u8::conditional_select(&0u8, &(1u8 << 6), self.infinity); res[0] |= u8::conditional_select(
357 &0u8,
358 &(1u8 << 5),
359 (!self.infinity) & self.y.lexicographically_largest(), );
361 res
362 }
363
364 pub fn to_uncompressed(&self) -> [u8; 96] {
366 let mut res = [0; 96];
367 res[0..48].copy_from_slice(
368 &Fp::conditional_select(&self.x, &Fp::zero(), self.infinity).to_bytes()[..],
369 );
370 res[48..96].copy_from_slice(
371 &Fp::conditional_select(&self.y, &Fp::zero(), self.infinity).to_bytes()[..],
372 );
373 res[0] |= u8::conditional_select(&0u8, &(1u8 << 6), self.infinity);
374 res
375 }
376
377 pub fn from_uncompressed(bytes: &[u8; 96]) -> CtOption<Self> {
379 Self::from_uncompressed_unchecked(bytes)
380 .and_then(|p| CtOption::new(p, p.is_on_curve() & p.is_torsion_free()))
381 }
382
383 pub fn from_uncompressed_unchecked(bytes: &[u8; 96]) -> CtOption<Self> {
385 let compression_flag_set = Choice::from((bytes[0] >> 7) & 1);
386 let infinity_flag_set = Choice::from((bytes[0] >> 6) & 1);
387 let sort_flag_set = Choice::from((bytes[0] >> 5) & 1);
388 let x = {
389 let mut tmp = [0; 48];
390 tmp.copy_from_slice(&bytes[0..48]);
391 tmp[0] &= 0b0001_1111;
392 Fp::from_bytes(&tmp)
393 };
394 let y = Fp::from_bytes(<&[u8; 48]>::try_from(&bytes[48..96]).unwrap());
395
396 x.and_then(|x| {
397 y.and_then(|y| {
398 let p = G1Affine::conditional_select(
399 &G1Affine { x, y, infinity: infinity_flag_set },
400 &G1Affine::identity(),
401 infinity_flag_set,
402 );
403 CtOption::new(
404 p,
405 ((!infinity_flag_set) | (infinity_flag_set & x.is_zero() & y.is_zero())) &
406 (!compression_flag_set) &
407 (!sort_flag_set),
408 )
409 })
410 })
411 }
412
413 pub fn from_compressed(bytes: &[u8; 48]) -> Result<Self> {
415 Self::from_compressed_unchecked(bytes)
416 .into_option() .ok_or_else(|| Error::Parameter {
418 name: "compressed_bytes".into(),
419 reason: "invalid G1 point encoding".into(),
420 })
421 .and_then(|p| {
422 if !bool::from(p.is_torsion_free()) {
423 Err(Error::param("point", "not in correct subgroup"))
424 } else {
425 Ok(p)
426 }
427 })
428 }
429
430 pub(crate) fn from_compressed_unchecked(bytes: &[u8; 48]) -> CtOption<Self> {
432 let compression_flag_set = Choice::from((bytes[0] >> 7) & 1);
433 let infinity_flag_set = Choice::from((bytes[0] >> 6) & 1);
434 let sort_flag_set = Choice::from((bytes[0] >> 5) & 1);
435 let x = {
436 let mut tmp = *bytes;
437 tmp[0] &= 0b0001_1111;
438 Fp::from_bytes(&tmp)
439 };
440
441 x.and_then(|x| {
442 CtOption::new(
443 G1Affine::identity(),
444 infinity_flag_set & compression_flag_set & (!sort_flag_set) & x.is_zero(),
445 )
446 .or_else(|| {
447 ((x.square() * x) + B).sqrt().and_then(|y| {
448 let y = Fp::conditional_select(
449 &y,
450 &-y,
451 y.lexicographically_largest() ^ sort_flag_set,
452 );
453 CtOption::new(
454 G1Affine { x, y, infinity: infinity_flag_set },
455 (!infinity_flag_set) & compression_flag_set,
456 )
457 })
458 })
459 })
460 }
461}
462
463#[derive(Copy, Clone, Debug)]
465pub struct G1Projective {
466 pub(crate) x: Fp,
467 pub(crate) y: Fp,
468 pub(crate) z: Fp,
469}
470
471impl Default for G1Projective {
472 fn default() -> G1Projective {
473 G1Projective::identity()
474 }
475}
476
477#[cfg(feature = "zeroize")]
478impl zeroize::DefaultIsZeroes for G1Projective {}
479
480impl fmt::Display for G1Projective {
481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482 write!(f, "{:?}", self)
483 }
484}
485
486impl<'a> From<&'a G1Affine> for G1Projective {
487 fn from(p: &'a G1Affine) -> G1Projective {
488 G1Projective {
489 x: p.x,
490 y: p.y,
491 z: Fp::conditional_select(&Fp::one(), &Fp::zero(), p.infinity),
492 }
493 }
494}
495
496impl From<G1Affine> for G1Projective {
497 fn from(p: G1Affine) -> G1Projective {
498 G1Projective::from(&p)
499 }
500}
501
502impl ConstantTimeEq for G1Projective {
503 fn ct_eq(&self, other: &Self) -> Choice {
504 let x1 = self.x * other.z;
505 let x2 = other.x * self.z;
506 let y1 = self.y * other.z;
507 let y2 = other.y * self.z;
508 let self_is_zero = self.z.is_zero();
509 let other_is_zero = other.z.is_zero();
510
511 (self_is_zero & other_is_zero) | ((!self_is_zero) & (!other_is_zero) & x1.ct_eq(&x2) & y1.ct_eq(&y2))
512 }
513}
514
515impl ConditionallySelectable for G1Projective {
516 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
517 G1Projective {
518 x: Fp::conditional_select(&a.x, &b.x, choice),
519 y: Fp::conditional_select(&a.y, &b.y, choice),
520 z: Fp::conditional_select(&a.z, &b.z, choice),
521 }
522 }
523}
524
525impl Eq for G1Projective {}
526impl PartialEq for G1Projective {
527 #[inline]
528 fn eq(&self, other: &Self) -> bool {
529 bool::from(self.ct_eq(other))
530 }
531}
532
533impl<'a> Neg for &'a G1Projective {
534 type Output = G1Projective;
535
536 #[inline]
537 fn neg(self) -> G1Projective {
538 G1Projective {
539 x: self.x,
540 y: -self.y,
541 z: self.z,
542 }
543 }
544}
545
546impl Neg for G1Projective {
547 type Output = G1Projective;
548
549 #[inline]
550 fn neg(self) -> G1Projective {
551 -&self
552 }
553}
554
555impl<'a, 'b> Add<&'b G1Projective> for &'a G1Projective {
556 type Output = G1Projective;
557
558 #[inline]
559 fn add(self, rhs: &'b G1Projective) -> G1Projective {
560 self.add(rhs)
561 }
562}
563
564impl<'a, 'b> Sub<&'b G1Projective> for &'a G1Projective {
565 type Output = G1Projective;
566
567 #[inline]
568 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
569 self + &(-rhs)
570 }
571}
572
573impl<'a, 'b> Mul<&'b Scalar> for &'a G1Projective {
574 type Output = G1Projective;
575
576 fn mul(self, other: &'b Scalar) -> Self::Output {
577 self.multiply(&other.to_bytes())
578 }
579}
580
581impl<'a, 'b> Mul<&'b G1Projective> for &'a Scalar {
582 type Output = G1Projective;
583
584 #[inline]
585 fn mul(self, rhs: &'b G1Projective) -> Self::Output {
586 rhs * self
587 }
588}
589
590impl<'a, 'b> Mul<&'b Scalar> for &'a G1Affine {
591 type Output = G1Projective;
592
593 fn mul(self, other: &'b Scalar) -> Self::Output {
594 G1Projective::from(self).multiply(&other.to_bytes())
595 }
596}
597
598impl<'a, 'b> Mul<&'b G1Affine> for &'a Scalar {
599 type Output = G1Projective;
600
601 #[inline]
602 fn mul(self, rhs: &'b G1Affine) -> Self::Output {
603 rhs * self
604 }
605}
606
607impl<'b> Add<&'b G1Projective> for G1Projective {
609 type Output = G1Projective;
610 #[inline]
611 fn add(self, rhs: &'b G1Projective) -> G1Projective {
612 &self + rhs
613 }
614}
615impl<'a> Add<G1Projective> for &'a G1Projective {
616 type Output = G1Projective;
617 #[inline]
618 fn add(self, rhs: G1Projective) -> G1Projective {
619 self + &rhs
620 }
621}
622impl Add<G1Projective> for G1Projective {
623 type Output = G1Projective;
624 #[inline]
625 fn add(self, rhs: G1Projective) -> G1Projective {
626 &self + &rhs
627 }
628}
629impl<'b> Sub<&'b G1Projective> for G1Projective {
630 type Output = G1Projective;
631 #[inline]
632 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
633 &self - rhs
634 }
635}
636impl<'a> Sub<G1Projective> for &'a G1Projective {
637 type Output = G1Projective;
638 #[inline]
639 fn sub(self, rhs: G1Projective) -> G1Projective {
640 self - &rhs
641 }
642}
643impl Sub<G1Projective> for G1Projective {
644 type Output = G1Projective;
645 #[inline]
646 fn sub(self, rhs: G1Projective) -> G1Projective {
647 &self - &rhs
648 }
649}
650impl SubAssign<G1Projective> for G1Projective {
651 #[inline]
652 fn sub_assign(&mut self, rhs: G1Projective) {
653 *self = &*self - &rhs;
654 }
655}
656impl AddAssign<G1Projective> for G1Projective {
657 #[inline]
658 fn add_assign(&mut self, rhs: G1Projective) {
659 *self = &*self + &rhs;
660 }
661}
662impl<'b> SubAssign<&'b G1Projective> for G1Projective {
663 #[inline]
664 fn sub_assign(&mut self, rhs: &'b G1Projective) {
665 *self = &*self - rhs;
666 }
667}
668impl<'b> AddAssign<&'b G1Projective> for G1Projective {
669 #[inline]
670 fn add_assign(&mut self, rhs: &'b G1Projective) {
671 *self = &*self + rhs;
672 }
673}
674
675impl<'b> Mul<&'b Scalar> for G1Projective {
677 type Output = G1Projective;
678 #[inline]
679 fn mul(self, rhs: &'b Scalar) -> G1Projective {
680 &self * rhs
681 }
682}
683impl<'a> Mul<Scalar> for &'a G1Projective {
684 type Output = G1Projective;
685 #[inline]
686 fn mul(self, rhs: Scalar) -> G1Projective {
687 self * &rhs
688 }
689}
690impl Mul<Scalar> for G1Projective {
691 type Output = G1Projective;
692 #[inline]
693 fn mul(self, rhs: Scalar) -> G1Projective {
694 &self * &rhs
695 }
696}
697impl MulAssign<Scalar> for G1Projective {
698 #[inline]
699 fn mul_assign(&mut self, rhs: Scalar) {
700 *self = &*self * &rhs;
701 }
702}
703impl<'b> MulAssign<&'b Scalar> for G1Projective {
704 #[inline]
705 fn mul_assign(&mut self, rhs: &'b Scalar) {
706 *self = &*self * rhs;
707 }
708}
709
710impl<'b> Mul<&'b Scalar> for G1Affine {
712 type Output = G1Projective;
713 #[inline]
714 fn mul(self, rhs: &'b Scalar) -> G1Projective {
715 &self * rhs
716 }
717}
718impl<'a> Mul<Scalar> for &'a G1Affine {
719 type Output = G1Projective;
720 #[inline]
721 fn mul(self, rhs: Scalar) -> G1Projective {
722 self * &rhs
723 }
724}
725impl Mul<Scalar> for G1Affine {
726 type Output = G1Projective;
727 #[inline]
728 fn mul(self, rhs: Scalar) -> G1Projective {
729 &self * &rhs
730 }
731}
732
733impl<'b> Mul<&'b G1Affine> for Scalar {
735 type Output = G1Projective;
736 #[inline]
737 fn mul(self, rhs: &'b G1Affine) -> G1Projective {
738 &self * rhs
739 }
740}
741impl<'a> Mul<G1Affine> for &'a Scalar {
742 type Output = G1Projective;
743 #[inline]
744 fn mul(self, rhs: G1Affine) -> G1Projective {
745 self * &rhs
746 }
747}
748impl Mul<G1Affine> for Scalar {
749 type Output = G1Projective;
750 #[inline]
751 fn mul(self, rhs: G1Affine) -> G1Projective {
752 &self * &rhs
753 }
754}
755
756impl<'b> Mul<&'b G1Projective> for Scalar {
758 type Output = G1Projective;
759 #[inline]
760 fn mul(self, rhs: &'b G1Projective) -> G1Projective {
761 &self * rhs
762 }
763}
764impl<'a> Mul<G1Projective> for &'a Scalar {
765 type Output = G1Projective;
766 #[inline]
767 fn mul(self, rhs: G1Projective) -> G1Projective {
768 self * &rhs
769 }
770}
771impl Mul<G1Projective> for Scalar {
772 type Output = G1Projective;
773 #[inline]
774 fn mul(self, rhs: G1Projective) -> G1Projective {
775 &self * &rhs
776 }
777}
778
779#[inline(always)]
780fn mul_by_3b(a: Fp) -> Fp {
781 let a = a + a; let a = a + a; a + a + a }
785
786impl G1Projective {
787 pub fn identity() -> G1Projective {
789 G1Projective {
790 x: Fp::zero(),
791 y: Fp::one(),
792 z: Fp::zero(),
793 }
794 }
795
796 pub fn generator() -> G1Projective {
798 G1Projective {
799 x: G1Affine::generator().x,
800 y: G1Affine::generator().y,
801 z: Fp::one(),
802 }
803 }
804
805 pub fn random(mut rng: impl RngCore) -> Self {
807 loop {
808 let x = Fp::random(&mut rng);
809 let flip_sign = rng.next_u32() % 2 != 0;
810
811 let p = ((x.square() * x) + B).sqrt().map(|y| G1Affine {
812 x,
813 y: if flip_sign { -y } else { y },
814 infinity: 0.into(),
815 });
816
817 if p.is_some().into() {
818 let p_proj = G1Projective::from(p.unwrap());
819 let p_cleared = p_proj.clear_cofactor();
820 if !bool::from(p_cleared.is_identity()) {
821 return p_cleared;
822 }
823 }
824 }
825 }
826
827 #[cfg(feature = "alloc")]
839 pub fn msm_vartime(
840 points: &[G1Affine],
841 scalars: &[Scalar],
842 ) -> Result<Self> {
843 if points.len() != scalars.len() {
844 return Err(Error::Parameter {
845 name: "points/scalars".into(),
846 reason: "Input slices must have the same length".into(),
847 });
848 }
849 Ok(Self::pippenger(points, scalars, true))
850 }
851
852 #[cfg(feature = "alloc")]
860 pub fn msm(
861 points: &[G1Affine],
862 scalars: &[Scalar],
863 ) -> Result<Self> {
864 if points.len() != scalars.len() {
865 return Err(Error::Parameter {
866 name: "points/scalars".into(),
867 reason: "Input slices must have the same length".into(),
868 });
869 }
870 Ok(Self::pippenger(points, scalars, false))
871 }
872
873 #[cfg(feature = "alloc")]
875 fn pippenger(points: &[G1Affine], scalars: &[Scalar], is_vartime: bool) -> Self {
876 if points.is_empty() {
877 return Self::identity();
878 }
879
880 let num_entries = points.len();
881 let scalar_bits = 255; let c = if is_vartime {
886 if num_entries < 32 {
887 3
888 } else {
889 let log2 = (usize::BITS - num_entries.leading_zeros() - 1) as usize;
892 log2 + 2
893 }
894 } else {
895 4
898 };
899
900 let num_windows = (scalar_bits + c - 1) / c;
901 let num_buckets = 1 << c;
902 let mut global_acc = Self::identity();
903
904 for w in (0..num_windows).rev() {
906 let mut window_acc = Self::identity();
907 let mut buckets = vec![Self::identity(); num_buckets];
908
909 for i in 0..num_entries {
911 let scalar_bytes = scalars[i].to_bytes();
912
913 let mut k = 0;
915 for bit_idx in 0..c {
916 let total_bit_idx = w * c + bit_idx;
917 if total_bit_idx < scalar_bits {
918 let byte_idx = total_bit_idx / 8;
919 let inner_bit_idx = total_bit_idx % 8;
920 let byte = scalar_bytes[byte_idx];
921 let bit = (byte >> inner_bit_idx) & 1;
922 k |= (bit as usize) << bit_idx;
923 }
924 }
925
926 if is_vartime {
927 if k > 0 {
928 buckets[k - 1] = buckets[k - 1].add_mixed(&points[i]);
929 }
930 } else {
931 for b in 0..num_buckets {
936 let bucket_idx = b + 1;
937 let choice = k.ct_eq(&bucket_idx);
939
940 let res = buckets[b].add_mixed(&points[i]);
941 buckets[b] = G1Projective::conditional_select(&buckets[b], &res, choice);
942 }
943 }
944 }
945
946 let mut running_sum = Self::identity();
948 for i in (0..num_buckets).rev() {
949 running_sum = running_sum.add(&buckets[i]);
950 window_acc = window_acc.add(&running_sum);
951 }
952
953 global_acc = global_acc.add(&window_acc);
955
956 if w > 0 {
958 for _ in 0..c {
959 global_acc = global_acc.double();
960 }
961 }
962 }
963
964 global_acc
965 }
966
967 pub fn double(&self) -> G1Projective {
974 let t0 = self.y.square();
976 let z3 = t0 + t0;
977 let z3 = z3 + z3;
978 let z3 = z3 + z3;
979 let t1 = self.y * self.z;
980 let t2 = self.z.square();
981 let t2 = mul_by_3b(t2);
982 let x3 = t2 * z3;
983 let y3 = t0 + t2;
984 let z3 = t1 * z3;
985 let t1 = t2 + t2;
986 let t2 = t1 + t2;
987 let t0 = t0 - t2;
988 let y3 = t0 * y3;
989 let y3 = x3 + y3;
990 let t1 = self.x * self.y;
991 let x3 = t0 * t1;
992 let x3 = x3 + x3;
993
994 let tmp = G1Projective { x: x3, y: y3, z: z3 };
995 G1Projective::conditional_select(&tmp, &G1Projective::identity(), self.is_identity())
996 }
997
998 pub fn add(&self, rhs: &G1Projective) -> G1Projective {
1000 let t0 = self.x * rhs.x;
1002 let t1 = self.y * rhs.y;
1003 let t2 = self.z * rhs.z;
1004 let t3 = self.x + self.y;
1005 let t4 = rhs.x + rhs.y;
1006 let t3 = t3 * t4;
1007 let t4 = t0 + t1;
1008 let t3 = t3 - t4;
1009 let t4 = self.y + self.z;
1010 let x3 = rhs.y + rhs.z;
1011 let t4 = t4 * x3;
1012 let x3 = t1 + t2;
1013 let t4 = t4 - x3;
1014 let x3 = self.x + self.z;
1015 let y3 = rhs.x + rhs.z;
1016 let x3 = x3 * y3;
1017 let y3 = t0 + t2;
1018 let y3 = x3 - y3;
1019 let x3 = t0 + t0;
1020 let t0 = x3 + t0;
1021 let t2 = mul_by_3b(t2);
1022 let z3 = t1 + t2;
1023 let t1 = t1 - t2;
1024 let y3 = mul_by_3b(y3);
1025 let x3 = t4 * y3;
1026 let t2 = t3 * t1;
1027 let x3 = t2 - x3;
1028 let y3 = y3 * t0;
1029 let t1 = t1 * z3;
1030 let y3 = t1 + y3;
1031 let t0 = t0 * t3;
1032 let z3 = z3 * t4;
1033 let z3 = z3 + t0;
1034
1035 G1Projective { x: x3, y: y3, z: z3 }
1036 }
1037
1038 pub fn add_mixed(&self, rhs: &G1Affine) -> G1Projective {
1040 let t0 = self.x * rhs.x;
1042 let t1 = self.y * rhs.y;
1043 let t3 = rhs.x + rhs.y;
1044 let t4 = self.x + self.y;
1045 let t3 = t3 * t4;
1046 let t4 = t0 + t1;
1047 let t3 = t3 - t4;
1048 let t4 = rhs.y * self.z;
1049 let t4 = t4 + self.y;
1050 let y3 = rhs.x * self.z;
1051 let y3 = y3 + self.x;
1052 let x3 = t0 + t0;
1053 let t0 = x3 + t0;
1054 let t2 = mul_by_3b(self.z);
1055 let z3 = t1 + t2;
1056 let t1 = t1 - t2;
1057 let y3 = mul_by_3b(y3);
1058 let x3 = t4 * y3;
1059 let t2 = t3 * t1;
1060 let x3 = t2 - x3;
1061 let y3 = y3 * t0;
1062 let t1 = t1 * z3;
1063 let y3 = t1 + y3;
1064 let t0 = t0 * t3;
1065 let z3 = z3 * t4;
1066 let z3 = z3 + t0;
1067
1068 let tmp = G1Projective { x: x3, y: y3, z: z3 };
1069 G1Projective::conditional_select(&tmp, self, rhs.is_identity())
1070 }
1071
1072 fn multiply(&self, by: &[u8; 32]) -> G1Projective {
1073 let mut acc = G1Projective::identity();
1074 for &byte in by.iter().rev() {
1075 for i in (0..8).rev() {
1076 acc = acc.double();
1077 let bit = Choice::from((byte >> i) & 1u8);
1078 acc = G1Projective::conditional_select(&acc, &(acc + self), bit);
1079 }
1080 }
1081 acc
1082 }
1083
1084 fn mul_by_x(&self) -> G1Projective {
1085 let mut xself = G1Projective::identity();
1086 let mut x = super::BLS_X >> 1;
1087 let mut tmp = *self;
1088 while x != 0 {
1089 tmp = tmp.double();
1090 if x % 2 == 1 {
1091 xself += tmp;
1092 }
1093 x >>= 1;
1094 }
1095 if super::BLS_X_IS_NEGATIVE {
1096 xself = -xself;
1097 }
1098 xself
1099 }
1100
1101 pub fn clear_cofactor(&self) -> G1Projective {
1103 self - &self.mul_by_x()
1104 }
1105
1106 pub fn batch_normalize(p: &[Self], q: &mut [G1Affine]) {
1108 assert_eq!(p.len(), q.len());
1109
1110 let mut acc = Fp::one();
1111 for (p, q) in p.iter().zip(q.iter_mut()) {
1112 q.x = acc;
1113 acc = Fp::conditional_select(&(acc * p.z), &acc, p.is_identity());
1114 }
1115
1116 acc = acc.invert().unwrap();
1117
1118 for (p, q) in p.iter().rev().zip(q.iter_mut().rev()) {
1119 let skip = p.is_identity();
1120 let tmp = q.x * acc;
1121 acc = Fp::conditional_select(&(acc * p.z), &acc, skip);
1122 q.x = p.x * tmp;
1123 q.y = p.y * tmp;
1124 q.infinity = Choice::from(0u8);
1125 *q = G1Affine::conditional_select(q, &G1Affine::identity(), skip);
1126 }
1127 }
1128
1129 #[inline]
1131 pub fn is_identity(&self) -> Choice {
1132 self.z.is_zero()
1133 }
1134
1135 pub fn is_on_curve(&self) -> Choice {
1137 (self.y.square() * self.z).ct_eq(&(self.x.square() * self.x + self.z.square() * self.z * B))
1138 | self.z.is_zero()
1139 }
1140
1141 pub fn from_bytes(bytes: &[u8; 48]) -> CtOption<Self> {
1143 G1Affine::from_compressed_unchecked(bytes).map(G1Projective::from)
1144 }
1145
1146 pub fn from_bytes_unchecked(bytes: &[u8; 48]) -> CtOption<Self> {
1148 G1Affine::from_compressed_unchecked(bytes).map(G1Projective::from)
1149 }
1150
1151 pub fn from_bytes_validated(bytes: &[u8]) -> Result<Self> {
1153 validate::length("G1Projective::from_bytes", bytes.len(), 48)?;
1155
1156 let mut array = [0u8; 48];
1157 array.copy_from_slice(bytes);
1158
1159 Self::from_bytes_unchecked(&array)
1160 .into_option() .ok_or_else(|| Error::Processing {
1162 operation: "G1 deserialization",
1163 details: "invalid point encoding",
1164 })
1165 .and_then(|p| {
1166 validate::parameter(
1167 bool::from(p.is_on_curve()),
1168 "point",
1169 "not on curve"
1170 )?;
1171 Ok(p)
1172 })
1173 }
1174
1175 pub fn to_bytes(&self) -> [u8; 48] {
1177 G1Affine::from(self).to_compressed()
1178 }
1179}
1180
1181
1182#[cfg(test)]
1183mod tests {
1184 use super::*;
1185
1186 #[test]
1187 fn test_g1_msm() {
1188 let g = G1Affine::generator();
1189 let s1 = Scalar::from(2u64);
1190 let s2 = Scalar::from(3u64);
1191 let s3 = Scalar::from(4u64);
1192
1193 let p1 = G1Affine::from(G1Projective::from(g) * s1); let p2 = G1Affine::from(G1Projective::from(g) * s2); let p3 = G1Affine::from(G1Projective::from(g) * s3); let scalars = vec![s1, s2, s3];
1198 let points = vec![p1, p2, p3];
1199
1200 let expected = G1Projective::from(g) * Scalar::from(29u64);
1202
1203 let naive_result = (p1 * s1) + (p2 * s2) + (p3 * s3);
1205 assert_eq!(G1Affine::from(naive_result), G1Affine::from(expected));
1206
1207 let msm_result_vartime = G1Projective::msm_vartime(&points, &scalars).unwrap();
1209 assert_eq!(G1Affine::from(msm_result_vartime), G1Affine::from(expected));
1210
1211 let msm_result = G1Projective::msm(&points, &scalars).unwrap();
1213 assert_eq!(G1Affine::from(msm_result), G1Affine::from(expected));
1214
1215 let empty_res = G1Projective::msm(&[], &[]).unwrap();
1217 assert_eq!(empty_res, G1Projective::identity());
1218 }
1219}