kyber_rs/group/edwards25519/
curve.rs

1use core::fmt::{Debug, Display, Formatter};
2
3use crate::cipher::StreamError;
4use crate::dh::Dh;
5use crate::group::edwards25519::Point;
6use crate::group::edwards25519::Scalar;
7use crate::group::Group;
8use crate::util::key::Generator;
9use crate::util::key::KeyError;
10use crate::util::random;
11
12use serde::Deserialize;
13use serde::Serialize;
14use sha2::Sha256;
15use sha2::{Digest, Sha512};
16use thiserror::Error;
17
18/// [`Curve`] represents the `Ed25519` [`group`](Group).
19/// There are no parameters and no initialization is required
20/// because it supports only this one specific curve.
21#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
22pub struct Curve {}
23
24impl Dh for Curve {
25    type H = Sha256;
26}
27
28impl Display for Curve {
29    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
30        write!(f, "Ed25519")
31    }
32}
33
34impl Group for Curve {
35    type POINT = Point;
36
37    /// [`scalar()`] creates a new scalar for the prime-order subgroup of the Ed25519 curve.
38    /// The scalars in this package implement scalar's [`set_bytes()`]
39    /// method, interpreting the bytes as a little-endian integer, in order to remain
40    /// compatible with other Ed25519 implementations, and with the standard implementation
41    /// of the EdDSA signature.
42    fn scalar(&self) -> Scalar {
43        Scalar::new()
44    }
45
46    /// [`scalar_len()`] returns 32, the size in bytes of an encoded [`Scalar`]
47    /// for the Ed25519 curve.
48    fn scalar_len(&self) -> usize {
49        32
50    }
51
52    fn point(&self) -> Point {
53        Point::new()
54    }
55
56    /// [`point_len()`] returns 32, the size in bytes of an encoded [`Point`] on the Ed25519 curve.
57    fn point_len(&self) -> usize {
58        32
59    }
60
61    fn is_prime_order(&self) -> Option<bool> {
62        None
63    }
64}
65
66impl Curve {
67    pub const fn new() -> Self {
68        Curve {}
69    }
70
71    /// [`new_key_and_seed_with_input()`] returns a formatted Ed25519 key (avoid subgroup attack by
72    /// requiring it to be a multiple of 8). It also returns the input and the digest used
73    /// to generate the key.
74    pub fn new_key_and_seed_with_input(self, buffer: &[u8]) -> (Scalar, &[u8], Vec<u8>) {
75        let mut hasher = Sha512::new();
76        hasher.update(buffer);
77
78        let mut digest = hasher.finalize();
79        digest[0] &= 0xf8;
80        digest[31] &= 0x7f;
81        digest[31] |= 0x40;
82
83        let mut secret = self.scalar();
84        secret.v.copy_from_slice(&digest[0..32]);
85
86        (secret, buffer, digest[32..].to_vec())
87    }
88
89    /// [`new_key_and_seed()`] returns a formatted Ed25519 key (avoid subgroup attack by requiring
90    /// it to be a multiple of 8). It also returns the seed and the input used to generate
91    /// the key.
92    pub fn new_key_and_seed<S: crate::cipher::Stream>(
93        self,
94        stream: &mut S,
95    ) -> Result<(Scalar, Vec<u8>, Vec<u8>), CurveError> {
96        let mut buffer = vec![0u8; 32];
97        random::bytes(&mut buffer, stream)?;
98        let (sc, buff, digest) = self.new_key_and_seed_with_input(&buffer);
99
100        Ok((sc, buff.to_vec(), digest))
101    }
102}
103
104impl Generator<Scalar> for Curve {
105    /// [`new_key()`] returns a formatted Ed25519 key (avoiding subgroup attack by requiring
106    /// it to be a multiple of 8). [`new_key()`] implements the [`Generator`] trait.
107    fn new_key<S: crate::cipher::Stream>(
108        &self,
109        stream: &mut S,
110    ) -> Result<Option<Scalar>, KeyError> {
111        let (secret, _, _) = self.new_key_and_seed(stream)?;
112        Ok(Some(secret))
113    }
114}
115
116impl Default for Curve {
117    fn default() -> Self {
118        Curve::new()
119    }
120}
121
122#[derive(Error, Debug)]
123pub enum CurveError {
124    #[error("stream error")]
125    StreamError(#[from] StreamError),
126}