use chacha20poly1305::aead::{Aead, Payload};
use chacha20poly1305::{ChaCha20Poly1305, Key, KeyInit, Nonce};
use crate::error::EncryptionError;
use crate::NoiseNonce;
pub type SharedSecret = [u8; 32];
fn _nonce(nonce: NoiseNonce) -> Nonce {
let mut chacha_nonce = [0u8; 12];
chacha_nonce[4..].copy_from_slice(&nonce.to_le_bytes());
*Nonce::from_slice(&chacha_nonce[..])
}
fn _cypher(key: &[u8]) -> ChaCha20Poly1305 {
let key = Key::from_slice(key);
ChaCha20Poly1305::new(key)
}
pub(crate) fn encrypt(
key: SharedSecret,
nonce: NoiseNonce,
associated_data: &[u8],
plaintext: &[u8],
) -> Result<Vec<u8>, EncryptionError> {
if plaintext.is_empty() {
return Ok(vec![]);
}
let payload = Payload {
msg: plaintext,
aad: associated_data,
};
_cypher(key.as_ref()).encrypt(&_nonce(nonce), payload).map_err(EncryptionError::from)
}
pub(crate) fn decrypt(
key: SharedSecret,
nonce: NoiseNonce,
associated_data: &[u8],
ciphertext: &[u8],
) -> Result<Vec<u8>, EncryptionError> {
if ciphertext.is_empty() {
return Ok(vec![]);
}
let payload = Payload {
msg: ciphertext,
aad: associated_data,
};
_cypher(key.as_ref()).decrypt(&_nonce(nonce), payload).map_err(EncryptionError::from)
}
pub(crate) fn rekey(k: SharedSecret) -> SharedSecret {
let key = encrypt(k, u64::MAX, &[], &[0u8; 32]).expect("error re-keying");
let mut buf = [0u8; 32];
buf.copy_from_slice(&key);
buf
}