libcrux_curve25519/
ecdh_api.rs1pub 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);