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;
13#[cfg(feature = "alloc")]
14use alloc::vec::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 {
400 x,
401 y,
402 infinity: infinity_flag_set,
403 },
404 &G1Affine::identity(),
405 infinity_flag_set,
406 );
407 CtOption::new(
408 p,
409 ((!infinity_flag_set) | (infinity_flag_set & x.is_zero() & y.is_zero()))
410 & (!compression_flag_set)
411 & (!sort_flag_set),
412 )
413 })
414 })
415 }
416
417 pub fn from_compressed(bytes: &[u8; 48]) -> Result<Self> {
419 Self::from_compressed_unchecked(bytes)
420 .into_option() .ok_or_else(|| Error::Parameter {
422 name: "compressed_bytes".into(),
423 reason: "invalid G1 point encoding".into(),
424 })
425 .and_then(|p| {
426 if !bool::from(p.is_torsion_free()) {
427 Err(Error::param("point", "not in correct subgroup"))
428 } else {
429 Ok(p)
430 }
431 })
432 }
433
434 pub(crate) fn from_compressed_unchecked(bytes: &[u8; 48]) -> CtOption<Self> {
436 let compression_flag_set = Choice::from((bytes[0] >> 7) & 1);
437 let infinity_flag_set = Choice::from((bytes[0] >> 6) & 1);
438 let sort_flag_set = Choice::from((bytes[0] >> 5) & 1);
439 let x = {
440 let mut tmp = *bytes;
441 tmp[0] &= 0b0001_1111;
442 Fp::from_bytes(&tmp)
443 };
444
445 x.and_then(|x| {
446 CtOption::new(
447 G1Affine::identity(),
448 infinity_flag_set & compression_flag_set & (!sort_flag_set) & x.is_zero(),
449 )
450 .or_else(|| {
451 ((x.square() * x) + B).sqrt().and_then(|y| {
452 let y = Fp::conditional_select(
453 &y,
454 &-y,
455 y.lexicographically_largest() ^ sort_flag_set,
456 );
457 CtOption::new(
458 G1Affine {
459 x,
460 y,
461 infinity: infinity_flag_set,
462 },
463 (!infinity_flag_set) & compression_flag_set,
464 )
465 })
466 })
467 })
468 }
469}
470
471#[derive(Copy, Clone, Debug)]
473pub struct G1Projective {
474 pub(crate) x: Fp,
475 pub(crate) y: Fp,
476 pub(crate) z: Fp,
477}
478
479impl Default for G1Projective {
480 fn default() -> G1Projective {
481 G1Projective::identity()
482 }
483}
484
485#[cfg(feature = "zeroize")]
486impl zeroize::DefaultIsZeroes for G1Projective {}
487
488impl fmt::Display for G1Projective {
489 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
490 write!(f, "{:?}", self)
491 }
492}
493
494impl<'a> From<&'a G1Affine> for G1Projective {
495 fn from(p: &'a G1Affine) -> G1Projective {
496 G1Projective {
497 x: p.x,
498 y: p.y,
499 z: Fp::conditional_select(&Fp::one(), &Fp::zero(), p.infinity),
500 }
501 }
502}
503
504impl From<G1Affine> for G1Projective {
505 fn from(p: G1Affine) -> G1Projective {
506 G1Projective::from(&p)
507 }
508}
509
510impl ConstantTimeEq for G1Projective {
511 fn ct_eq(&self, other: &Self) -> Choice {
512 let x1 = self.x * other.z;
513 let x2 = other.x * self.z;
514 let y1 = self.y * other.z;
515 let y2 = other.y * self.z;
516 let self_is_zero = self.z.is_zero();
517 let other_is_zero = other.z.is_zero();
518
519 (self_is_zero & other_is_zero)
520 | ((!self_is_zero) & (!other_is_zero) & x1.ct_eq(&x2) & y1.ct_eq(&y2))
521 }
522}
523
524impl ConditionallySelectable for G1Projective {
525 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
526 G1Projective {
527 x: Fp::conditional_select(&a.x, &b.x, choice),
528 y: Fp::conditional_select(&a.y, &b.y, choice),
529 z: Fp::conditional_select(&a.z, &b.z, choice),
530 }
531 }
532}
533
534impl Eq for G1Projective {}
535impl PartialEq for G1Projective {
536 #[inline]
537 fn eq(&self, other: &Self) -> bool {
538 bool::from(self.ct_eq(other))
539 }
540}
541
542impl<'a> Neg for &'a G1Projective {
543 type Output = G1Projective;
544
545 #[inline]
546 fn neg(self) -> G1Projective {
547 G1Projective {
548 x: self.x,
549 y: -self.y,
550 z: self.z,
551 }
552 }
553}
554
555impl Neg for G1Projective {
556 type Output = G1Projective;
557
558 #[inline]
559 fn neg(self) -> G1Projective {
560 -&self
561 }
562}
563
564impl<'a, 'b> Add<&'b G1Projective> for &'a G1Projective {
565 type Output = G1Projective;
566
567 #[inline]
568 fn add(self, rhs: &'b G1Projective) -> G1Projective {
569 self.add(rhs)
570 }
571}
572
573impl<'a, 'b> Sub<&'b G1Projective> for &'a G1Projective {
574 type Output = G1Projective;
575
576 #[inline]
577 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
578 self + &(-rhs)
579 }
580}
581
582impl<'a, 'b> Mul<&'b Scalar> for &'a G1Projective {
583 type Output = G1Projective;
584
585 fn mul(self, other: &'b Scalar) -> Self::Output {
586 self.multiply(&other.to_bytes())
587 }
588}
589
590impl<'a, 'b> Mul<&'b G1Projective> for &'a Scalar {
591 type Output = G1Projective;
592
593 #[inline]
594 fn mul(self, rhs: &'b G1Projective) -> Self::Output {
595 rhs * self
596 }
597}
598
599impl<'a, 'b> Mul<&'b Scalar> for &'a G1Affine {
600 type Output = G1Projective;
601
602 fn mul(self, other: &'b Scalar) -> Self::Output {
603 G1Projective::from(self).multiply(&other.to_bytes())
604 }
605}
606
607impl<'a, 'b> Mul<&'b G1Affine> for &'a Scalar {
608 type Output = G1Projective;
609
610 #[inline]
611 fn mul(self, rhs: &'b G1Affine) -> Self::Output {
612 rhs * self
613 }
614}
615
616impl<'b> Add<&'b G1Projective> for G1Projective {
618 type Output = G1Projective;
619 #[inline]
620 fn add(self, rhs: &'b G1Projective) -> G1Projective {
621 &self + rhs
622 }
623}
624impl<'a> Add<G1Projective> for &'a G1Projective {
625 type Output = G1Projective;
626 #[inline]
627 fn add(self, rhs: G1Projective) -> G1Projective {
628 self + &rhs
629 }
630}
631impl Add<G1Projective> for G1Projective {
632 type Output = G1Projective;
633 #[inline]
634 fn add(self, rhs: G1Projective) -> G1Projective {
635 &self + &rhs
636 }
637}
638impl<'b> Sub<&'b G1Projective> for G1Projective {
639 type Output = G1Projective;
640 #[inline]
641 fn sub(self, rhs: &'b G1Projective) -> G1Projective {
642 &self - rhs
643 }
644}
645impl<'a> Sub<G1Projective> for &'a G1Projective {
646 type Output = G1Projective;
647 #[inline]
648 fn sub(self, rhs: G1Projective) -> G1Projective {
649 self - &rhs
650 }
651}
652impl Sub<G1Projective> for G1Projective {
653 type Output = G1Projective;
654 #[inline]
655 fn sub(self, rhs: G1Projective) -> G1Projective {
656 &self - &rhs
657 }
658}
659impl SubAssign<G1Projective> for G1Projective {
660 #[inline]
661 fn sub_assign(&mut self, rhs: G1Projective) {
662 *self = &*self - &rhs;
663 }
664}
665impl AddAssign<G1Projective> for G1Projective {
666 #[inline]
667 fn add_assign(&mut self, rhs: G1Projective) {
668 *self = &*self + &rhs;
669 }
670}
671impl<'b> SubAssign<&'b G1Projective> for G1Projective {
672 #[inline]
673 fn sub_assign(&mut self, rhs: &'b G1Projective) {
674 *self = &*self - rhs;
675 }
676}
677impl<'b> AddAssign<&'b G1Projective> for G1Projective {
678 #[inline]
679 fn add_assign(&mut self, rhs: &'b G1Projective) {
680 *self = &*self + rhs;
681 }
682}
683
684impl<'b> Mul<&'b Scalar> for G1Projective {
686 type Output = G1Projective;
687 #[inline]
688 fn mul(self, rhs: &'b Scalar) -> G1Projective {
689 &self * rhs
690 }
691}
692impl<'a> Mul<Scalar> for &'a G1Projective {
693 type Output = G1Projective;
694 #[inline]
695 fn mul(self, rhs: Scalar) -> G1Projective {
696 self * &rhs
697 }
698}
699impl Mul<Scalar> for G1Projective {
700 type Output = G1Projective;
701 #[inline]
702 fn mul(self, rhs: Scalar) -> G1Projective {
703 &self * &rhs
704 }
705}
706impl MulAssign<Scalar> for G1Projective {
707 #[inline]
708 fn mul_assign(&mut self, rhs: Scalar) {
709 *self = &*self * &rhs;
710 }
711}
712impl<'b> MulAssign<&'b Scalar> for G1Projective {
713 #[inline]
714 fn mul_assign(&mut self, rhs: &'b Scalar) {
715 *self = &*self * rhs;
716 }
717}
718
719impl<'b> Mul<&'b Scalar> for G1Affine {
721 type Output = G1Projective;
722 #[inline]
723 fn mul(self, rhs: &'b Scalar) -> G1Projective {
724 &self * rhs
725 }
726}
727impl<'a> Mul<Scalar> for &'a G1Affine {
728 type Output = G1Projective;
729 #[inline]
730 fn mul(self, rhs: Scalar) -> G1Projective {
731 self * &rhs
732 }
733}
734impl Mul<Scalar> for G1Affine {
735 type Output = G1Projective;
736 #[inline]
737 fn mul(self, rhs: Scalar) -> G1Projective {
738 &self * &rhs
739 }
740}
741
742impl<'b> Mul<&'b G1Affine> for Scalar {
744 type Output = G1Projective;
745 #[inline]
746 fn mul(self, rhs: &'b G1Affine) -> G1Projective {
747 &self * rhs
748 }
749}
750impl<'a> Mul<G1Affine> for &'a Scalar {
751 type Output = G1Projective;
752 #[inline]
753 fn mul(self, rhs: G1Affine) -> G1Projective {
754 self * &rhs
755 }
756}
757impl Mul<G1Affine> for Scalar {
758 type Output = G1Projective;
759 #[inline]
760 fn mul(self, rhs: G1Affine) -> G1Projective {
761 &self * &rhs
762 }
763}
764
765impl<'b> Mul<&'b G1Projective> for Scalar {
767 type Output = G1Projective;
768 #[inline]
769 fn mul(self, rhs: &'b G1Projective) -> G1Projective {
770 &self * rhs
771 }
772}
773impl<'a> Mul<G1Projective> for &'a Scalar {
774 type Output = G1Projective;
775 #[inline]
776 fn mul(self, rhs: G1Projective) -> G1Projective {
777 self * &rhs
778 }
779}
780impl Mul<G1Projective> for Scalar {
781 type Output = G1Projective;
782 #[inline]
783 fn mul(self, rhs: G1Projective) -> G1Projective {
784 &self * &rhs
785 }
786}
787
788#[inline(always)]
789fn mul_by_3b(a: Fp) -> Fp {
790 let a = a + a; let a = a + a; a + a + a }
794
795impl G1Projective {
796 pub fn identity() -> G1Projective {
798 G1Projective {
799 x: Fp::zero(),
800 y: Fp::one(),
801 z: Fp::zero(),
802 }
803 }
804
805 pub fn generator() -> G1Projective {
807 G1Projective {
808 x: G1Affine::generator().x,
809 y: G1Affine::generator().y,
810 z: Fp::one(),
811 }
812 }
813
814 pub fn random(mut rng: impl RngCore) -> Self {
816 loop {
817 let x = Fp::random(&mut rng);
818 let flip_sign = rng.next_u32() % 2 != 0;
819
820 let p = ((x.square() * x) + B).sqrt().map(|y| G1Affine {
821 x,
822 y: if flip_sign { -y } else { y },
823 infinity: 0.into(),
824 });
825
826 if p.is_some().into() {
827 let p_proj = G1Projective::from(p.unwrap());
828 let p_cleared = p_proj.clear_cofactor();
829 if !bool::from(p_cleared.is_identity()) {
830 return p_cleared;
831 }
832 }
833 }
834 }
835
836 #[cfg(feature = "alloc")]
848 pub fn msm_vartime(points: &[G1Affine], scalars: &[Scalar]) -> Result<Self> {
849 if points.len() != scalars.len() {
850 return Err(Error::Parameter {
851 name: "points/scalars".into(),
852 reason: "Input slices must have the same length".into(),
853 });
854 }
855 Ok(Self::pippenger(points, scalars, true))
856 }
857
858 #[cfg(feature = "alloc")]
866 pub fn msm(points: &[G1Affine], scalars: &[Scalar]) -> Result<Self> {
867 if points.len() != scalars.len() {
868 return Err(Error::Parameter {
869 name: "points/scalars".into(),
870 reason: "Input slices must have the same length".into(),
871 });
872 }
873 Ok(Self::pippenger(points, scalars, false))
874 }
875
876 #[cfg(feature = "alloc")]
878 fn pippenger(points: &[G1Affine], scalars: &[Scalar], is_vartime: bool) -> Self {
879 if points.is_empty() {
880 return Self::identity();
881 }
882
883 let num_entries = points.len();
884 let scalar_bits = 255; let c = if is_vartime {
889 if num_entries < 32 {
890 3
891 } else {
892 let log2 = (usize::BITS - num_entries.leading_zeros() - 1) as usize;
895 log2 + 2
896 }
897 } else {
898 4
901 };
902
903 let num_windows = (scalar_bits + c - 1) / c;
904 let num_buckets = 1 << c;
905 let mut global_acc = Self::identity();
906
907 for w in (0..num_windows).rev() {
909 let mut window_acc = Self::identity();
910 let mut buckets = vec![Self::identity(); num_buckets];
911
912 for i in 0..num_entries {
914 let scalar_bytes = scalars[i].to_bytes();
915
916 let mut k = 0;
918 for bit_idx in 0..c {
919 let total_bit_idx = w * c + bit_idx;
920 if total_bit_idx < scalar_bits {
921 let byte_idx = total_bit_idx / 8;
922 let inner_bit_idx = total_bit_idx % 8;
923 let byte = scalar_bytes[byte_idx];
924 let bit = (byte >> inner_bit_idx) & 1;
925 k |= (bit as usize) << bit_idx;
926 }
927 }
928
929 if is_vartime {
930 if k > 0 {
931 buckets[k - 1] = buckets[k - 1].add_mixed(&points[i]);
932 }
933 } else {
934 for b in 0..num_buckets {
939 let bucket_idx = b + 1;
940 let choice = k.ct_eq(&bucket_idx);
942
943 let res = buckets[b].add_mixed(&points[i]);
944 buckets[b] = G1Projective::conditional_select(&buckets[b], &res, choice);
945 }
946 }
947 }
948
949 let mut running_sum = Self::identity();
951 for i in (0..num_buckets).rev() {
952 running_sum = running_sum.add(&buckets[i]);
953 window_acc = window_acc.add(&running_sum);
954 }
955
956 global_acc = global_acc.add(&window_acc);
958
959 if w > 0 {
961 for _ in 0..c {
962 global_acc = global_acc.double();
963 }
964 }
965 }
966
967 global_acc
968 }
969
970 pub fn double(&self) -> G1Projective {
976 let t0 = self.y.square();
978 let z3 = t0 + t0;
979 let z3 = z3 + z3;
980 let z3 = z3 + z3;
981 let t1 = self.y * self.z;
982 let t2 = self.z.square();
983 let t2 = mul_by_3b(t2);
984 let x3 = t2 * z3;
985 let y3 = t0 + t2;
986 let z3 = t1 * z3;
987 let t1 = t2 + t2;
988 let t2 = t1 + t2;
989 let t0 = t0 - t2;
990 let y3 = t0 * y3;
991 let y3 = x3 + y3;
992 let t1 = self.x * self.y;
993 let x3 = t0 * t1;
994 let x3 = x3 + x3;
995
996 let tmp = G1Projective {
997 x: x3,
998 y: y3,
999 z: z3,
1000 };
1001 G1Projective::conditional_select(&tmp, &G1Projective::identity(), self.is_identity())
1002 }
1003
1004 pub fn add(&self, rhs: &G1Projective) -> G1Projective {
1006 let t0 = self.x * rhs.x;
1008 let t1 = self.y * rhs.y;
1009 let t2 = self.z * rhs.z;
1010 let t3 = self.x + self.y;
1011 let t4 = rhs.x + rhs.y;
1012 let t3 = t3 * t4;
1013 let t4 = t0 + t1;
1014 let t3 = t3 - t4;
1015 let t4 = self.y + self.z;
1016 let x3 = rhs.y + rhs.z;
1017 let t4 = t4 * x3;
1018 let x3 = t1 + t2;
1019 let t4 = t4 - x3;
1020 let x3 = self.x + self.z;
1021 let y3 = rhs.x + rhs.z;
1022 let x3 = x3 * y3;
1023 let y3 = t0 + t2;
1024 let y3 = x3 - y3;
1025 let x3 = t0 + t0;
1026 let t0 = x3 + t0;
1027 let t2 = mul_by_3b(t2);
1028 let z3 = t1 + t2;
1029 let t1 = t1 - t2;
1030 let y3 = mul_by_3b(y3);
1031 let x3 = t4 * y3;
1032 let t2 = t3 * t1;
1033 let x3 = t2 - x3;
1034 let y3 = y3 * t0;
1035 let t1 = t1 * z3;
1036 let y3 = t1 + y3;
1037 let t0 = t0 * t3;
1038 let z3 = z3 * t4;
1039 let z3 = z3 + t0;
1040
1041 G1Projective {
1042 x: x3,
1043 y: y3,
1044 z: z3,
1045 }
1046 }
1047
1048 pub fn add_mixed(&self, rhs: &G1Affine) -> G1Projective {
1050 let t0 = self.x * rhs.x;
1052 let t1 = self.y * rhs.y;
1053 let t3 = rhs.x + rhs.y;
1054 let t4 = self.x + self.y;
1055 let t3 = t3 * t4;
1056 let t4 = t0 + t1;
1057 let t3 = t3 - t4;
1058 let t4 = rhs.y * self.z;
1059 let t4 = t4 + self.y;
1060 let y3 = rhs.x * self.z;
1061 let y3 = y3 + self.x;
1062 let x3 = t0 + t0;
1063 let t0 = x3 + t0;
1064 let t2 = mul_by_3b(self.z);
1065 let z3 = t1 + t2;
1066 let t1 = t1 - t2;
1067 let y3 = mul_by_3b(y3);
1068 let x3 = t4 * y3;
1069 let t2 = t3 * t1;
1070 let x3 = t2 - x3;
1071 let y3 = y3 * t0;
1072 let t1 = t1 * z3;
1073 let y3 = t1 + y3;
1074 let t0 = t0 * t3;
1075 let z3 = z3 * t4;
1076 let z3 = z3 + t0;
1077
1078 let tmp = G1Projective {
1079 x: x3,
1080 y: y3,
1081 z: z3,
1082 };
1083 G1Projective::conditional_select(&tmp, self, rhs.is_identity())
1084 }
1085
1086 fn multiply(&self, by: &[u8; 32]) -> G1Projective {
1087 let mut acc = G1Projective::identity();
1088 for &byte in by.iter().rev() {
1089 for i in (0..8).rev() {
1090 acc = acc.double();
1091 let bit = Choice::from((byte >> i) & 1u8);
1092 acc = G1Projective::conditional_select(&acc, &(acc + self), bit);
1093 }
1094 }
1095 acc
1096 }
1097
1098 fn mul_by_x(&self) -> G1Projective {
1099 let mut xself = G1Projective::identity();
1100 let mut x = super::BLS_X >> 1;
1101 let mut tmp = *self;
1102 while x != 0 {
1103 tmp = tmp.double();
1104 if x % 2 == 1 {
1105 xself += tmp;
1106 }
1107 x >>= 1;
1108 }
1109 if super::BLS_X_IS_NEGATIVE {
1110 xself = -xself;
1111 }
1112 xself
1113 }
1114
1115 pub fn clear_cofactor(&self) -> G1Projective {
1117 self - &self.mul_by_x()
1118 }
1119
1120 pub fn batch_normalize(p: &[Self], q: &mut [G1Affine]) {
1122 assert_eq!(p.len(), q.len());
1123
1124 let mut acc = Fp::one();
1125 for (p, q) in p.iter().zip(q.iter_mut()) {
1126 q.x = acc;
1127 acc = Fp::conditional_select(&(acc * p.z), &acc, p.is_identity());
1128 }
1129
1130 acc = acc.invert().unwrap();
1131
1132 for (p, q) in p.iter().rev().zip(q.iter_mut().rev()) {
1133 let skip = p.is_identity();
1134 let tmp = q.x * acc;
1135 acc = Fp::conditional_select(&(acc * p.z), &acc, skip);
1136 q.x = p.x * tmp;
1137 q.y = p.y * tmp;
1138 q.infinity = Choice::from(0u8);
1139 *q = G1Affine::conditional_select(q, &G1Affine::identity(), skip);
1140 }
1141 }
1142
1143 #[inline]
1145 pub fn is_identity(&self) -> Choice {
1146 self.z.is_zero()
1147 }
1148
1149 pub fn is_on_curve(&self) -> Choice {
1151 (self.y.square() * self.z).ct_eq(&(self.x.square() * self.x + self.z.square() * self.z * B))
1152 | self.z.is_zero()
1153 }
1154
1155 pub fn from_bytes(bytes: &[u8; 48]) -> CtOption<Self> {
1157 G1Affine::from_compressed_unchecked(bytes).map(G1Projective::from)
1158 }
1159
1160 pub fn from_bytes_unchecked(bytes: &[u8; 48]) -> CtOption<Self> {
1162 G1Affine::from_compressed_unchecked(bytes).map(G1Projective::from)
1163 }
1164
1165 pub fn from_bytes_validated(bytes: &[u8]) -> Result<Self> {
1167 validate::length("G1Projective::from_bytes", bytes.len(), 48)?;
1169
1170 let mut array = [0u8; 48];
1171 array.copy_from_slice(bytes);
1172
1173 Self::from_bytes_unchecked(&array)
1174 .into_option() .ok_or_else(|| Error::Processing {
1176 operation: "G1 deserialization",
1177 details: "invalid point encoding",
1178 })
1179 .and_then(|p| {
1180 validate::parameter(bool::from(p.is_on_curve()), "point", "not on curve")?;
1181 Ok(p)
1182 })
1183 }
1184
1185 pub fn to_bytes(&self) -> [u8; 48] {
1187 G1Affine::from(self).to_compressed()
1188 }
1189}
1190
1191#[cfg(test)]
1192mod tests {
1193 use super::*;
1194
1195 #[test]
1196 fn test_g1_msm() {
1197 let g = G1Affine::generator();
1198 let s1 = Scalar::from(2u64);
1199 let s2 = Scalar::from(3u64);
1200 let s3 = Scalar::from(4u64);
1201
1202 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];
1207 let points = vec![p1, p2, p3];
1208
1209 let expected = G1Projective::from(g) * Scalar::from(29u64);
1211
1212 let naive_result = (p1 * s1) + (p2 * s2) + (p3 * s3);
1214 assert_eq!(G1Affine::from(naive_result), G1Affine::from(expected));
1215
1216 let msm_result_vartime = G1Projective::msm_vartime(&points, &scalars).unwrap();
1218 assert_eq!(G1Affine::from(msm_result_vartime), G1Affine::from(expected));
1219
1220 let msm_result = G1Projective::msm(&points, &scalars).unwrap();
1222 assert_eq!(G1Affine::from(msm_result), G1Affine::from(expected));
1223
1224 let empty_res = G1Projective::msm(&[], &[]).unwrap();
1226 assert_eq!(empty_res, G1Projective::identity());
1227 }
1228}