libcrux_curve25519/
ecdh_api.rs

1pub use libcrux_traits::ecdh::{arrayref::EcdhArrayref, owned::EcdhOwned, slice::EcdhSlice};
2
3use crate::clamp;
4
5use super::{DK_LEN, EK_LEN, X25519};
6
7const RAND_LEN: usize = DK_LEN;
8const SECRET_LEN: usize = DK_LEN;
9const PUBLIC_LEN: usize = EK_LEN;
10
11use libcrux_secrets::{Classify, Declassify, DeclassifyRef, DeclassifyRefMut, U8};
12
13impl libcrux_traits::ecdh::arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN> for X25519 {
14    fn generate_secret(
15        secret: &mut [U8; SECRET_LEN],
16        rand: &[U8; RAND_LEN],
17    ) -> Result<(), libcrux_traits::ecdh::arrayref::GenerateSecretError> {
18        secret.copy_from_slice(rand);
19        clamp(secret.declassify_ref_mut());
20
21        Ok(())
22    }
23
24    fn secret_to_public(
25        public: &mut [u8; PUBLIC_LEN],
26        secret: &[U8; SECRET_LEN],
27    ) -> Result<(), libcrux_traits::ecdh::arrayref::SecretToPublicError> {
28        crate::hacl::secret_to_public(public, secret.declassify_ref());
29        Ok(())
30    }
31
32    fn derive_ecdh(
33        derived: &mut [U8; PUBLIC_LEN],
34        public: &[u8; PUBLIC_LEN],
35        secret: &[U8; SECRET_LEN],
36    ) -> Result<(), libcrux_traits::ecdh::arrayref::DeriveError> {
37        crate::hacl::ecdh(
38            derived.declassify_ref_mut().as_mut_slice(),
39            secret.declassify_ref().as_slice(),
40            public.as_ref(),
41        )
42        .then_some(())
43        .ok_or(libcrux_traits::ecdh::arrayref::DeriveError::Unknown)
44    }
45
46    fn validate_secret(
47        secret: &[U8; SECRET_LEN],
48    ) -> Result<(), libcrux_traits::ecdh::arrayref::ValidateSecretError> {
49        let mut all_zero = 0u8.classify();
50        for i in 0..SECRET_LEN {
51            all_zero |= secret[i];
52        }
53
54        (all_zero.declassify() != 0)
55            .then_some(())
56            .ok_or(libcrux_traits::ecdh::arrayref::ValidateSecretError::InvalidSecret)
57    }
58}
59
60libcrux_traits::ecdh::slice::impl_ecdh_slice_trait!(X25519 => RAND_LEN, SECRET_LEN, PUBLIC_LEN);