use crate::Result;
use rand::{CryptoRng, RngCore};
use zeroize::Zeroize;
pub trait Operation<T> {
fn execute(self) -> Result<T>;
}
pub trait EncryptOperation<'a, C: SymmetricCipher>: Operation<C::Ciphertext> {
fn with_nonce(self, nonce: &'a C::Nonce) -> Self;
fn with_aad(self, aad: &'a [u8]) -> Self;
fn encrypt(self, plaintext: &'a [u8]) -> Result<C::Ciphertext>;
}
pub trait DecryptOperation<'a, C: SymmetricCipher>: Operation<Vec<u8>> {
fn with_nonce(self, nonce: &'a C::Nonce) -> Self;
fn with_aad(self, aad: &'a [u8]) -> Self;
fn decrypt(self, ciphertext: &'a C::Ciphertext) -> Result<Vec<u8>>;
}
pub trait SymmetricCipher: Sized {
type Key: Zeroize + AsRef<[u8]> + AsMut<[u8]> + Clone;
type Nonce: AsRef<[u8]> + AsMut<[u8]> + Clone;
type Ciphertext: AsRef<[u8]> + AsMut<[u8]> + Clone;
type EncryptOperation<'a>: EncryptOperation<'a, Self>
where
Self: 'a;
type DecryptOperation<'a>: DecryptOperation<'a, Self>
where
Self: 'a;
fn name() -> &'static str;
fn encrypt(&self) -> Self::EncryptOperation<'_>;
fn decrypt(&self) -> Self::DecryptOperation<'_>;
fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Result<Self::Key>;
fn generate_nonce<R: RngCore + CryptoRng>(rng: &mut R) -> Result<Self::Nonce>;
fn derive_key_from_bytes(bytes: &[u8]) -> Result<Self::Key>;
}