use alloc::vec::Vec;
use hkdf::Hkdf;
use sha2::Sha256;
use zeroize::Zeroizing;
use crate::error::ProfileError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PartyIdentity(Option<Vec<u8>>);
impl PartyIdentity {
#[must_use]
pub const fn nil() -> Self {
Self(None)
}
pub fn from_bytes(identity: Vec<u8>) -> Result<Self, ProfileError> {
if identity.is_empty() {
return Err(ProfileError::EmptyPartyIdentity);
}
Ok(Self(Some(identity)))
}
#[must_use]
pub fn as_bytes(&self) -> Option<&[u8]> {
self.0.as_deref()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KdfParties {
pub party_u: PartyIdentity,
pub party_v: PartyIdentity,
}
impl KdfParties {
#[must_use]
pub const fn anonymous() -> Self {
Self {
party_u: PartyIdentity::nil(),
party_v: PartyIdentity::nil(),
}
}
#[must_use]
pub const fn is_anonymous(&self) -> bool {
self.party_u.0.is_none() && self.party_v.0.is_none()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KdfFailed;
pub fn derive_cek(
shared_secret: &Zeroizing<[u8; 32]>,
kdf_context: &[u8],
) -> Result<Zeroizing<[u8; 32]>, KdfFailed> {
let hk = Hkdf::<Sha256>::new(None, shared_secret.as_slice());
let mut okm = Zeroizing::new([0u8; 32]);
hk.expand(kdf_context, okm.as_mut_slice())
.map_err(|_| KdfFailed)?;
Ok(okm)
}