use core::num::NonZeroUsize;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
pub mod consts {
pub use generic_array::typenum::*;
}
pub type Key<T> = GenericArray<u8, <T as Aead>::KeyLength>;
pub type Nonce<T> = GenericArray<u8, <T as Aead>::NonceLength>;
pub type Tag<T> = GenericArray<u8, <T as Aead>::TagLength>;
pub trait Aead {
type KeyLength: ArrayLength<u8>;
type NonceLength: ArrayLength<u8>;
type TagLength: ArrayLength<u8>;
const NAME: &'static str;
const KEY_LENGTH: usize = <Self::KeyLength as Unsigned>::USIZE;
const NONCE_LENGTH: usize = <Self::NonceLength as Unsigned>::USIZE;
const TAG_LENGTH: usize = <Self::TagLength as Unsigned>::USIZE;
fn encrypt(
key: &Key<Self>,
nonce: &Nonce<Self>,
associated_data: &[u8],
plaintext: &[u8],
ciphertext: &mut [u8],
tag: &mut Tag<Self>,
) -> crate::Result<usize>;
fn decrypt(
key: &Key<Self>,
nonce: &Nonce<Self>,
associated_data: &[u8],
plaintext: &mut [u8],
ciphertext: &[u8],
tag: &Tag<Self>,
) -> crate::Result<usize>;
fn try_encrypt(
key: &[u8],
nonce: &[u8],
associated_data: &[u8],
plaintext: &[u8],
ciphertext: &mut [u8],
tag: &mut [u8],
) -> crate::Result<usize> {
let key: &Key<Self> = try_generic_array(key, "key")?;
let nonce: &Nonce<Self> = try_generic_array(nonce, "nonce")?;
let tag: &mut Tag<Self> = try_generic_array_mut(tag, "tag")?;
Self::encrypt(key, nonce, associated_data, plaintext, ciphertext, tag)
}
fn try_decrypt(
key: &[u8],
nonce: &[u8],
associated_data: &[u8],
plaintext: &mut [u8],
ciphertext: &[u8],
tag: &[u8],
) -> crate::Result<usize> {
let key: &Key<Self> = try_generic_array(key, "key")?;
let nonce: &Nonce<Self> = try_generic_array(nonce, "nonce")?;
let tag: &Tag<Self> = try_generic_array(tag, "tag")?;
Self::decrypt(key, nonce, associated_data, plaintext, ciphertext, tag)
}
#[cfg(feature = "random")]
fn random_nonce() -> crate::Result<Nonce<Self>> {
let mut nonce: Nonce<Self> = Default::default();
crate::utils::rand::fill(&mut nonce)?;
Ok(nonce)
}
fn padsize(_: &[u8]) -> Option<NonZeroUsize> {
None
}
}
#[inline(always)]
fn try_generic_array<'a, T>(slice: &'a [u8], name: &'static str) -> crate::Result<&'a GenericArray<u8, T>>
where
T: ArrayLength<u8>,
{
if slice.len() == T::USIZE {
Ok(slice.into())
} else {
Err(crate::Error::BufferSize {
name,
needs: T::USIZE,
has: slice.len(),
})
}
}
#[inline(always)]
fn try_generic_array_mut<'a, T>(slice: &'a mut [u8], name: &'static str) -> crate::Result<&'a mut GenericArray<u8, T>>
where
T: ArrayLength<u8>,
{
if slice.len() == T::USIZE {
Ok(slice.into())
} else {
Err(crate::Error::BufferSize {
name,
needs: T::USIZE,
has: slice.len(),
})
}
}