use crate::Result;
pub trait Algorithm {
const ID: &'static str;
const NAME: &'static str;
}
pub trait Digest: Algorithm + Clone + Default {
type Output: AsRef<[u8]> + AsMut<[u8]> + Copy;
const OUTPUT_LEN: usize;
const BLOCK_LEN: usize;
fn new() -> Self {
Self::default()
}
fn update(&mut self, data: &[u8]);
fn finalize(self) -> Self::Output;
fn digest(data: &[u8]) -> Self::Output {
let mut h = Self::new();
h.update(data);
h.finalize()
}
}
pub trait Xof: Algorithm + Clone + Default {
const BLOCK_LEN: usize;
fn update(&mut self, data: &[u8]);
fn finalize_xof(self, out: &mut [u8]);
}
pub trait Mac: Algorithm + Clone {
type Tag: AsRef<[u8]> + AsMut<[u8]> + Copy;
const TAG_LEN: usize;
fn new(key: &[u8]) -> Result<Self>
where
Self: Sized;
fn update(&mut self, data: &[u8]);
fn finalize(self) -> Self::Tag;
fn mac(key: &[u8], data: &[u8]) -> Result<Self::Tag>
where
Self: Sized,
{
let mut m = Self::new(key)?;
m.update(data);
Ok(m.finalize())
}
fn verify(key: &[u8], data: &[u8], tag: &[u8]) -> Result<()>
where
Self: Sized,
{
let expected = Self::mac(key, data)?;
if crate::ct::verify(expected.as_ref(), tag) {
Ok(())
} else {
Err(crate::err!(AuthenticationFailed, "mac tag"))
}
}
}
pub trait BlockCipher: Algorithm {
const BLOCK_LEN: usize;
const KEY_LEN: usize;
fn new(key: &[u8]) -> Result<Self>
where
Self: Sized;
fn encrypt_block(&self, block: &mut [u8]) -> Result<()>;
fn decrypt_block(&self, block: &mut [u8]) -> Result<()>;
fn encrypt_blocks(&self, data: &mut [u8]) -> Result<()> {
if data.len() % Self::BLOCK_LEN != 0 {
return Err(crate::err!(InvalidLength, "batch must be block-aligned"));
}
for block in data.chunks_mut(Self::BLOCK_LEN) {
self.encrypt_block(block)?;
}
Ok(())
}
}
pub trait Aead: Algorithm {
const KEY_LEN: usize;
const NONCE_LEN: usize;
const TAG_LEN: usize;
fn new(key: &[u8]) -> Result<Self>
where
Self: Sized;
fn seal_detached(
&self,
nonce: &[u8],
aad: &[u8],
in_out: &mut [u8],
tag: &mut [u8],
) -> Result<()>;
fn open_detached(&self, nonce: &[u8], aad: &[u8], in_out: &mut [u8], tag: &[u8]) -> Result<()>;
}
pub trait Kdf: Algorithm {
fn derive(secret: &[u8], salt: &[u8], info: &[u8], out: &mut [u8]) -> Result<()>;
}
pub trait Drbg: Algorithm {
fn instantiate(entropy: &[u8], nonce: &[u8], personalization: &[u8]) -> Result<Self>
where
Self: Sized;
fn reseed(&mut self, entropy: &[u8], additional: &[u8]) -> Result<()>;
fn generate(&mut self, additional: &[u8], out: &mut [u8]) -> Result<()>;
}
pub trait RandomSource {
fn fill(&mut self, out: &mut [u8]) -> Result<()>;
}
pub trait KeyAgreement: Algorithm {
const PRIVATE_KEY_LEN: usize;
const PUBLIC_KEY_LEN: usize;
const SHARED_SECRET_LEN: usize;
fn public_key(private_key: &[u8], out: &mut [u8]) -> Result<()>;
fn agree(private_key: &[u8], peer_public_key: &[u8], out: &mut [u8]) -> Result<()>;
}
pub trait SignatureScheme: Algorithm {
const PRIVATE_KEY_LEN: usize;
const PUBLIC_KEY_LEN: usize;
const SIGNATURE_LEN: usize;
fn public_key(private_key: &[u8], out: &mut [u8]) -> Result<()>;
fn sign(private_key: &[u8], message: &[u8], signature: &mut [u8]) -> Result<()>;
fn verify(public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<()>;
}
pub trait SelfTest {
fn self_test() -> Result<()>;
}