Add generic SymmetricKey container

This commit is contained in:
Jazz Turner-Baggs 2026-02-12 15:06:04 -08:00
parent 3b69f946fd
commit 14535369fd
No known key found for this signature in database
2 changed files with 39 additions and 24 deletions

View File

@ -39,7 +39,7 @@ struct BaseConvoId([u8; 18]);
impl BaseConvoId {
fn new(key: &SecretKey) -> Self {
let base = Blake2bMac::<U18>::new_with_salt_and_personal(key.as_slice(), b"", b"L-PV1-CID")
let base = Blake2bMac::<U18>::new_with_salt_and_personal(key.as_bytes(), b"", b"L-PV1-CID")
.expect("fixed inputs should never fail");
Self(base.finalize_fixed().into())
}
@ -87,7 +87,7 @@ impl PrivateV1Convo {
let remote_convo_id = base_convo_id.id_for_participant(Role::Initiator);
// TODO: Danger - Fix double-ratchets types to Accept SecretKey
let dr_state = RatchetState::init_receiver(seed_key.as_bytes().to_owned(), dh_self);
let dr_state = RatchetState::init_receiver(seed_key.DANGER_to_bytes(), dh_self);
Self {
local_convo_id,
@ -234,14 +234,11 @@ mod tests {
let seed_key = saro.diffie_hellman(&pub_raya);
let send_content_bytes = vec![0, 2, 4, 6, 8];
let mut sr_convo =
PrivateV1Convo::new_initiator(SecretKey::from(seed_key.to_bytes()), pub_raya);
let mut sr_convo = PrivateV1Convo::new_initiator(SymmetricKey32::from(&seed_key), pub_raya);
let installation_key_pair = InstallationKeyPair::from(raya);
let mut rs_convo = PrivateV1Convo::new_responder(
SecretKey::from(seed_key.to_bytes()),
installation_key_pair,
);
let mut rs_convo =
PrivateV1Convo::new_responder(SymmetricKey32::from(&seed_key), installation_key_pair);
let send_frame = PrivateV1Frame {
conversation_id: "_".into(),

View File

@ -1,35 +1,53 @@
use std::fmt::Debug;
pub use generic_array::{GenericArray, typenum::U32};
use x25519_dalek::SharedSecret;
use zeroize::{Zeroize, ZeroizeOnDrop};
/// A Generic secret key container for symmetric keys.
/// SymmetricKey retains ownership of bytes to ensure they are Zeroized on drop.
#[derive(Clone, Zeroize, ZeroizeOnDrop, PartialEq)]
pub struct SecretKey([u8; 32]);
pub struct SymmetricKey<const N: usize>([u8; N]);
impl SecretKey {
pub fn as_slice(&self) -> &[u8] {
impl<const N: usize> SymmetricKey<N> {
pub fn as_bytes(&self) -> &[u8] {
self.0.as_slice()
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
/// Returns internal [u8; N].
/// This function by passes zeroize_on_drop, and will be deprecated once all consumers have been migrated
#[allow(nonstandard_style)]
pub fn DANGER_to_bytes(self) -> [u8; N] {
// TODO: (P3) Remove once DR ported to use safe keys.
self.0
}
}
impl From<[u8; 32]> for SecretKey {
fn from(value: [u8; 32]) -> Self {
SecretKey(value)
impl<const N: usize> From<[u8; N]> for SymmetricKey<N> {
fn from(value: [u8; N]) -> Self {
SymmetricKey(value)
}
}
impl From<GenericArray<u8, U32>> for SecretKey {
fn from(value: GenericArray<u8, U32>) -> Self {
SecretKey(value.into())
}
}
impl Debug for SecretKey {
impl<const N: usize> Debug for SymmetricKey<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SecretKey").field(&"<32 bytes>").finish()
write!(f, "SymmetricKey(...{N} Bytes Redacted...)")
}
}
// TODO: (P5) look into typenum::generic_const_mappings to avoid having to implment From<U>
pub type SymmetricKey32 = SymmetricKey<32>;
impl From<GenericArray<u8, U32>> for SymmetricKey32 {
fn from(value: GenericArray<u8, U32>) -> Self {
SymmetricKey(value.into())
}
}
impl From<&SharedSecret> for SymmetricKey32 {
// This relies on the feature 'zeroize' being set for x25519-dalek.
// If not the SharedSecret will need to manually zeroized
fn from(value: &SharedSecret) -> Self {
value.to_bytes().into()
}
}