use chacha20poly1305::{aead::KeyInit, AeadInPlace, Tag, XChaCha20Poly1305, XNonce};
use crate::v1::utils::EMPTY_BYTES;
use super::utils::{generate_nonce, CHACHA_NONCE_LENGTH, CHACHA_NONCE_PLUS_TAG_LENGTH};
pub async fn encrypt(data: &[u8], key: &[u8]) -> Option<Vec<u8>> {
let aead = XChaCha20Poly1305::new(key.as_ref().into());
let nonce = generate_nonce();
let mut out = Vec::with_capacity(data.len());
out.extend(data);
match aead.encrypt_in_place_detached(&nonce, &EMPTY_BYTES, &mut out) {
Ok(tag) => {
let mut output = Vec::with_capacity(CHACHA_NONCE_PLUS_TAG_LENGTH + data.len());
output.extend(nonce);
output.extend(tag);
output.extend(out);
Some(output)
}
Err(_) => return None,
}
}
pub async fn decrypt(data: &[u8], key: &[u8]) -> Option<Vec<u8>> {
if data.len() < CHACHA_NONCE_PLUS_TAG_LENGTH {
return None;
}
let aead = XChaCha20Poly1305::new(key.as_ref().into());
let nonce = XNonce::from_slice(&data[..CHACHA_NONCE_LENGTH]);
let tag = Tag::from_slice(&data[CHACHA_NONCE_LENGTH..CHACHA_NONCE_PLUS_TAG_LENGTH]);
let mut out = Vec::with_capacity(data.len() - CHACHA_NONCE_PLUS_TAG_LENGTH);
out.extend(&data[CHACHA_NONCE_PLUS_TAG_LENGTH..]);
match aead.decrypt_in_place_detached(nonce.into(), &EMPTY_BYTES, &mut out, tag) {
Ok(_) => Some(out),
Err(_) => None,
}
}