use x25519_dalek::{x25519, PublicKey, StaticSecret};
use zeroize::{Zeroize, ZeroizeOnDrop};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct X25519PublicKey(pub [u8; 32]);
impl X25519PublicKey {
pub const LEN: usize = 32;
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct X25519SecretKey([u8; 32]);
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct X25519SharedSecret([u8; 32]);
impl X25519SecretKey {
pub const LEN: usize = 32;
pub const fn new(scalar: [u8; 32]) -> Self {
Self(scalar)
}
pub(crate) fn cloned(&self) -> Self {
Self(self.0)
}
pub(crate) fn secret_bytes(&self) -> &[u8; 32] {
&self.0
}
}
impl X25519SharedSecret {
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
pub fn x25519_diffie_hellman(
secret: &X25519SecretKey,
peer: &X25519PublicKey,
) -> X25519SharedSecret {
X25519SharedSecret(x25519(secret.0, peer.0))
}
pub fn x25519_public_key(secret: &X25519SecretKey) -> X25519PublicKey {
X25519PublicKey(*PublicKey::from(&StaticSecret::from(secret.0)).as_bytes())
}
pub fn x25519_keys_for_seal(
ephemeral_secret: &X25519SecretKey,
dh_target: &X25519PublicKey,
) -> (X25519PublicKey, X25519SharedSecret) {
(
x25519_public_key(ephemeral_secret),
x25519_diffie_hellman(ephemeral_secret, dh_target),
)
}