#![cfg_attr(not(feature = "std"), no_std)]
pub mod chacha;
pub use chacha::chacha20::{ChaCha20, CHACHA20_BLOCK_SIZE, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE};
use crate::error::{Error, Result};
pub trait StreamCipher {
const KEY_SIZE: usize;
const NONCE_SIZE: usize;
const BLOCK_SIZE: usize;
fn process(&mut self, data: &mut [u8]) -> Result<()>;
fn encrypt(&mut self, data: &mut [u8]) -> Result<()> {
self.process(data)
}
fn decrypt(&mut self, data: &mut [u8]) -> Result<()> {
self.process(data)
}
fn keystream(&mut self, output: &mut [u8]) -> Result<()>;
fn reset(&mut self) -> Result<()>;
fn seek(&mut self, position: u64) -> Result<()>;
}
impl StreamCipher for ChaCha20 {
const KEY_SIZE: usize = CHACHA20_KEY_SIZE;
const NONCE_SIZE: usize = CHACHA20_NONCE_SIZE;
const BLOCK_SIZE: usize = CHACHA20_BLOCK_SIZE;
fn process(&mut self, data: &mut [u8]) -> Result<()> {
self.process(data);
Ok(())
}
fn keystream(&mut self, output: &mut [u8]) -> Result<()> {
self.keystream(output);
Ok(())
}
fn reset(&mut self) -> Result<()> {
self.reset();
Ok(())
}
fn seek(&mut self, position: u64) -> Result<()> {
if position > u32::MAX as u64 {
return Err(Error::param(
"position",
"ChaCha20 seek position must fit in u32",
));
}
self.seek(position as u32);
Ok(())
}
}