halo2curves/derive/
curve.rs

1#[macro_export]
2macro_rules! endo {
3    ($name:ident, $field:ident, $params:expr) => {
4        impl CurveEndo for $name {
5            fn decompose_scalar(k: &$field) -> (u128, bool, u128, bool) {
6                let to_limbs = |e: &$field| {
7                    let repr = e.to_repr();
8                    let repr = repr.as_ref();
9                    let tmp0 = u64::from_le_bytes(repr[0..8].try_into().unwrap());
10                    let tmp1 = u64::from_le_bytes(repr[8..16].try_into().unwrap());
11                    let tmp2 = u64::from_le_bytes(repr[16..24].try_into().unwrap());
12                    let tmp3 = u64::from_le_bytes(repr[24..32].try_into().unwrap());
13                    [tmp0, tmp1, tmp2, tmp3]
14                };
15
16                let get_lower_128 = |e: &$field| {
17                    let e = to_limbs(e);
18                    u128::from(e[0]) | (u128::from(e[1]) << 64)
19                };
20
21                let is_neg = |e: &$field| {
22                    let e = to_limbs(e);
23                    let (_, borrow) = sbb(0xffffffffffffffff, e[0], 0);
24                    let (_, borrow) = sbb(0xffffffffffffffff, e[1], borrow);
25                    let (_, borrow) = sbb(0xffffffffffffffff, e[2], borrow);
26                    let (_, borrow) = sbb(0x00, e[3], borrow);
27                    borrow & 1 != 0
28                };
29
30                let input = to_limbs(&k);
31                let c1 = mul_512($params.gamma2, input);
32                let c2 = mul_512($params.gamma1, input);
33                let c1 = [c1[4], c1[5], c1[6], c1[7]];
34                let c2 = [c2[4], c2[5], c2[6], c2[7]];
35                let q1 = mul_512(c1, $params.b1);
36                let q2 = mul_512(c2, $params.b2);
37                let q1 = $field::from_raw([q1[0], q1[1], q1[2], q1[3]]);
38                let q2 = $field::from_raw([q2[0], q2[1], q2[2], q2[3]]);
39                let k2 = q2 - q1;
40                let k1 = k + k2 * $field::ZETA;
41                let k1_neg = is_neg(&k1);
42                let k2_neg = is_neg(&k2);
43                let k1 = if k1_neg { -k1 } else { k1 };
44                let k2 = if k2_neg { -k2 } else { k2 };
45
46                (get_lower_128(&k1), k1_neg, get_lower_128(&k2), k2_neg)
47            }
48        }
49    };
50}
51
52#[macro_export]
53macro_rules! new_curve_impl {
54    (($($privacy:tt)*),
55    $name:ident,
56    $name_affine:ident,
57    $base:ident,
58    $scalar:ident,
59    $generator:expr,
60    $constant_a:expr,
61    $constant_b:expr,
62    $curve_id:literal,
63    $hash_to_curve:expr,
64    $flag_config:expr,
65    standard_sign
66    ) => {
67
68        paste::paste! {
69            impl $crate::serde::Compressed<$name_affine> for [<$name:upper Compressed >] {
70                const CONFIG: $crate::serde::CompressedFlagConfig = $flag_config;
71                fn sign(c: &$name_affine) -> subtle::Choice {
72                    Choice::from(c.y.to_repr()[0] as u8 & 1) & !c.is_identity()
73                }
74                fn resolve(x: $base, sign_set: Choice) -> CtOption<$name_affine> {
75                    $name_affine::y2(x).sqrt().map(|y| {
76                        let y = $base::conditional_select(&y, &-y, sign_set ^ Choice::from(y.to_repr()[0] as u8 & 1));
77                        $name_affine { x, y }
78                    })
79                }
80            }
81        }
82
83
84        new_curve_impl!(($($privacy)*), $name, $name_affine, $base, $scalar, $generator, $constant_a, $constant_b, $curve_id, $hash_to_curve, $flag_config);
85    };
86
87    (($($privacy:tt)*),
88    $name:ident,
89    $name_affine:ident,
90    $base:ident,
91    $scalar:ident,
92    $generator:expr,
93    $constant_a:expr,
94    $constant_b:expr,
95    $curve_id:literal,
96    $hash_to_curve:expr,
97    $flag_config:expr
98    ) => {
99
100
101        paste::paste! {
102            const [< $name:upper _COMPRESSED_SIZE >]: usize = $base::SIZE + if $flag_config.has_extra_byte() { 1 } else { 0 };
103
104            pub type [<$name:upper Compressed >] = $crate::serde::Repr<[< $name:upper _COMPRESSED_SIZE >]>;
105            pub type [<$name Uncompressed >] = $crate::serde::Repr<{ 2*$base::SIZE }>;
106
107            impl GroupEncoding for $name_affine {
108                type Repr = [<$name:upper Compressed >];
109
110                fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
111                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::decode(bytes.clone())
112                }
113
114                fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
115                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::decode(bytes.clone())
116                }
117
118                fn to_bytes(&self) -> Self::Repr {
119                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::encode(&self)
120                }
121            }
122
123            impl GroupEncoding for $name {
124                type Repr = [<$name:upper Compressed >];
125
126                fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
127                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::decode(bytes.clone()).map(Self::from)
128                }
129
130                fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
131                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::decode(bytes.clone()).map(Self::from)
132                }
133
134                fn to_bytes(&self) -> Self::Repr {
135                    <Self::Repr as $crate::serde::Compressed<$name_affine>>::encode(&self.to_affine())
136                }
137            }
138
139            impl group::UncompressedEncoding for $name_affine {
140                type Uncompressed = [<$name Uncompressed >];
141
142                fn from_uncompressed(bytes: &Self::Uncompressed) -> CtOption<Self> {
143                    Self::from_uncompressed_unchecked(bytes).and_then(|p| CtOption::new(p, p.is_on_curve()))
144                }
145
146                fn from_uncompressed_unchecked(bytes: &Self::Uncompressed) -> CtOption<Self> {
147                    let mut repr = [0u8; $base::SIZE];
148
149                    let x = {
150                        repr.copy_from_slice(&bytes[0..$base::SIZE]);
151                        $base::from_bytes(&repr)
152                    };
153
154                    let y = {
155                        repr.copy_from_slice(&bytes[$base::SIZE..2*$base::SIZE]);
156                        $base::from_bytes(&repr)
157                    };
158
159                    x.and_then(|x| {
160                        y.and_then(|y| {
161                            let is_identity = x.is_zero() & y.is_zero();
162                            let unchecked = Self { x, y };
163                            subtle::CtOption::new($name_affine::identity(), is_identity)
164                                .or_else(|| subtle::CtOption::new(unchecked, Choice::from(1u8)))
165                        })
166                    })
167                }
168
169                fn to_uncompressed(&self) -> Self::Uncompressed {
170                    let mut res = Self::Uncompressed::default();
171
172                    res[0..$base::SIZE].copy_from_slice(
173                        &$base::conditional_select(&self.x, &$base::zero(), self.is_identity()).to_bytes()[..],
174                    );
175
176                    res[$base::SIZE.. 2*$base::SIZE].copy_from_slice(
177                        &$base::conditional_select(&self.y, &$base::zero(), self.is_identity()).to_bytes()[..],
178                    );
179
180                    res
181                }
182            }
183        }
184
185        /// A macro to help define point serialization using the [`group::GroupEncoding`] trait
186        /// This assumes both point types ($name, $nameaffine) implement [`group::GroupEncoding`].
187        #[cfg(feature = "derive_serde")]
188        macro_rules! serialize_deserialize_to_from_bytes {
189            () => {
190                impl ::serde::Serialize for $name {
191                    fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
192                        let bytes = &self.to_bytes();
193                        if serializer.is_human_readable() {
194                            ::hex::serde::serialize(&bytes, serializer)
195                        } else {
196                            ::serde_arrays::serialize(bytes.inner(), serializer)
197                        }
198                    }
199                }
200
201                paste::paste! {
202                    impl<'de> ::serde::Deserialize<'de> for $name {
203                        fn deserialize<D: ::serde::Deserializer<'de>>(
204                            deserializer: D,
205                        ) -> Result<Self, D::Error> {
206                            use ::serde::de::Error as _;
207                            let bytes = if deserializer.is_human_readable() {
208                                ::hex::serde::deserialize(deserializer)?
209                            } else {
210                                ::serde_arrays::deserialize::<_, u8, [< $name:upper _COMPRESSED_SIZE >]>(deserializer)?
211                            };
212                            Option::from(Self::from_bytes(&bytes.into())).ok_or_else(|| {
213                                D::Error::custom("deserialized bytes don't encode a valid field element")
214                            })
215                        }
216                    }
217                }
218
219                impl ::serde::Serialize for $name_affine {
220                    fn serialize<S: ::serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
221                        let bytes = &self.to_bytes();
222                        if serializer.is_human_readable() {
223                            ::hex::serde::serialize(&bytes, serializer)
224                        } else {
225                            ::serde_arrays::serialize(bytes.inner(), serializer)
226                        }
227                    }
228                }
229
230                paste::paste! {
231                    impl<'de> ::serde::Deserialize<'de> for $name_affine {
232                        fn deserialize<D: ::serde::Deserializer<'de>>(
233                            deserializer: D,
234                        ) -> Result<Self, D::Error> {
235                            use ::serde::de::Error as _;
236                            let bytes = if deserializer.is_human_readable() {
237                                ::hex::serde::deserialize(deserializer)?
238                            } else {
239                                ::serde_arrays::deserialize::<_, u8, [< $name:upper _COMPRESSED_SIZE >]>(deserializer)?
240                            };
241                            Option::from(Self::from_bytes(&bytes.into())).ok_or_else(|| {
242                                D::Error::custom("deserialized bytes don't encode a valid field element")
243                            })
244                        }
245                    }
246                }
247            };
248        }
249
250        #[derive(Copy, Clone, Debug)]
251        $($privacy)* struct $name {
252            pub x: $base,
253            pub y: $base,
254            pub z: $base,
255        }
256
257        #[derive(Copy, Clone, PartialEq)]
258        $($privacy)* struct $name_affine {
259            pub x: $base,
260            pub y: $base,
261        }
262
263        #[cfg(feature = "derive_serde")]
264        serialize_deserialize_to_from_bytes!();
265
266
267
268        impl $name {
269            pub fn generator() -> Self {
270                let generator = $name_affine::generator();
271                Self {
272                    x: generator.x,
273                    y: generator.y,
274                    z: $base::one(),
275                }
276            }
277
278            #[inline]
279            fn curve_constant_3b() -> $base {
280                lazy_static::lazy_static! {
281                    static ref CONST_3B: $base = $constant_b + $constant_b + $constant_b;
282                }
283                *CONST_3B
284            }
285
286            fn mul_by_3b(input: &$base) -> $base {
287                if $name::CURVE_ID == "bn256_g1"{
288                    input.double().double().double() + input
289                } else {
290                    input * $name::curve_constant_3b()
291                }
292            }
293        }
294
295        impl $name_affine {
296            pub fn generator() -> Self {
297                Self {
298                    x: $generator.0,
299                    y: $generator.1,
300                }
301            }
302
303            #[inline(always)]
304            fn y2(x: $base) -> $base {
305                if $constant_a == $base::ZERO {
306                    let x3 = x.square() * x;
307                    (x3 + $constant_b)
308                } else {
309                    let x2 = x.square();
310                    ((x2 + $constant_a) * x + $constant_b)
311                }
312            }
313
314            pub fn random(mut rng: impl RngCore) -> Self {
315                loop {
316                    let x = $base::random(&mut rng);
317                    let ysign = (rng.next_u32() % 2) as u8;
318
319                    let y2 = $name_affine::y2(x);
320                    if let Some(y) = Option::<$base>::from(y2.sqrt()) {
321                        let sign = y.to_repr()[0] & 1;
322                        let y = if ysign ^ sign == 0 { y } else { -y };
323
324                        let p = $name_affine {
325                            x,
326                            y,
327                        };
328
329
330                        use $crate::group::cofactor::CofactorGroup;
331                        let p = p.to_curve();
332                        return p.clear_cofactor().to_affine()
333                    }
334                }
335            }
336        }
337
338
339
340        // Jacobian implementations
341
342        impl<'a> From<&'a $name_affine> for $name {
343            fn from(p: &'a $name_affine) -> $name {
344                p.to_curve()
345            }
346        }
347
348        impl From<$name_affine> for $name {
349            fn from(p: $name_affine) -> $name {
350                p.to_curve()
351            }
352        }
353
354        impl Default for $name {
355            fn default() -> $name {
356                $name::identity()
357            }
358        }
359
360        impl subtle::ConstantTimeEq for $name {
361            fn ct_eq(&self, other: &Self) -> Choice {
362                // Is (x, y, z) equal to (x', y, z') when converted to affine?
363                // => (x/z , y/z) equal to (x'/z' , y'/z')
364                // => (xz' == x'z) & (yz' == y'z)
365
366                let x1 = self.x * other.z;
367                let y1 = self.y * other.z;
368
369                let x2 = other.x * self.z;
370                let y2 = other.y * self.z;
371
372                let self_is_zero = self.is_identity();
373                let other_is_zero = other.is_identity();
374
375                (self_is_zero & other_is_zero) // Both point at infinity
376                            | ((!self_is_zero) & (!other_is_zero) & x1.ct_eq(&x2) & y1.ct_eq(&y2))
377                // Neither point at infinity, coordinates are the same
378            }
379
380        }
381
382        impl subtle::ConditionallySelectable for $name {
383            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
384                $name {
385                    x: $base::conditional_select(&a.x, &b.x, choice),
386                    y: $base::conditional_select(&a.y, &b.y, choice),
387                    z: $base::conditional_select(&a.z, &b.z, choice),
388                }
389            }
390        }
391
392        impl PartialEq for $name {
393            fn eq(&self, other: &Self) -> bool {
394                self.ct_eq(other).into()
395            }
396        }
397
398        impl cmp::Eq for $name {}
399
400        impl CurveExt for $name {
401
402            type ScalarExt = $scalar;
403            type Base = $base;
404            type AffineExt = $name_affine;
405
406            const CURVE_ID: &'static str = $curve_id;
407
408            fn endo(&self) -> Self {
409                Self {
410                    x: self.x * Self::Base::ZETA,
411                    y: self.y,
412                    z: self.z,
413                }
414            }
415
416            fn jacobian_coordinates(&self) -> ($base, $base, $base) {
417                // Homogeneous to Jacobian
418                let x = self.x * self.z;
419                let y = self.y * self.z.square();
420                (x, y, self.z)
421            }
422
423
424            #[allow(clippy::redundant_closure_call)]
425            fn hash_to_curve<'a>(domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
426                $hash_to_curve(domain_prefix)
427            }
428
429            fn is_on_curve(&self) -> Choice {
430                if $constant_a == $base::ZERO {
431                    // Check (Y/Z)^2 = (X/Z)^3 + b
432                    // <=>    Z Y^2 - X^3 = Z^3 b
433
434                    (self.z * self.y.square() - self.x.square() * self.x)
435                        .ct_eq(&(self.z.square() * self.z * $constant_b))
436                        | self.z.is_zero()
437                } else {
438                    // Check (Y/Z)^2 = (X/Z)^3 + a(X/Z) + b
439                    // <=>    Z Y^2 - X^3 - a(X Z^2) = Z^3 b
440
441                    let z2 = self.z.square();
442                    (self.z * self.y.square() - (self.x.square() + $constant_a * z2) * self.x)
443                        .ct_eq(&(z2 * self.z * $constant_b))
444                        | self.z.is_zero()
445                }
446            }
447
448            fn b() -> Self::Base {
449                $constant_b
450            }
451
452            fn a() -> Self::Base {
453                $constant_a
454            }
455
456            fn new_jacobian(x: Self::Base, y: Self::Base, z: Self::Base) -> CtOption<Self> {
457                // Jacobian to homogeneous
458                let z_inv = z.invert().unwrap_or($base::zero());
459                let p_x = x * z_inv;
460                let p_y = y * z_inv.square();
461                let p = $name {
462                    x:p_x,
463                    y:$base::conditional_select(&p_y, &$base::one(), z.is_zero()),
464                    z
465                };
466                CtOption::new(p, p.is_on_curve())
467            }
468        }
469
470        impl group::Curve for $name {
471
472            type AffineRepr = $name_affine;
473
474            fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
475                assert_eq!(p.len(), q.len());
476
477                let mut acc = $base::one();
478                for (p, q) in p.iter().zip(q.iter_mut()) {
479                    // We use the `x` field of $name_affine to store the product
480                    // of previous z-coordinates seen.
481                    q.x = acc;
482
483                    // We will end up skipping all identities in p
484                    acc = $base::conditional_select(&(acc * p.z), &acc, p.is_identity());
485                }
486
487                // This is the inverse, as all z-coordinates are nonzero and the ones
488                // that are not are skipped.
489                acc = acc.invert().unwrap();
490
491                for (p, q) in p.iter().rev().zip(q.iter_mut().rev()) {
492                    let skip = p.is_identity();
493
494                    // Compute tmp = 1/z
495                    let tmp = q.x * acc;
496
497                    // Cancel out z-coordinate in denominator of `acc`
498                    acc = $base::conditional_select(&(acc * p.z), &acc, skip);
499
500                    q.x = p.x * tmp;
501                    q.y = p.y * tmp;
502
503                    *q = $name_affine::conditional_select(&q, &$name_affine::identity(), skip);
504                }
505            }
506
507            fn to_affine(&self) -> Self::AffineRepr {
508                let zinv = self.z.invert().unwrap_or($base::zero());
509                let x = self.x * zinv;
510                let y = self.y * zinv;
511                let tmp = $name_affine {
512                    x,
513                    y,
514                };
515                $name_affine::conditional_select(&tmp, &$name_affine::identity(), zinv.is_zero())
516            }
517        }
518
519        impl group::Group for $name {
520            type Scalar = $scalar;
521
522            fn random(mut rng: impl RngCore) -> Self {
523                $name_affine::random(&mut rng).to_curve()
524            }
525
526            fn double(&self) -> Self {
527                if $constant_a == $base::ZERO {
528                    // Algorithm 9, https://eprint.iacr.org/2015/1060.pdf
529                    let t0 = self.y.square();
530                    let z3 = t0 + t0;
531                    let z3 = z3 + z3;
532                    let z3 = z3 + z3;
533                    let t1 = self.y * self.z;
534                    let t2 = self.z.square();
535                    let t2 = $name::mul_by_3b(&t2);
536                    let x3 = t2 * z3;
537                    let y3 = t0 + t2;
538                    let z3 = t1 * z3;
539                    let t1 = t2 + t2;
540                    let t2 = t1 + t2;
541                    let t0 = t0 - t2;
542                    let y3 = t0 * y3;
543                    let y3 = x3 + y3;
544                    let t1 = self.x * self.y;
545                    let x3 = t0 * t1;
546                    let x3 = x3 + x3;
547
548                    let tmp = $name {
549                        x: x3,
550                        y: y3,
551                        z: z3,
552                    };
553
554                    $name::conditional_select(&tmp, &$name::identity(), self.is_identity())
555                } else {
556                    // Algorithm 3, https://eprint.iacr.org/2015/1060.pdf
557                    let t0 = self.x.square();
558                    let t1 = self.y.square();
559                    let t2 = self.z.square();
560                    let t3 = self.x * self.y;
561                    let t3 = t3 + t3;
562                    let z3 = self.x * self.z;
563                    let z3 = z3 + z3;
564                    let x3 = $constant_a * z3;
565                    let y3 = $name::mul_by_3b(&t2);
566                    let y3 = x3 + y3;
567                    let x3 = t1 - y3;
568                    let y3 = t1 + y3;
569                    let y3 = x3 * y3;
570                    let x3 = t3 * x3;
571                    let z3 = $name::mul_by_3b(&z3);
572                    let t2 = $constant_a * t2;
573                    let t3 = t0 - t2;
574                    let t3 = $constant_a * t3;
575                    let t3 = t3 + z3;
576                    let z3 = t0 + t0;
577                    let t0 = z3 + t0;
578                    let t0 = t0 + t2;
579                    let t0 = t0 * t3;
580                    let y3 = y3 + t0;
581                    let t2 = self.y * self.z;
582                    let t2 = t2 + t2;
583                    let t0 = t2 * t3;
584                    let x3 = x3 - t0;
585                    let z3 = t2 * t1;
586                    let z3 = z3 + z3;
587                    let z3 = z3 + z3;
588
589                    let tmp = $name {
590                        x: x3,
591                        y: y3,
592                        z: z3,
593                    };
594
595                    $name::conditional_select(&tmp, &$name::identity(), self.is_identity())
596                }
597            }
598
599            fn generator() -> Self {
600                $name::generator()
601            }
602
603            fn identity() -> Self {
604                Self {
605                    x: $base::zero(),
606                    y: $base::one(),
607                    z: $base::zero(),
608                }
609            }
610
611            fn is_identity(&self) -> Choice {
612                self.z.is_zero()
613            }
614        }
615
616        impl $crate::serde::SerdeObject for $name {
617            fn from_raw_bytes_unchecked(bytes: &[u8]) -> Self {
618                debug_assert_eq!(bytes.len(), 3 * $base::SIZE);
619                let [x, y, z] = [0, 1, 2]
620                    .map(|i| $base::from_raw_bytes_unchecked(&bytes[i * $base::SIZE..(i + 1) * $base::SIZE]));
621                Self { x, y, z }
622            }
623            fn from_raw_bytes(bytes: &[u8]) -> Option<Self> {
624                if bytes.len() != 3 * $base::SIZE {
625                    return None;
626                }
627                let [x, y, z] =
628                    [0, 1, 2].map(|i| $base::from_raw_bytes(&bytes[i * $base::SIZE..(i + 1) * $base::SIZE]));
629                x.zip(y).zip(z).and_then(|((x, y), z)| {
630                    let res = Self { x, y, z };
631                    // Check that the point is on the curve.
632                    bool::from(res.is_on_curve()).then(|| res)
633                })
634            }
635            fn to_raw_bytes(&self) -> Vec<u8> {
636                let mut res = Vec::with_capacity(3 * $base::SIZE);
637                Self::write_raw(self, &mut res).unwrap();
638                res
639            }
640            fn read_raw_unchecked<R: std::io::Read>(reader: &mut R) -> Self {
641                let [x, y, z] = [(); 3].map(|_| $base::read_raw_unchecked(reader));
642                Self { x, y, z }
643            }
644            fn read_raw<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
645                let x = $base::read_raw(reader)?;
646                let y = $base::read_raw(reader)?;
647                let z = $base::read_raw(reader)?;
648                Ok(Self { x, y, z })
649            }
650            fn write_raw<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
651                self.x.write_raw(writer)?;
652                self.y.write_raw(writer)?;
653                self.z.write_raw(writer)
654            }
655        }
656
657        impl group::prime::PrimeGroup for $name {}
658
659        impl group::prime::PrimeCurve for $name {
660            type Affine = $name_affine;
661        }
662
663        impl group::cofactor::CofactorCurve for $name {
664            type Affine = $name_affine;
665        }
666
667        // Affine implementations
668
669        impl std::fmt::Debug for $name_affine {
670            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
671                if self.is_identity().into() {
672                    write!(f, "Infinity")
673                } else {
674                    write!(f, "({:?}, {:?})", self.x, self.y)
675                }
676            }
677        }
678
679        impl<'a> From<&'a $name> for $name_affine {
680            fn from(p: &'a $name) -> $name_affine {
681                p.to_affine()
682            }
683        }
684
685        impl From<$name> for $name_affine {
686            fn from(p: $name) -> $name_affine {
687                p.to_affine()
688            }
689        }
690
691        impl Default for $name_affine {
692            fn default() -> $name_affine {
693                $name_affine::identity()
694            }
695        }
696
697        impl subtle::ConstantTimeEq for $name_affine {
698            fn ct_eq(&self, other: &Self) -> Choice {
699                let z1 = self.is_identity();
700                let z2 = other.is_identity();
701
702                (z1 & z2) | ((!z1) & (!z2) & (self.x.ct_eq(&other.x)) & (self.y.ct_eq(&other.y)))
703            }
704        }
705
706        impl subtle::ConditionallySelectable for $name_affine {
707            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
708                $name_affine {
709                    x: $base::conditional_select(&a.x, &b.x, choice),
710                    y: $base::conditional_select(&a.y, &b.y, choice),
711                }
712            }
713        }
714
715        impl cmp::Eq for $name_affine {}
716
717
718        impl $crate::serde::SerdeObject for $name_affine {
719            fn from_raw_bytes_unchecked(bytes: &[u8]) -> Self {
720                debug_assert_eq!(bytes.len(), 2 * $base::SIZE);
721                let [x, y] =
722                    [0, $base::SIZE].map(|i| $base::from_raw_bytes_unchecked(&bytes[i..i + $base::SIZE]));
723                Self { x, y }
724            }
725            fn from_raw_bytes(bytes: &[u8]) -> Option<Self> {
726                if bytes.len() != 2 * $base::SIZE {
727                    return None;
728                }
729                let [x, y] = [0, $base::SIZE].map(|i| $base::from_raw_bytes(&bytes[i..i + $base::SIZE]));
730                x.zip(y).and_then(|(x, y)| {
731                    let res = Self { x, y };
732                    // Check that the point is on the curve.
733                    bool::from(res.is_on_curve()).then(|| res)
734                })
735            }
736            fn to_raw_bytes(&self) -> Vec<u8> {
737                let mut res = Vec::with_capacity(2 * $base::SIZE);
738                Self::write_raw(self, &mut res).unwrap();
739                res
740            }
741            fn read_raw_unchecked<R: std::io::Read>(reader: &mut R) -> Self {
742                let [x, y] = [(); 2].map(|_| $base::read_raw_unchecked(reader));
743                Self { x, y }
744            }
745            fn read_raw<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
746                let x = $base::read_raw(reader)?;
747                let y = $base::read_raw(reader)?;
748                Ok(Self { x, y })
749            }
750            fn write_raw<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
751                self.x.write_raw(writer)?;
752                self.y.write_raw(writer)
753            }
754        }
755
756        impl group::prime::PrimeCurveAffine for $name_affine {
757            type Curve = $name;
758            type Scalar = $scalar;
759
760
761            fn generator() -> Self {
762                $name_affine::generator()
763            }
764
765            fn identity() -> Self {
766                Self {
767                    x: $base::zero(),
768                    y: $base::zero(),
769                }
770            }
771
772            fn is_identity(&self) -> Choice {
773                self.x.is_zero() & self.y.is_zero()
774            }
775
776            fn to_curve(&self) -> Self::Curve {
777                let tmp = $name {
778                    x: self.x,
779                    y: self.y,
780                    z: $base::one(),
781                };
782                $name::conditional_select(&tmp, &$name::identity(), self.is_identity())
783            }
784        }
785
786        impl group::cofactor::CofactorCurveAffine for $name_affine {
787            type Curve = $name;
788            type Scalar = $scalar;
789
790            fn identity() -> Self {
791                <Self as group::prime::PrimeCurveAffine>::identity()
792            }
793
794            fn generator() -> Self {
795                <Self as group::prime::PrimeCurveAffine>::generator()
796            }
797
798            fn is_identity(&self) -> Choice {
799                <Self as group::prime::PrimeCurveAffine>::is_identity(self)
800            }
801
802            fn to_curve(&self) -> Self::Curve {
803                <Self as group::prime::PrimeCurveAffine>::to_curve(self)
804            }
805        }
806
807
808        impl CurveAffine for $name_affine {
809            type ScalarExt = $scalar;
810            type Base = $base;
811            type CurveExt = $name;
812
813            fn is_on_curve(&self) -> Choice {
814                if $constant_a == $base::ZERO {
815                    // y^2 - x^3 ?= b
816                    (self.y.square() - self.x.square() * self.x).ct_eq(&$constant_b)
817                        | self.is_identity()
818                } else {
819                    // y^2 - x^3 - ax ?= b
820                    (self.y.square() - (self.x.square() + $constant_a) * self.x).ct_eq(&$constant_b)
821                        | self.is_identity()
822                }
823            }
824
825            fn coordinates(&self) -> CtOption<Coordinates<Self>> {
826                Coordinates::from_xy( self.x, self.y )
827            }
828
829            fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self> {
830                let p = $name_affine {
831                    x, y
832                };
833                CtOption::new(p, p.is_on_curve())
834            }
835
836            fn a() -> Self::Base {
837                $constant_a
838            }
839
840            fn b() -> Self::Base {
841                $constant_b
842            }
843        }
844
845
846        impl_binops_additive!($name, $name);
847        impl_binops_additive!($name, $name_affine);
848        impl_binops_additive_specify_output!($name_affine, $name_affine, $name);
849        impl_binops_additive_specify_output!($name_affine, $name, $name);
850        impl_binops_multiplicative!($name, $scalar);
851        impl_binops_multiplicative_mixed!($name_affine, $scalar, $name);
852
853        impl<'a> Neg for &'a $name {
854            type Output = $name;
855
856            fn neg(self) -> $name {
857                $name {
858                    x: self.x,
859                    y: -self.y,
860                    z: self.z,
861                }
862            }
863        }
864
865        impl Neg for $name {
866            type Output = $name;
867
868            fn neg(self) -> $name {
869                -&self
870            }
871        }
872
873        impl<T> Sum<T> for $name
874        where
875            T: core::borrow::Borrow<$name>,
876        {
877            fn sum<I>(iter: I) -> Self
878            where
879                I: Iterator<Item = T>,
880            {
881                iter.fold(Self::identity(), |acc, item| acc + item.borrow())
882            }
883        }
884
885        impl<'a, 'b> Add<&'a $name> for &'b $name {
886            type Output = $name;
887
888            fn add(self, rhs: &'a $name) -> $name {
889                if $constant_a == $base::ZERO {
890                    // Algorithm 7, https://eprint.iacr.org/2015/1060.pdf
891                    let t0 = self.x * rhs.x;
892                    let t1 = self.y * rhs.y;
893                    let t2 = self.z * rhs.z;
894                    let t3 = self.x + self.y;
895                    let t4 = rhs.x + rhs.y;
896                    let t3 = t3 * t4;
897                    let t4 = t0 + t1;
898                    let t3 = t3 - t4;
899                    let t4 = self.y + self.z;
900                    let x3 = rhs.y + rhs.z;
901                    let t4 = t4 * x3;
902                    let x3 = t1 + t2;
903                    let t4 = t4 - x3;
904                    let x3 = self.x + self.z;
905                    let y3 = rhs.x + rhs.z;
906                    let x3 = x3 * y3;
907                    let y3 = t0 + t2;
908                    let y3 = x3 - y3;
909                    let x3 = t0 + t0;
910                    let t0 = x3 + t0;
911                    let t2 = $name::mul_by_3b(&t2);
912                    let z3 = t1 + t2;
913                    let t1 = t1 - t2;
914                    let y3 = $name::mul_by_3b(&y3);
915                    let x3 = t4 * y3;
916                    let t2 = t3 * t1;
917                    let x3 = t2 - x3;
918                    let y3 = y3 * t0;
919                    let t1 = t1 * z3;
920                    let y3 = t1 + y3;
921                    let t0 = t0 * t3;
922                    let z3 = z3 * t4;
923                    let z3 = z3 + t0;
924
925                    $name {
926                        x: x3,
927                        y: y3,
928                        z: z3,
929                    }
930                } else {
931                    // Algorithm 1, https://eprint.iacr.org/2015/1060.pdf
932                    let t0 = self.x * rhs.x;
933                    let t1 = self.y * rhs.y;
934                    let t2 = self.z * rhs.z;
935                    let t3 = self.x + self.y;
936                    let t4 = rhs.x + rhs.y;
937                    let t3 = t3 * t4;
938                    let t4 = t0 + t1;
939                    let t3 = t3 - t4;
940                    let t4 = self.x + self.z;
941                    let t5 = rhs.x + rhs.z;
942                    let t4 = t4 * t5;
943                    let t5 = t0 + t2;
944                    let t4 = t4 - t5;
945                    let t5 = self.y + self.z;
946                    let x3 = rhs.y + rhs.z;
947                    let t5 = t5 * x3;
948                    let x3 = t1 + t2;
949                    let t5 = t5 - x3;
950                    let z3 = $constant_a * t4;
951                    let x3 = $name::mul_by_3b(&t2);
952                    let z3 = x3 + z3;
953                    let x3 = t1 - z3;
954                    let z3 = t1 + z3;
955                    let y3 = x3 * z3;
956                    let t1 = t0 + t0;
957                    let t1 = t1 + t0;
958                    let t2 = $constant_a * t2;
959                    let t4 = $name::mul_by_3b(&t4);
960                    let t1 = t1 + t2;
961                    let t2 = t0 - t2;
962                    let t2 = $constant_a * t2;
963                    let t4 = t4 + t2;
964                    let t0 = t1 * t4;
965                    let y3 = y3 + t0;
966                    let t0 = t5 * t4;
967                    let x3 = t3 * x3;
968                    let x3 = x3 - t0;
969                    let t0 = t3 * t1;
970                    let z3 = t5 * z3;
971                    let z3 = z3 + t0;
972
973                    $name {
974                        x: x3,
975                        y: y3,
976                        z: z3,
977                    }
978                }
979            }
980        }
981
982        impl<'a, 'b> Add<&'a $name_affine> for &'b $name {
983            type Output = $name;
984
985            // Mixed addition
986            fn add(self, rhs: &'a $name_affine) -> $name {
987                if $constant_a == $base::ZERO {
988                    // Algorithm 8, https://eprint.iacr.org/2015/1060.pdf
989                    let t0 = self.x * rhs.x;
990                    let t1 = self.y * rhs.y;
991                    let t3 = rhs.x + rhs.y;
992                    let t4 = self.x + self.y;
993                    let t3 = t3 * t4;
994                    let t4 = t0 + t1;
995                    let t3 = t3 - t4;
996                    let t4 = rhs.y * self.z;
997                    let t4 = t4 + self.y;
998                    let y3 = rhs.x * self.z;
999                    let y3 = y3 + self.x;
1000                    let x3 = t0 + t0;
1001                    let t0 = x3 + t0;
1002                    let t2 = $name::mul_by_3b(&self.z);
1003                    let z3 = t1 + t2;
1004                    let t1 = t1 - t2;
1005                    let y3 = $name::mul_by_3b(&y3);
1006                    let x3 = t4 * y3;
1007                    let t2 = t3 * t1;
1008                    let x3 = t2 - x3;
1009                    let y3 = y3 * t0;
1010                    let t1 = t1 * z3;
1011                    let y3 = t1 + y3;
1012                    let t0 = t0 * t3;
1013                    let z3 = z3 * t4;
1014                    let z3 = z3 + t0;
1015
1016                    let tmp = $name{
1017                        x: x3,
1018                        y: y3,
1019                        z: z3,
1020                    };
1021
1022                    $name::conditional_select(&tmp, self, rhs.is_identity())
1023                } else {
1024                    // Algorithm 2, https://eprint.iacr.org/2015/1060.pdf
1025                    let t0 = self.x * rhs.x;
1026                    let t1 = self.y * rhs.y;
1027                    let t3 = rhs.x + rhs.y;
1028                    let t4 = self.x + self.y;
1029                    let t3 = t3 * t4;
1030                    let t4 = t0 + t1;
1031                    let t3 = t3 - t4;
1032                    let t4 = rhs.x * self.z;
1033                    let t4 = t4 + self.x;
1034                    let t5 = rhs.y * self.z;
1035                    let t5 = t5 + self.y;
1036                    let z3 = $constant_a * t4;
1037                    let x3 = $name::mul_by_3b(&self.z);
1038                    let z3 = x3 + z3;
1039                    let x3 = t1 - z3;
1040                    let z3 = t1 + z3;
1041                    let y3 = x3 * z3;
1042                    let t1 = t0 + t0;
1043                    let t1 = t1 + t0;
1044                    let t2 = $constant_a * self.z;
1045                    let t4 = $name::mul_by_3b(&t4);
1046                    let t1 = t1 + t2;
1047                    let t2 = t0 - t2;
1048                    let t2 = $constant_a * t2;
1049                    let t4 = t4 + t2;
1050                    let t0 = t1 * t4;
1051                    let y3 = y3 + t0;
1052                    let t0 = t5 * t4;
1053                    let x3 = t3 * x3;
1054                    let x3 = x3 - t0;
1055                    let t0 = t3 * t1;
1056                    let z3 = t5 * z3;
1057                    let z3 = z3 + t0;
1058
1059                    let tmp = $name{
1060                        x: x3,
1061                        y: y3,
1062                        z: z3,
1063                    };
1064
1065                    $name::conditional_select(&tmp, self, rhs.is_identity())
1066                }
1067            }
1068        }
1069
1070        impl<'a, 'b> Sub<&'a $name> for &'b $name {
1071            type Output = $name;
1072
1073            fn sub(self, other: &'a $name) -> $name {
1074                self + (-other)
1075            }
1076        }
1077
1078        impl<'a, 'b> Sub<&'a $name_affine> for &'b $name {
1079            type Output = $name;
1080
1081            fn sub(self, other: &'a $name_affine) -> $name {
1082                self + (-other)
1083            }
1084        }
1085
1086
1087
1088        #[allow(clippy::suspicious_arithmetic_impl)]
1089        impl<'a, 'b> Mul<&'b $scalar> for &'a $name {
1090            type Output = $name;
1091
1092            // This is a simple double-and-add implementation of point
1093            // multiplication, moving from most significant to least
1094            // significant bit of the scalar.
1095
1096            fn mul(self, other: &'b $scalar) -> Self::Output {
1097                let mut acc = $name::identity();
1098                for bit in other
1099                    .to_repr()
1100                    .as_ref()
1101                    .iter()
1102                    .rev()
1103                    .flat_map(|byte| (0..8).rev().map(move |i| Choice::from((byte >> i) & 1u8)))
1104                {
1105                    acc = acc.double();
1106                    acc = $name::conditional_select(&acc, &(acc + self), bit);
1107                }
1108
1109                acc
1110            }
1111        }
1112
1113        impl<'a> Neg for &'a $name_affine {
1114            type Output = $name_affine;
1115
1116            fn neg(self) -> $name_affine {
1117                $name_affine {
1118                    x: self.x,
1119                    y: -self.y,
1120                }
1121            }
1122        }
1123
1124        impl Neg for $name_affine {
1125            type Output = $name_affine;
1126
1127            fn neg(self) -> $name_affine {
1128                -&self
1129            }
1130        }
1131
1132        impl<'a, 'b> Add<&'a $name> for &'b $name_affine {
1133            type Output = $name;
1134
1135            fn add(self, rhs: &'a $name) -> $name {
1136                rhs + self
1137            }
1138        }
1139
1140        impl<'a, 'b> Add<&'a $name_affine> for &'b $name_affine {
1141            type Output = $name;
1142
1143            fn add(self, rhs: &'a $name_affine) -> $name {
1144                rhs.to_curve() + self.to_curve()
1145            }
1146        }
1147
1148        impl<'a, 'b> Sub<&'a $name_affine> for &'b $name_affine {
1149            type Output = $name;
1150
1151            fn sub(self, other: &'a $name_affine) -> $name {
1152                self + (-other)
1153            }
1154        }
1155
1156        impl<'a, 'b> Sub<&'a $name> for &'b $name_affine {
1157            type Output = $name;
1158
1159            fn sub(self, other: &'a $name) -> $name {
1160                self + (-other)
1161            }
1162        }
1163
1164        #[allow(clippy::suspicious_arithmetic_impl)]
1165        impl<'a, 'b> Mul<&'b $scalar> for &'a $name_affine {
1166            type Output = $name;
1167
1168            fn mul(self, other: &'b $scalar) -> Self::Output {
1169                let mut acc = $name::identity();
1170
1171                // This is a simple double-and-add implementation of point
1172                // multiplication, moving from most significant to least
1173                // significant bit of the scalar.
1174
1175                for bit in other
1176                    .to_repr()
1177                    .as_ref()
1178                    .iter()
1179                    .rev()
1180                    .flat_map(|byte| (0..8).rev().map(move |i| Choice::from((byte >> i) & 1u8)))
1181                {
1182                    acc = acc.double();
1183                    acc = $name::conditional_select(&acc, &(acc + self), bit);
1184                }
1185
1186                acc
1187            }
1188        }
1189    };
1190}