use super::arrayref;
use super::arrayref::{DeriveError, GenerateSecretError, SecretToPublicError, ValidateSecretError};
use libcrux_secrets::{Classify, U8};
pub trait EcdhOwned<const RAND_LEN: usize, const SECRET_LEN: usize, const PUBLIC_LEN: usize> {
fn generate_secret(rand: &[U8; RAND_LEN]) -> Result<[U8; SECRET_LEN], GenerateSecretError>;
fn secret_to_public(secret: &[U8; SECRET_LEN])
-> Result<[u8; PUBLIC_LEN], SecretToPublicError>;
fn generate_pair(
rand: &[U8; RAND_LEN],
) -> Result<([u8; PUBLIC_LEN], [U8; SECRET_LEN]), GenerateSecretError> {
let secret = Self::generate_secret(rand)?;
let public = Self::secret_to_public(&secret).map_err(|_| GenerateSecretError::Unknown)?;
Ok((public, secret))
}
fn derive_ecdh(
public: &[u8; PUBLIC_LEN],
secret: &[U8; SECRET_LEN],
) -> Result<[U8; PUBLIC_LEN], DeriveError>;
fn validate_secret(secret: &[U8; SECRET_LEN]) -> Result<(), ValidateSecretError>;
}
impl<
const RAND_LEN: usize,
const SECRET_LEN: usize,
const PUBLIC_LEN: usize,
T: arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN>,
> EcdhOwned<RAND_LEN, SECRET_LEN, PUBLIC_LEN> for T
{
fn generate_secret(rand: &[U8; RAND_LEN]) -> Result<[U8; SECRET_LEN], GenerateSecretError> {
let mut secret = [0u8; SECRET_LEN].classify();
<Self as arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN>>::generate_secret(
&mut secret,
rand,
)?;
Ok(secret)
}
fn secret_to_public(
secret: &[U8; SECRET_LEN],
) -> Result<[u8; PUBLIC_LEN], SecretToPublicError> {
let mut public = [0u8; PUBLIC_LEN];
<Self as arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN>>::secret_to_public(
&mut public,
secret,
)?;
Ok(public)
}
fn derive_ecdh(
public: &[u8; PUBLIC_LEN],
secret: &[U8; SECRET_LEN],
) -> Result<[U8; PUBLIC_LEN], DeriveError> {
let mut derived = [0u8; PUBLIC_LEN].classify();
<Self as arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN>>::derive_ecdh(
&mut derived,
public,
secret,
)?;
Ok(derived)
}
fn validate_secret(secret: &[U8; SECRET_LEN]) -> Result<(), ValidateSecretError> {
<Self as arrayref::EcdhArrayref<RAND_LEN, SECRET_LEN, PUBLIC_LEN>>::validate_secret(secret)
}
}