use crate::EciesError;
use hkdf::Hkdf;
use sha2::Sha256;
pub trait Key {
const EC_PUBLIC_KEY_LEN: usize;
type SecretKey;
fn as_bytes(&self) -> Vec<u8>;
fn from_bytes(x: &[u8]) -> Self;
}
pub trait KeyExchange: Key {
fn key_exchange(&self, sk: &Self::SecretKey) -> Vec<u8>;
}
pub trait GenerateEphemeralKey: Key + Sized {
fn get_ephemeral_key() -> (Self, Self::SecretKey);
}
impl<K: Key> TakeEphemeralKey for K {}
pub trait TakeEphemeralKey: Key + Sized {
fn get_ephemeral_key(x: &mut Vec<u8>) -> Result<Self, EciesError> {
if x.len() < Self::EC_PUBLIC_KEY_LEN {
return Err(EciesError::BadData);
}
Ok(Self::from_bytes(
&x.drain(..Self::EC_PUBLIC_KEY_LEN).collect::<Vec<u8>>(),
))
}
}
impl<K: Key> DeriveKeyMaterial for K {}
pub trait DeriveKeyMaterial: Key {
fn derive_key_material(&self, mut shared_secret: Vec<u8>, len: usize) -> Vec<u8> {
shared_secret.extend_from_slice(&self.as_bytes());
let hkdf = Hkdf::<Sha256>::new(None, shared_secret.as_slice());
let mut out = vec![0u8; len];
hkdf.expand(b"", &mut out)
.expect("Could not derive enough Key Material");
out.to_vec()
}
}