halo2curves_axiom/ed25519/
curve.rs

1use crate::ed25519::Fq;
2use crate::ed25519::Fr;
3use crate::{Coordinates, CurveAffine, CurveAffineExt, CurveExt};
4use core::cmp;
5use core::fmt::Debug;
6use core::iter::Sum;
7use core::ops::{Add, Mul, Neg, Sub};
8use ff::{BatchInverter, Field, PrimeField};
9use group::{self, Curve};
10use group::{prime::PrimeCurveAffine, GroupEncoding};
11use rand::RngCore;
12use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
13
14#[cfg(feature = "derive_serde")]
15use serde::{Deserialize, Serialize};
16
17const ED25519_GENERATOR_X: Fq = Fq::from_raw([
18    0xc956_2d60_8f25_d51a,
19    0x692c_c760_9525_a7b2,
20    0xc0a4_e231_fdd6_dc5c,
21    0x2169_36d3_cd6e_53fe,
22]);
23const ED25519_GENERATOR_Y: Fq = Fq::from_raw([
24    0x6666_6666_6666_6658,
25    0x6666_6666_6666_6666,
26    0x6666_6666_6666_6666,
27    0x6666_6666_6666_6666,
28]);
29
30// `d = -(121665/121666)`
31const ED25519_D: Fq = Fq::from_raw([
32    0x75eb_4dca_1359_78a3,
33    0x0070_0a4d_4141_d8ab,
34    0x8cc7_4079_7779_e898,
35    0x5203_6cee_2b6f_fe73,
36]);
37
38const FR_MODULUS_BYTES: [u8; 32] = [
39    237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0,
40    0, 0, 0, 0, 0, 0, 0, 0, 16,
41];
42
43use crate::{
44    impl_add_binop_specify_output, impl_binops_additive, impl_binops_additive_specify_output,
45    impl_binops_multiplicative, impl_binops_multiplicative_mixed, impl_sub_binop_specify_output,
46};
47
48#[derive(Copy, Clone, Debug)]
49#[cfg_attr(feature = "derive_serde", derive(Serialize, Deserialize))]
50pub struct Ed25519 {
51    pub x: Fq,
52    pub y: Fq,
53    pub z: Fq,
54    pub t: Fq,
55}
56
57#[derive(Copy, Clone, Debug, PartialEq, Hash)]
58#[cfg_attr(feature = "derive_serde", derive(Serialize, Deserialize))]
59pub struct Ed25519Affine {
60    pub x: Fq,
61    pub y: Fq,
62}
63
64#[derive(Copy, Clone, Hash, Default)]
65pub struct Ed25519Compressed([u8; 32]);
66
67impl Ed25519 {
68    /// Constructs an extended point from the neutral element `(0, 1)`.
69    pub const fn identity() -> Self {
70        Ed25519 {
71            x: Fq::zero(),
72            y: Fq::one(),
73            z: Fq::one(),
74            t: Fq::zero(),
75        }
76    }
77
78    /// Determines if this point is the identity.
79    pub fn is_identity(&self) -> Choice {
80        // If this point is the identity, then
81        //     u = 0 * z = 0
82        // and v = 1 * z = z
83        self.x.ct_eq(&Fq::zero()) & self.y.ct_eq(&self.z)
84    }
85
86    /// Determines if this point is torsion free and so is contained
87    /// in the prime order subgroup.
88    pub fn is_torsion_free(&self) -> Choice {
89        self.multiply(&FR_MODULUS_BYTES).is_identity()
90    }
91
92    #[inline]
93    fn multiply(&self, by: &[u8; 32]) -> Ed25519 {
94        let zero = Ed25519::identity();
95        let mut acc = Ed25519::identity();
96
97        // This is a simple double-and-add implementation of point
98        // multiplication, moving from most significant to least
99        // significant bit of the scalar.
100        //
101        // We skip the leading three bits because they're always
102        // unset for Fr.
103        for bit in by
104            .iter()
105            .rev()
106            .flat_map(|byte| (0..8).rev().map(move |i| Choice::from((byte >> i) & 1u8)))
107            .skip(3)
108        {
109            acc = acc.double();
110            acc += Ed25519::conditional_select(&zero, self, bit);
111        }
112
113        acc
114    }
115
116    /// Multiplies this element by the cofactor `8`.
117    pub fn mul_by_cofactor(&self) -> Ed25519 {
118        self.double().double().double()
119    }
120
121    pub fn generator() -> Self {
122        let generator = Ed25519Affine::generator();
123        Self {
124            x: generator.x,
125            y: generator.y,
126            z: Fq::one(),
127            t: generator.x * generator.y,
128        }
129    }
130
131    pub fn double(&self) -> Ed25519 {
132        //  A = X1^2
133        //  B = Y1^2
134        //  C = 2*Z1^2
135        //  H = A+B
136        //  E = H-(X1+Y1)^2
137        //  G = A-B
138        //  F = C+G
139        //  X3 = E*F
140        //  Y3 = G*H
141        //  T3 = E*H
142        //  Z3 = F*G
143
144        let a = self.x.square();
145        let b = self.y.square();
146        let c = self.z.square().double();
147
148        let h = a + b;
149        let e = h - (self.x + self.y).square();
150        let g = a - b;
151        let f = c + g;
152
153        Ed25519 {
154            x: e * f,
155            y: g * h,
156            z: f * g,
157            t: e * h,
158        }
159    }
160}
161
162impl Ed25519Affine {
163    /// Constructs the neutral element `(0, 1)`.
164    pub const fn identity() -> Self {
165        Ed25519Affine {
166            x: Fq::zero(),
167            y: Fq::one(),
168        }
169    }
170
171    /// Determines if this point is the identity.
172    pub fn is_identity(&self) -> Choice {
173        Ed25519::from(*self).is_identity()
174    }
175
176    pub fn generator() -> Self {
177        Self {
178            x: ED25519_GENERATOR_X,
179            y: ED25519_GENERATOR_Y,
180        }
181    }
182
183    pub fn to_extended(&self) -> Ed25519 {
184        Ed25519 {
185            x: self.x,
186            y: self.y,
187            z: Fq::one(),
188            t: self.x * self.y,
189        }
190    }
191
192    pub fn random(mut rng: impl RngCore) -> Self {
193        loop {
194            let y = Fq::random(&mut rng);
195            let flip_sign = rng.next_u32() % 2 != 0;
196
197            let y2 = y.square();
198            let p = ((y2 - Fq::one())
199                * ((Fq::one() + ED25519_D * y2).invert().unwrap_or(Fq::zero())))
200            .sqrt()
201            .map(|x| Ed25519Affine {
202                x: if flip_sign { -x } else { x },
203                y,
204            });
205
206            if p.is_some().into() {
207                use crate::group::cofactor::CofactorGroup;
208                let p = p.unwrap().to_curve();
209
210                if bool::from(!p.is_identity()) {
211                    return p.clear_cofactor().to_affine();
212                }
213            }
214        }
215    }
216
217    /// Converts this element into its byte representation.
218    pub fn to_bytes(&self) -> [u8; 32] {
219        let mut tmp = self.y.to_bytes();
220        let u = self.x.to_bytes();
221
222        // Encode the sign of the u-coordinate in the most
223        // significant bit.
224        tmp[31] |= u[0] << 7;
225
226        tmp
227    }
228
229    /// Attempts to interpret a byte representation of an
230    /// affine point, failing if the element is not on
231    /// the curve or non-canonical.
232    pub fn from_bytes(b: [u8; 32]) -> CtOption<Self> {
233        Self::from_bytes_inner(b, 1.into())
234    }
235
236    fn from_bytes_inner(mut b: [u8; 32], zip_216_enabled: Choice) -> CtOption<Self> {
237        // Grab the sign bit from the representation
238        let sign = b[31] >> 7;
239
240        // Mask away the sign bit
241        b[31] &= 0b0111_1111;
242
243        // Interpret what remains as the v-coordinate
244        Fq::from_bytes(&b).and_then(|v| {
245            // -u^2 + v^2 = 1 + d.u^2.v^2
246            // -u^2 = 1 + d.u^2.v^2 - v^2    (rearrange)
247            // -u^2 - d.u^2.v^2 = 1 - v^2    (rearrange)
248            // u^2 + d.u^2.v^2 = v^2 - 1     (flip signs)
249            // u^2 (1 + d.v^2) = v^2 - 1     (factor)
250            // u^2 = (v^2 - 1) / (1 + d.v^2) (isolate u^2)
251            // We know that (1 + d.v^2) is nonzero for all v:
252            //   (1 + d.v^2) = 0
253            //   d.v^2 = -1
254            //   v^2 = -(1 / d)   No solutions, as -(1 / d) is not a square
255
256            let v2 = v.square();
257
258            ((v2 - Fq::one()) * ((Fq::one() + ED25519_D * v2).invert().unwrap_or(Fq::zero())))
259                .sqrt()
260                .and_then(|u| {
261                    // Fix the sign of `u` if necessary
262                    let flip_sign = Choice::from((u.to_bytes()[0] ^ sign) & 1);
263                    let u_negated = -u;
264                    let final_u = Fq::conditional_select(&u, &u_negated, flip_sign);
265
266                    // If u == 0, flip_sign == sign_bit. We therefore want to reject the
267                    // encoding as non-canonical if all of the following occur:
268                    // - ZIP 216 is enabled
269                    // - u == 0
270                    // - flip_sign == true
271                    let u_is_zero = u.ct_eq(&Fq::zero());
272                    CtOption::new(
273                        Ed25519Affine { x: final_u, y: v },
274                        !(zip_216_enabled & u_is_zero & flip_sign),
275                    )
276                })
277        })
278    }
279}
280
281// Compressed
282impl std::fmt::Debug for Ed25519Compressed {
283    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
284        self.0[..].fmt(f)
285    }
286}
287
288impl AsRef<[u8]> for Ed25519Compressed {
289    fn as_ref(&self) -> &[u8] {
290        &self.0
291    }
292}
293
294impl AsMut<[u8]> for Ed25519Compressed {
295    fn as_mut(&mut self) -> &mut [u8] {
296        &mut self.0
297    }
298}
299
300// Jacobian implementations
301impl<'a> From<&'a Ed25519Affine> for Ed25519 {
302    fn from(p: &'a Ed25519Affine) -> Ed25519 {
303        p.to_curve()
304    }
305}
306
307impl From<Ed25519Affine> for Ed25519 {
308    fn from(p: Ed25519Affine) -> Ed25519 {
309        p.to_curve()
310    }
311}
312
313impl Default for Ed25519 {
314    fn default() -> Ed25519 {
315        Ed25519::identity()
316    }
317}
318
319impl subtle::ConstantTimeEq for Ed25519 {
320    fn ct_eq(&self, other: &Self) -> Choice {
321        (self.x * other.z).ct_eq(&(other.x * self.z))
322            & (self.y * other.z).ct_eq(&(other.y * self.z))
323    }
324}
325
326impl subtle::ConditionallySelectable for Ed25519 {
327    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
328        Ed25519 {
329            x: Fq::conditional_select(&a.x, &b.x, choice),
330            y: Fq::conditional_select(&a.y, &b.y, choice),
331            z: Fq::conditional_select(&a.z, &b.z, choice),
332            t: Fq::conditional_select(&a.t, &b.t, choice),
333        }
334    }
335}
336
337impl PartialEq for Ed25519 {
338    fn eq(&self, other: &Self) -> bool {
339        self.ct_eq(other).into()
340    }
341}
342
343impl cmp::Eq for Ed25519 {}
344
345impl CurveExt for Ed25519 {
346    type ScalarExt = Fr;
347    type Base = Fq;
348    type AffineExt = Ed25519Affine;
349
350    const CURVE_ID: &'static str = "ed25519";
351
352    fn is_on_curve(&self) -> Choice {
353        let affine = Ed25519Affine::from(*self);
354        !self.z.is_zero() & affine.is_on_curve() & (affine.x * affine.y * self.z).ct_eq(&self.t)
355    }
356
357    fn endo(&self) -> Self {
358        unimplemented!();
359    }
360
361    fn jacobian_coordinates(&self) -> (Fq, Fq, Fq) {
362        unimplemented!();
363    }
364
365    fn hash_to_curve<'a>(_: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
366        unimplemented!();
367    }
368
369    fn a() -> Self::Base {
370        unimplemented!()
371    }
372
373    fn b() -> Self::Base {
374        unimplemented!()
375    }
376
377    fn new_jacobian(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> CtOption<Self> {
378        unimplemented!();
379    }
380}
381
382impl group::Curve for Ed25519 {
383    type AffineRepr = Ed25519Affine;
384
385    fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
386        assert_eq!(p.len(), q.len());
387
388        for (p, q) in p.iter().zip(q.iter_mut()) {
389            // We use the `u` field of `AffinePoint` to store the z-coordinate being
390            // inverted, and the `v` field for scratch space.
391            q.x = p.z;
392        }
393
394        BatchInverter::invert_with_internal_scratch(q, |q| &mut q.x, |q| &mut q.y);
395
396        for (p, q) in p.iter().zip(q.iter_mut()).rev() {
397            let tmp = q.x;
398
399            // Set the coordinates to the correct value
400            q.x = p.x * tmp; // Multiply by 1/z
401            q.y = p.y * tmp; // Multiply by 1/z
402        }
403    }
404
405    fn to_affine(&self) -> Self::AffineRepr {
406        // Z coordinate is always nonzero, so this is
407        // its inverse.
408        let zinv = self.z.invert().unwrap();
409
410        Ed25519Affine {
411            x: self.x * zinv,
412            y: self.y * zinv,
413        }
414    }
415}
416
417impl group::Group for Ed25519 {
418    type Scalar = Fr;
419
420    fn random(mut rng: impl RngCore) -> Self {
421        Ed25519Affine::random(&mut rng).to_curve()
422    }
423
424    fn generator() -> Self {
425        Ed25519::generator()
426    }
427
428    fn identity() -> Self {
429        Self::identity()
430    }
431
432    fn is_identity(&self) -> Choice {
433        self.is_identity()
434    }
435
436    #[must_use]
437    fn double(&self) -> Self {
438        self.double()
439    }
440}
441
442impl GroupEncoding for Ed25519 {
443    type Repr = Ed25519Compressed;
444
445    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
446        Ed25519Affine::from_bytes(bytes.0).map(Self::from)
447    }
448
449    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
450        Ed25519Affine::from_bytes(bytes.0).map(Self::from)
451    }
452
453    fn to_bytes(&self) -> Self::Repr {
454        Ed25519Compressed(Ed25519Affine::from(self).to_bytes())
455    }
456}
457
458impl crate::serde::SerdeObject for Ed25519 {
459    fn from_raw_bytes_unchecked(bytes: &[u8]) -> Self {
460        debug_assert_eq!(bytes.len(), 4 * Fq::size());
461        let [x, y, z, t] = [0, 1, 2, 3]
462            .map(|i| Fq::from_raw_bytes_unchecked(&bytes[i * Fq::size()..(i + 1) * Fq::size()]));
463        Self { x, y, z, t }
464    }
465    fn from_raw_bytes(bytes: &[u8]) -> Option<Self> {
466        if bytes.len() != 4 * Fq::size() {
467            return None;
468        }
469        let [x, y, z, t] =
470            [0, 1, 2, 3].map(|i| Fq::from_raw_bytes(&bytes[i * Fq::size()..(i + 1) * Fq::size()]));
471        x.zip(y).zip(z).zip(t).and_then(|(((x, y), z), t)| {
472            let res = Self { x, y, z, t };
473            // Check that the point is on the curve.
474            bool::from(res.is_on_curve()).then_some(res)
475        })
476    }
477    fn to_raw_bytes(&self) -> Vec<u8> {
478        let mut res = Vec::with_capacity(4 * Fq::size());
479        Self::write_raw(self, &mut res).unwrap();
480        res
481    }
482    fn read_raw_unchecked<R: std::io::Read>(reader: &mut R) -> Self {
483        let [x, y, z, t] = [(); 4].map(|_| Fq::read_raw_unchecked(reader));
484        Self { x, y, z, t }
485    }
486    fn read_raw<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
487        let x = Fq::read_raw(reader)?;
488        let y = Fq::read_raw(reader)?;
489        let z = Fq::read_raw(reader)?;
490        let t = Fq::read_raw(reader)?;
491        Ok(Self { x, y, z, t })
492    }
493    fn write_raw<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
494        self.x.write_raw(writer)?;
495        self.y.write_raw(writer)?;
496        self.z.write_raw(writer)?;
497        self.t.write_raw(writer)
498    }
499}
500
501impl group::prime::PrimeGroup for Ed25519 {}
502
503impl group::prime::PrimeCurve for Ed25519 {
504    type Affine = Ed25519Affine;
505}
506
507impl group::cofactor::CofactorCurve for Ed25519 {
508    type Affine = Ed25519Affine;
509}
510
511impl group::cofactor::CofactorGroup for Ed25519 {
512    type Subgroup = Ed25519;
513
514    fn clear_cofactor(&self) -> Self {
515        self.mul_by_cofactor()
516    }
517
518    fn into_subgroup(self) -> CtOption<Self::Subgroup> {
519        CtOption::new(self, self.is_torsion_free())
520    }
521
522    fn is_torsion_free(&self) -> Choice {
523        self.is_torsion_free()
524    }
525}
526
527impl<'a> From<&'a Ed25519> for Ed25519Affine {
528    fn from(p: &'a Ed25519) -> Ed25519Affine {
529        p.to_affine()
530    }
531}
532
533impl From<Ed25519> for Ed25519Affine {
534    fn from(p: Ed25519) -> Ed25519Affine {
535        p.to_affine()
536    }
537}
538
539impl Default for Ed25519Affine {
540    fn default() -> Ed25519Affine {
541        Ed25519Affine::identity()
542    }
543}
544
545impl subtle::ConstantTimeEq for Ed25519Affine {
546    fn ct_eq(&self, other: &Self) -> Choice {
547        self.x.ct_eq(&other.x) & self.y.ct_eq(&other.y)
548    }
549}
550
551impl subtle::ConditionallySelectable for Ed25519Affine {
552    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
553        Ed25519Affine {
554            x: Fq::conditional_select(&a.x, &b.x, choice),
555            y: Fq::conditional_select(&a.y, &b.y, choice),
556        }
557    }
558}
559
560impl cmp::Eq for Ed25519Affine {}
561
562impl group::GroupEncoding for Ed25519Affine {
563    type Repr = [u8; 32];
564
565    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
566        Self::from_bytes(*bytes)
567    }
568
569    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
570        Self::from_bytes(*bytes)
571    }
572
573    fn to_bytes(&self) -> Self::Repr {
574        self.to_bytes()
575    }
576}
577
578impl crate::serde::SerdeObject for Ed25519Affine {
579    fn from_raw_bytes_unchecked(bytes: &[u8]) -> Self {
580        debug_assert_eq!(bytes.len(), 2 * Fq::size());
581        let [x, y] =
582            [0, Fq::size()].map(|i| Fq::from_raw_bytes_unchecked(&bytes[i..i + Fq::size()]));
583        Self { x, y }
584    }
585    fn from_raw_bytes(bytes: &[u8]) -> Option<Self> {
586        if bytes.len() != 2 * Fq::size() {
587            return None;
588        }
589        let [x, y] = [0, Fq::size()].map(|i| Fq::from_raw_bytes(&bytes[i..i + Fq::size()]));
590        x.zip(y).and_then(|(x, y)| {
591            let res = Self { x, y };
592            // Check that the point is on the curve.
593            bool::from(res.is_on_curve()).then_some(res)
594        })
595    }
596    fn to_raw_bytes(&self) -> Vec<u8> {
597        let mut res = Vec::with_capacity(2 * Fq::size());
598        Self::write_raw(self, &mut res).unwrap();
599        res
600    }
601    fn read_raw_unchecked<R: std::io::Read>(reader: &mut R) -> Self {
602        let [x, y] = [(); 2].map(|_| Fq::read_raw_unchecked(reader));
603        Self { x, y }
604    }
605    fn read_raw<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
606        let x = Fq::read_raw(reader)?;
607        let y = Fq::read_raw(reader)?;
608        Ok(Self { x, y })
609    }
610    fn write_raw<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
611        self.x.write_raw(writer)?;
612        self.y.write_raw(writer)
613    }
614}
615
616impl group::prime::PrimeCurveAffine for Ed25519Affine {
617    type Curve = Ed25519;
618    type Scalar = Fr;
619
620    fn generator() -> Self {
621        Ed25519Affine::generator()
622    }
623
624    fn identity() -> Self {
625        Ed25519Affine::identity()
626    }
627
628    fn is_identity(&self) -> Choice {
629        self.is_identity()
630    }
631
632    fn to_curve(&self) -> Self::Curve {
633        Ed25519 {
634            x: self.x,
635            y: self.y,
636            z: Fq::one(),
637            t: self.x * self.y,
638        }
639    }
640}
641
642impl group::cofactor::CofactorCurveAffine for Ed25519Affine {
643    type Curve = Ed25519;
644    type Scalar = Fr;
645
646    fn identity() -> Self {
647        <Self as group::prime::PrimeCurveAffine>::identity()
648    }
649
650    fn generator() -> Self {
651        <Self as group::prime::PrimeCurveAffine>::generator()
652    }
653
654    fn is_identity(&self) -> Choice {
655        <Self as group::prime::PrimeCurveAffine>::is_identity(self)
656    }
657
658    fn to_curve(&self) -> Self::Curve {
659        <Self as group::prime::PrimeCurveAffine>::to_curve(self)
660    }
661}
662
663impl CurveAffine for Ed25519Affine {
664    type ScalarExt = Fr;
665    type Base = Fq;
666    type CurveExt = Ed25519;
667
668    fn is_on_curve(&self) -> Choice {
669        let x2 = self.x.square();
670        let y2 = self.y.square();
671
672        (y2 - x2).ct_eq(&(Fq::one() + ED25519_D * x2 * y2))
673    }
674
675    fn coordinates(&self) -> CtOption<Coordinates<Self>> {
676        Coordinates::from_xy(self.x, self.y)
677    }
678
679    fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self> {
680        let p = Ed25519Affine { x, y };
681        CtOption::new(p, p.is_on_curve())
682    }
683
684    fn a() -> Self::Base {
685        unimplemented!()
686    }
687
688    fn b() -> Self::Base {
689        unimplemented!()
690    }
691}
692
693impl_binops_additive!(Ed25519, Ed25519);
694impl_binops_additive!(Ed25519, Ed25519Affine);
695impl_binops_additive_specify_output!(Ed25519Affine, Ed25519Affine, Ed25519);
696impl_binops_additive_specify_output!(Ed25519Affine, Ed25519, Ed25519);
697impl_binops_multiplicative!(Ed25519, Fr);
698impl_binops_multiplicative_mixed!(Ed25519Affine, Fr, Ed25519);
699
700impl<'a> Neg for &'a Ed25519 {
701    type Output = Ed25519;
702
703    fn neg(self) -> Ed25519 {
704        Ed25519 {
705            x: -self.x,
706            y: self.y,
707            z: self.z,
708            t: -self.t,
709        }
710    }
711}
712
713impl Neg for Ed25519 {
714    type Output = Ed25519;
715
716    fn neg(self) -> Ed25519 {
717        -&self
718    }
719}
720
721impl<T> Sum<T> for Ed25519
722where
723    T: core::borrow::Borrow<Ed25519>,
724{
725    fn sum<I>(iter: I) -> Self
726    where
727        I: Iterator<Item = T>,
728    {
729        iter.fold(Self::identity(), |acc, item| acc + item.borrow())
730    }
731}
732
733impl<'a, 'b> Add<&'a Ed25519> for &'b Ed25519 {
734    type Output = Ed25519;
735
736    fn add(self, rhs: &'a Ed25519) -> Ed25519 {
737        // We perform addition in the extended coordinates. Here we use
738        // a formula presented by Hisil, Wong, Carter and Dawson in
739        // "Twisted Edward Curves Revisited" which only requires 8M.
740        //
741        // A = (V1 - U1) * (V2 - U2)
742        // B = (V1 + U1) * (V2 + U2)
743        // C = 2d * T1 * T2
744        // D = 2 * Z1 * Z2
745        // E = B - A
746        // F = D - C
747        // G = D + C
748        // H = B + A
749        // U3 = E * F
750        // Y3 = G * H
751        // Z3 = F * G
752        // T3 = E * H
753
754        let a = (self.x - self.y) * (rhs.x - rhs.y);
755        let b = (self.x + self.y) * (rhs.x + rhs.y);
756        let c = (self.t * rhs.t * ED25519_D).double();
757        let d = (self.z * rhs.z).double();
758
759        let e = b - a;
760        let f = d - c;
761        let g = d + c;
762        let h = b + a;
763
764        Ed25519 {
765            x: e * f,
766            y: g * h,
767            z: f * g,
768            t: e * h,
769        }
770    }
771}
772
773impl<'a, 'b> Add<&'a Ed25519Affine> for &'b Ed25519 {
774    type Output = Ed25519;
775
776    fn add(self, rhs: &'a Ed25519Affine) -> Ed25519 {
777        self + rhs.to_extended()
778    }
779}
780
781impl<'a, 'b> Sub<&'a Ed25519> for &'b Ed25519 {
782    type Output = Ed25519;
783
784    fn sub(self, other: &'a Ed25519) -> Ed25519 {
785        self + (-other)
786    }
787}
788
789impl<'a, 'b> Sub<&'a Ed25519Affine> for &'b Ed25519 {
790    type Output = Ed25519;
791
792    fn sub(self, other: &'a Ed25519Affine) -> Ed25519 {
793        self + (-other)
794    }
795}
796
797#[allow(clippy::suspicious_arithmetic_impl)]
798impl<'a, 'b> Mul<&'b Fr> for &'a Ed25519 {
799    type Output = Ed25519;
800
801    // This is a simple double-and-add implementation of point
802    // multiplication, moving from most significant to least
803    // significant bit of the scalar.
804    //
805    // We skip the leading three bits because they're always
806    // unset for Fr.
807    fn mul(self, other: &'b Fr) -> Self::Output {
808        let mut acc = Ed25519::identity();
809        for bit in other
810            .to_repr()
811            .iter()
812            .rev()
813            .flat_map(|byte| (0..8).rev().map(move |i| Choice::from((byte >> i) & 1u8)))
814            .skip(3)
815        {
816            acc = acc.double();
817            acc = Ed25519::conditional_select(&acc, &(acc + self), bit);
818        }
819
820        acc
821    }
822}
823
824impl<'a> Neg for &'a Ed25519Affine {
825    type Output = Ed25519Affine;
826
827    fn neg(self) -> Ed25519Affine {
828        Ed25519Affine {
829            x: -self.x,
830            y: self.y,
831        }
832    }
833}
834
835impl Neg for Ed25519Affine {
836    type Output = Ed25519Affine;
837
838    fn neg(self) -> Ed25519Affine {
839        -&self
840    }
841}
842
843impl<'a, 'b> Add<&'a Ed25519> for &'b Ed25519Affine {
844    type Output = Ed25519;
845
846    fn add(self, rhs: &'a Ed25519) -> Ed25519 {
847        rhs + self
848    }
849}
850
851impl<'a, 'b> Add<&'a Ed25519Affine> for &'b Ed25519Affine {
852    type Output = Ed25519;
853
854    fn add(self, rhs: &'a Ed25519Affine) -> Ed25519 {
855        self.to_extended() + rhs.to_extended()
856    }
857}
858
859impl<'a, 'b> Sub<&'a Ed25519Affine> for &'b Ed25519Affine {
860    type Output = Ed25519;
861
862    fn sub(self, other: &'a Ed25519Affine) -> Ed25519 {
863        self + (-other)
864    }
865}
866
867impl<'a, 'b> Sub<&'a Ed25519> for &'b Ed25519Affine {
868    type Output = Ed25519;
869
870    fn sub(self, other: &'a Ed25519) -> Ed25519 {
871        self + (-other)
872    }
873}
874
875#[allow(clippy::suspicious_arithmetic_impl)]
876impl<'a, 'b> Mul<&'b Fr> for &'a Ed25519Affine {
877    type Output = Ed25519;
878
879    fn mul(self, other: &'b Fr) -> Self::Output {
880        let mut acc = Ed25519::identity();
881
882        // This is a simple double-and-add implementation of point
883        // multiplication, moving from most significant to least
884        // significant bit of the scalar.
885        //
886        // We skip the leading three bits because they're always
887        // unset for Fr.
888        for bit in other
889            .to_repr()
890            .iter()
891            .rev()
892            .flat_map(|byte| (0..8).rev().map(move |i| Choice::from((byte >> i) & 1u8)))
893        {
894            acc = acc.double();
895            acc = Ed25519::conditional_select(&acc, &(acc + self), bit);
896        }
897
898        acc
899    }
900}
901
902impl CurveAffineExt for Ed25519Affine {
903    fn into_coordinates(self) -> (Self::Base, Self::Base) {
904        (self.x, self.y)
905    }
906}
907
908pub trait TwistedEdwardsCurveExt: CurveExt {
909    fn a() -> <Self as CurveExt>::Base;
910    fn d() -> <Self as CurveExt>::Base;
911}
912
913impl TwistedEdwardsCurveExt for Ed25519 {
914    fn a() -> Fq {
915        -Fq::ONE
916    }
917
918    fn d() -> Fq {
919        ED25519_D
920    }
921}
922
923pub trait TwistedEdwardsCurveAffineExt: CurveAffineExt {
924    fn a() -> <Self as CurveAffine>::Base;
925    fn d() -> <Self as CurveAffine>::Base;
926}
927
928impl TwistedEdwardsCurveAffineExt for Ed25519Affine {
929    fn a() -> Fq {
930        -Fq::ONE
931    }
932
933    fn d() -> Fq {
934        ED25519_D
935    }
936}
937
938#[test]
939fn test_is_on_curve() {
940    assert!(bool::from(Ed25519Affine::identity().is_on_curve()));
941}
942
943#[test]
944fn test_d_is_non_quadratic_residue() {
945    assert!(bool::from(ED25519_D.sqrt().is_none()));
946    assert!(bool::from((-ED25519_D).sqrt().is_none()));
947    assert!(bool::from((-ED25519_D).invert().unwrap().sqrt().is_none()));
948}
949
950#[test]
951fn test_double() {
952    let p = Ed25519::generator();
953
954    assert_eq!(p.double(), p + p);
955}
956
957#[test]
958fn test_assoc() {
959    let p = Ed25519::from(Ed25519Affine {
960        x: Fq::from_raw([
961            0x4eb5_31fa_487c_0f3e,
962            0x1313_5118_1c90_b35e,
963            0xdb9a_afaf_f32a_26f7,
964            0x5e0c_b226_a2aa_bab4,
965        ]),
966        y: Fq::from_raw([
967            0xbf09_6275_684b_b8c9,
968            0xc7ba_2458_90af_256d,
969            0x5911_9f3e_8638_0eb0,
970            0x3793_de18_2f9f_b1d2,
971        ]),
972    })
973    .mul_by_cofactor();
974    assert!(bool::from(p.is_on_curve()));
975
976    assert_eq!(
977        (p * Fr::from(1000u64)) * Fr::from(3938u64),
978        p * (Fr::from(1000u64) * Fr::from(3938u64)),
979    );
980}
981
982#[test]
983fn test_curve() {
984    crate::tests::curve::curve_tests::<Ed25519>();
985}
986
987#[test]
988fn test_serialization() {
989    crate::tests::curve::random_serialization_test::<Ed25519>();
990}
991
992// #[test]
993// #[allow(non_snake_case)]
994// fn eddsa_example() {
995//     use crate::group::cofactor::CofactorGroup;
996//     use sha2::{Digest, Sha512};
997
998//     fn hash_to_fr(hash: Sha512) -> Fr {
999//         let mut output = [0u8; 64];
1000//         output.copy_from_slice(hash.finalize().as_slice());
1001
1002//         Fr::from_bytes_wide(&output)
1003//     }
1004
1005//     fn seed_to_key(seed: [u8; 32]) -> (Fr, [u8; 32], [u8; 32]) {
1006//         // Expand the seed to a 64-byte array with SHA512.
1007//         let h = Sha512::digest(&seed[..]);
1008
1009//         // Convert the low half to a scalar with Ed25519 "clamping"
1010//         let s = {
1011//             let mut scalar_bytes = [0u8; 32];
1012//             scalar_bytes[..].copy_from_slice(&h.as_slice()[0..32]);
1013//             // Clear the lowest three bits to make the scalar a multiple of 8
1014//             scalar_bytes[0] &= 248;
1015//             // Clear highest bit
1016//             scalar_bytes[31] &= 127;
1017//             // Set second highest bit to 1
1018//             scalar_bytes[31] |= 64;
1019
1020//             let mut scalar_bytes_wide = [0u8; 64];
1021//             scalar_bytes_wide[0..32].copy_from_slice(&scalar_bytes);
1022
1023//             Fr::from_bytes_wide(&scalar_bytes_wide)
1024//         };
1025
1026//         // Extract and cache the high half.
1027//         let prefix = {
1028//             let mut prefix = [0u8; 32];
1029//             prefix[..].copy_from_slice(&h.as_slice()[32..64]);
1030//             prefix
1031//         };
1032
1033//         // Compute the public key as A = [s]B.
1034//         let A = Ed25519::generator() * &s;
1035
1036//         let A_bytes = A.to_bytes().0;
1037
1038//         (s, prefix, A_bytes)
1039//     }
1040
1041//     fn sign(s: Fr, prefix: [u8; 32], A_bytes: [u8; 32], msg: &[u8]) -> ([u8; 32], [u8; 32]) {
1042//         let r = hash_to_fr(Sha512::default().chain(&prefix[..]).chain(msg));
1043
1044//         let R_bytes = (Ed25519::generator() * &r).to_bytes().0;
1045
1046//         let k = hash_to_fr(
1047//             Sha512::default()
1048//                 .chain(&R_bytes[..])
1049//                 .chain(&A_bytes[..])
1050//                 .chain(msg),
1051//         );
1052
1053//         let s_bytes = (r + s * k).to_bytes();
1054
1055//         (R_bytes, s_bytes)
1056//     }
1057
1058//     fn verify(R_bytes: [u8; 32], s_bytes: [u8; 32], A_bytes: [u8; 32], msg: &[u8]) -> Choice {
1059//         let k = hash_to_fr(
1060//             Sha512::default()
1061//                 .chain(&R_bytes[..])
1062//                 .chain(&A_bytes[..])
1063//                 .chain(msg),
1064//         );
1065//         verify_prehashed(R_bytes, s_bytes, A_bytes, k)
1066//     }
1067
1068//     fn verify_prehashed(R_bytes: [u8; 32], s_bytes: [u8; 32], A_bytes: [u8; 32], k: Fr) -> Choice {
1069//         // `R_bytes` MUST be an encoding of a point on the twisted Edwards form of Curve25519.
1070//         let R = Ed25519::from_bytes(&Ed25519Compressed(R_bytes)).unwrap();
1071//         // `s_bytes` MUST represent an integer less than the prime `l`.
1072//         let s = Fr::from_bytes(&s_bytes).unwrap();
1073//         // `A_bytes` MUST be an encoding of a point on the twisted Edwards form of Curve25519.
1074//         let A = Ed25519::from_bytes(&Ed25519Compressed(A_bytes)).unwrap();
1075
1076//         //       [8][s]B = [8]R + [8][k]A
1077//         // <=>   [8]R = [8][s]B - [8][k]A
1078//         // <=>   0 = [8](R - ([s]B - [k]A))
1079//         // <=>   0 = [8](R - R')  where R' = [s]B - [k]A
1080//         let R_prime = Ed25519::from(Ed25519::generator()) * s - A * k;
1081
1082//         (R - R_prime).clear_cofactor().is_identity()
1083//     }
1084
1085//     use rand_core::OsRng;
1086//     let mut rng = OsRng;
1087
1088//     for _ in 0..1000 {
1089//         // Generate a key pair
1090//         let mut seed = [0u8; 32];
1091//         rng.fill_bytes(&mut seed[..]);
1092
1093//         let (s, prefix, A_bytes) = seed_to_key(seed);
1094
1095//         // Generate a valid signature
1096//         // Suppose `m` is the message
1097//         let msg = b"test message";
1098
1099//         let (R_bytes, s_bytes) = sign(s, prefix, A_bytes, msg);
1100
1101//         // Verify the signature
1102//         assert!(bool::from(verify(R_bytes, s_bytes, A_bytes, msg)));
1103//     }
1104// }