use chacha20poly1305::aead::{Aead, NewAead, Payload};
use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
use crate::noise::EncryptionError;
pub const TAG_SIZE: usize = 16;
pub fn encrypt(
key: &[u8],
nonce: u64,
associated_data: &[u8],
plaintext: &[u8],
cipher_text: &mut [u8],
) -> Result<(), EncryptionError> {
let mut chacha_nonce = [0u8; 12];
chacha_nonce[4..].copy_from_slice(&nonce.to_le_bytes());
let nonce = Nonce::from_slice(&chacha_nonce[..]);
let key = Key::from_slice(key);
let cipher = ChaCha20Poly1305::new(key);
let payload = Payload {
msg: plaintext,
aad: associated_data,
};
let encrypted = cipher.encrypt(nonce, payload)?;
if cipher_text.len() != encrypted.len() {
return Err(EncryptionError::ExpectedMessageLenMismatch);
}
cipher_text.copy_from_slice(&encrypted[..]);
Ok(())
}
pub fn decrypt(
key: &[u8],
nonce: u64,
associated_data: &[u8],
ciphertext: &[u8],
plain_text: &mut [u8],
) -> Result<(), EncryptionError> {
let mut chacha_nonce = [0u8; 12];
chacha_nonce[4..].copy_from_slice(&nonce.to_le_bytes());
let nonce = Nonce::from_slice(&chacha_nonce[..]);
let key = Key::from_slice(key);
let cipher = ChaCha20Poly1305::new(key);
let payload = Payload {
msg: ciphertext,
aad: associated_data,
};
let decrypted = cipher.decrypt(nonce, payload)?;
if plain_text.len() != decrypted.len() {
return Err(EncryptionError::ExpectedMessageLenMismatch);
}
plain_text.copy_from_slice(&decrypted[..]);
Ok(())
}
#[cfg(test)]
mod test {
use chacha20poly1305::aead::{Aead, NewAead};
use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
use crate::chacha20poly1305::aead::AeadInPlace;
#[test]
fn test1() {
let key = Key::from_slice(b"an example very very secret key."); let cipher = ChaCha20Poly1305::new(key);
let nonce = Nonce::from_slice(b"unique nonce");
let ciphertext = cipher
.encrypt(nonce, b"plaintext message".as_ref())
.expect("encryption failure!"); let plaintext = cipher
.decrypt(nonce, ciphertext.as_ref())
.expect("decryption failure!");
assert_eq!(&plaintext, b"plaintext message");
}
#[test]
fn test2() {
let key = Key::from_slice(b"an example very very secret key.");
let cipher = ChaCha20Poly1305::new(key);
let nonce = Nonce::from_slice(b"unique nonce");
let mut buffer: Vec<u8> = Vec::new();
buffer.extend_from_slice(b"plaintext message");
cipher
.encrypt_in_place(nonce, b"", &mut buffer)
.expect("encryption failure!");
assert_ne!(&buffer, b"plaintext message");
cipher
.decrypt_in_place(nonce, b"", &mut buffer)
.expect("decryption failure!");
assert_eq!(&buffer, b"plaintext message");
}
}