use crate::{auth_tag::*, easy::*, nonce::*};
#[doc = include_str!("rustdoc/easy_encrypt.md")]
#[cfg(feature = "rand")] pub fn encrypt(
plaintext: Plaintext,
associated_data: AssociatedData,
key: &Key256,
) -> Result<Vec<u8>> {
let pt_len = plaintext.as_bytes().len();
let payload_len = pt_len + Nonce256::BYTES + AuthTag256::BYTES;
if payload_len > isize::MAX as usize {
return Err(Error::InputBufferWrongSize);
}
let mut encrypted_payload = vec![0; payload_len];
let raw_nonce = Nonce256::generate()?.into_array();
encrypted_payload[..Nonce256::BYTES].copy_from_slice(&raw_nonce);
let ct_end = pt_len + Nonce256::BYTES;
let buffer_slice = &mut encrypted_payload[Nonce256::BYTES..ct_end];
let tag = crate::careful::aegis256x4::encrypt_to_slice_detached::<AuthTag256>(
plaintext,
associated_data,
key,
Nonce::new(raw_nonce)?,
CiphertextMut::new(buffer_slice),
)?;
encrypted_payload[ct_end..].copy_from_slice(tag.as_ref());
Ok(encrypted_payload)
}
#[allow(clippy::missing_panics_doc, reason = "Can't actually panic.")]
#[doc = include_str!("rustdoc/easy_decrypt.md")]
pub fn decrypt(
encrypted_payload: Ciphertext,
associated_data: AssociatedData,
key: &Key256,
) -> Result<Vec<u8>> {
let payload_len = encrypted_payload.as_bytes().len();
let Some(pt_len) =
payload_len.checked_sub(Nonce256::BYTES + AuthTag256::BYTES)
else {
return Err(Error::InputBufferWrongSize);
};
let nonce_slice = &encrypted_payload.as_bytes()[..Nonce256::BYTES];
let nonce = Nonce::new(
*nonce_slice
.as_array()
.expect("slice was created from correct byte range"),
)?;
let auth_tag_start = payload_len - AuthTag256::BYTES;
let tag_slice = &encrypted_payload.as_bytes()[auth_tag_start..];
let tag: AuthTag256 = *tag_slice
.as_array()
.expect("slice was created from correct byte range");
let ct_slice = &encrypted_payload.as_bytes()[Nonce256::BYTES..auth_tag_start];
let mut plaintext = vec![0; pt_len];
crate::careful::aegis256x4::decrypt_to_slice_detached(
Ciphertext::new(ct_slice),
&tag,
associated_data,
key,
nonce,
PlaintextMut::new(&mut plaintext),
)?;
Ok(plaintext)
}
macro_rules! gen_aegis_facade_fns {
($algo:ident) => {
use crate::auth_tag::*;
use crate::easy::*;
type Key = crate::facade::aegis_key_type!($algo);
type Nonce = crate::facade::aegis_nonce_type!($algo);
#[doc = include_str!("rustdoc/encrypt.md")]
pub fn encrypt<Tag: AuthTag>(
plaintext: Plaintext,
associated_data: AssociatedData,
key: &Key,
nonce: Nonce,
) -> Result<Vec<u8>> {
let pt_len = plaintext.as_bytes().len();
let ct_with_tag_len = pt_len + size_of::<Tag>();
if ct_with_tag_len > isize::MAX as usize {
return Err(Error::InputBufferWrongSize);
}
let mut ciphertext_with_tag = vec![0; ct_with_tag_len];
let ciphertext_slice = &mut ciphertext_with_tag[..pt_len];
let tag = encrypt_to_slice_detached::<Tag>(
plaintext,
associated_data,
key,
nonce,
CiphertextMut::new(ciphertext_slice),
)?;
ciphertext_with_tag[pt_len..].copy_from_slice(tag.as_ref());
Ok(ciphertext_with_tag)
}
#[doc = include_str!("rustdoc/decrypt.md")]
pub fn decrypt<Tag: AuthTag>(
ciphertext_with_tag: Ciphertext,
associated_data: AssociatedData,
key: &Key,
nonce: Nonce,
) -> Result<Vec<u8>> {
let ct_len = ciphertext_with_tag.as_bytes().len();
let Some(pt_len) = ct_len.checked_sub(Tag::BYTES) else {
return Err(Error::InputBufferWrongSize);
};
let ciphertext_slice = &ciphertext_with_tag.as_bytes()[..pt_len];
let tag_slice = &ciphertext_with_tag.as_bytes()[pt_len..];
let mut tag = Tag::default();
tag.as_mut().copy_from_slice(tag_slice);
decrypt_detached(
Ciphertext::new(ciphertext_slice),
&tag,
associated_data,
key,
nonce,
)
}
#[doc = include_str!("rustdoc/encrypt_detached.md")]
pub fn encrypt_detached<Tag: AuthTag>(
plaintext: Plaintext,
associated_data: AssociatedData,
key: &Key,
nonce: Nonce,
) -> Result<(Vec<u8>, Tag)> {
let mut ciphertext = vec![0; plaintext.as_bytes().len()];
let tag = encrypt_to_slice_detached(
plaintext,
associated_data,
key,
nonce,
CiphertextMut::new(&mut ciphertext),
)?;
Ok((ciphertext, tag))
}
#[doc = include_str!("rustdoc/decrypt_detached.md")]
pub fn decrypt_detached<Tag: AuthTag>(
ciphertext: Ciphertext,
auth_tag: &Tag,
associated_data: AssociatedData,
key: &Key,
nonce: Nonce,
) -> Result<Vec<u8>> {
let mut plaintext = vec![0; ciphertext.as_bytes().len()];
decrypt_to_slice_detached(
ciphertext,
auth_tag,
associated_data,
key,
nonce,
PlaintextMut::new(&mut plaintext),
)?;
Ok(plaintext)
}
};
}
pub(crate) use gen_aegis_facade_fns;
macro_rules! aegis_key_type {
(aegis128l) => {
crate::easy::Key128
};
(aegis128x2) => {
crate::easy::Key128
};
(aegis128x4) => {
crate::easy::Key128
};
(aegis256) => {
crate::easy::Key256
};
(aegis256x2) => {
crate::easy::Key256
};
(aegis256x4) => {
crate::easy::Key256
};
}
pub(crate) use aegis_key_type;
macro_rules! aegis_nonce_type {
(aegis128l) => {
crate::careful::Nonce128
};
(aegis128x2) => {
crate::careful::Nonce128
};
(aegis128x4) => {
crate::careful::Nonce128
};
(aegis256) => {
crate::careful::Nonce256
};
(aegis256x2) => {
crate::careful::Nonce256
};
(aegis256x4) => {
crate::careful::Nonce256
};
}
pub(crate) use aegis_nonce_type;