use chacha20poly1305::aead::{Aead, OsRng};
use chacha20poly1305::{AeadCore, Key, KeyInit, XChaCha20Poly1305, XNonce};
use super::{ClusterKey, AEAD_NONCE_LEN, AEAD_TAG_LEN};
fn cipher(key: &ClusterKey) -> XChaCha20Poly1305 {
XChaCha20Poly1305::new(Key::from_slice(key.as_bytes()))
}
pub(super) fn seal(key: &ClusterKey, payload: &[u8]) -> Vec<u8> {
let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
let ciphertext = cipher(key)
.encrypt(&nonce, payload)
.expect("XChaCha20-Poly1305 encryption of a datagram-sized payload cannot fail");
let mut framed = Vec::with_capacity(AEAD_NONCE_LEN + ciphertext.len());
framed.extend_from_slice(nonce.as_slice());
framed.extend_from_slice(&ciphertext);
framed
}
pub(super) fn open(key: &ClusterKey, datagram: &[u8]) -> Option<Vec<u8>> {
if datagram.len() < AEAD_NONCE_LEN + AEAD_TAG_LEN {
return None;
}
let (nonce, ciphertext) = datagram.split_at(AEAD_NONCE_LEN);
cipher(key)
.decrypt(XNonce::from_slice(nonce), ciphertext)
.ok()
}