mod ring_aead;
mod sodium_aead;
mod sodium_stream;
pub use ring_aead::*;
pub use sodium_aead::*;
pub use sodium_stream::*;
use crate::{Result, SecretBytes};
pub trait Algorithm {
fn header_size(&self) -> u64;
fn content_size(&self) -> u64;
fn tag_size(&self) -> u64;
fn key_size(&self) -> usize;
fn key(&self, key: SecretBytes) -> Result<Box<dyn AlgoKey + Send + Sync>>;
#[inline]
fn block_size(&self) -> u64 {
self.header_size() + self.content_size() + self.tag_size()
}
#[inline]
fn metadata_size(&self) -> u64 {
self.header_size() + self.tag_size()
}
fn plaintext_size(&self, ciphertext_size: u64) -> u64 {
let metadata_size = self.metadata_size();
let content_size = self.content_size();
let blocks = ciphertext_size / (content_size + metadata_size);
let rem = ciphertext_size % (content_size + metadata_size);
blocks * content_size + rem.saturating_sub(metadata_size)
}
fn ciphertext_size(&self, plaintext_size: u64) -> u64 {
let metadata_size = self.metadata_size();
let block_size = self.content_size();
let blocks = plaintext_size / block_size;
let rem = plaintext_size % block_size;
blocks * (block_size + metadata_size) + if rem == 0 { 0 } else { metadata_size + rem }
}
}
pub trait AlgoKey {
fn encrypt(&self, block: u64, buffer: &mut [u8]) -> Result<()>;
fn decrypt(&self, block: u64, buffer: &mut [u8]) -> Result<()>;
}
pub(crate) fn is_nil(bytes: &[u8]) -> bool {
bytes.iter().all(|&b| b == 0)
}