use seckey::Bytes;
use super::{ AeadCipher, DecryptFail };
#[derive(Debug, Clone)]
pub struct Ascon {
key: Bytes,
aad: Vec<u8>
}
impl AeadCipher for Ascon {
fn new(key: &[u8]) -> Self where Self: Sized {
assert_eq!(key.len(), Self::KEY_LENGTH);
Ascon {
key: Bytes::new(key),
aad: Vec::new()
}
}
const KEY_LENGTH: usize = 16;
const TAG_LENGTH: usize = Self::KEY_LENGTH;
const NONCE_LENGTH: usize = Self::KEY_LENGTH;
fn with_aad(&mut self, aad: &[u8]) -> &mut Self {
self.aad = aad.into();
self
}
fn encrypt(&self, nonce: &[u8], data: &[u8]) -> Vec<u8> {
assert_eq!(nonce.len(), Self::NONCE_LENGTH);
let (mut output, tag) = ::ascon::aead_encrypt(&self.key, nonce, data, &self.aad);
output.extend_from_slice(&tag);
output
}
fn decrypt(&self, nonce: &[u8], data: &[u8]) -> Result<Vec<u8>, DecryptFail> {
assert_eq!(nonce.len(), Self::NONCE_LENGTH);
if data.len() < Self::TAG_LENGTH { Err(DecryptFail::LengthError)? };
let (data, tag) = data.split_at(data.len() - Self::TAG_LENGTH);
::ascon::aead_decrypt(&self.key, nonce, data, &self.aad, tag)
.map_err(|err| err.into())
}
}
impl From<::ascon::DecryptFail> for DecryptFail {
fn from(err: ::ascon::DecryptFail) -> DecryptFail {
match err {
::ascon::DecryptFail::TagLengthError => DecryptFail::LengthError,
::ascon::DecryptFail::AuthenticationFail => DecryptFail::AuthenticationFail
}
}
}