use crate::crypto::{hmac::Hmac, sha256::Sha256, SecretKey};
use zeroize::Zeroize;
#[derive(Clone)]
pub struct NoiseContext {
chaining_key: [u8; 32],
state: [u8; 32],
}
impl Drop for NoiseContext {
fn drop(&mut self) {
self.chaining_key.zeroize();
self.state.zeroize();
}
}
impl NoiseContext {
pub fn new(chaining_key: [u8; 32], state: [u8; 32]) -> Self {
Self {
chaining_key,
state,
}
}
pub fn chaining_key(&self) -> &[u8] {
&self.chaining_key
}
pub fn state(&self) -> &[u8] {
&self.state
}
pub fn mix_hash(&mut self, input: impl AsRef<[u8]>) -> &mut Self {
self.state = Sha256::new().update(self.state).update(input).finalize_new();
self
}
pub fn mix_key<S: SecretKey, P: AsRef<x25519_dalek::PublicKey>>(
&mut self,
secret_key: &S,
public_key: &P,
) -> [u8; 32] {
self.mix_key_from_shared_secret(&secret_key.diffie_hellman(public_key))
}
pub fn mix_key_from_shared_secret(&mut self, shared_secret: &[u8]) -> [u8; 32] {
let mut temp_key = Hmac::new(&self.chaining_key).update(shared_secret).finalize_new();
self.chaining_key = Hmac::new(&temp_key).update([0x01]).finalize_new();
let key = Hmac::new(&temp_key).update(self.chaining_key).update([0x02]).finalize_new();
temp_key.zeroize();
key
}
}