#![no_std]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg"
)]
#![deny(unsafe_code)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs, rust_2018_idioms)]
mod consts;
pub use cipher;
use cipher::{
Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend,
BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, ParBlocksSizeUser,
consts::{U1, U16},
inout::InOut,
};
#[cfg(feature = "zeroize")]
use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
mod aria128;
mod aria192;
mod aria256;
mod utils;
use utils::{fe, fo, sl2};
#[derive(Clone)]
pub struct Aria<const RK: usize> {
ek: [u128; RK],
dk: [u128; RK],
}
impl<const RK: usize> BlockSizeUser for Aria<RK> {
type BlockSize = U16;
}
impl<const RK: usize> ParBlocksSizeUser for Aria<RK> {
type ParBlocksSize = U1;
}
impl<const RK: usize> BlockCipherEncrypt for Aria<RK> {
#[inline]
fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = Self::BlockSize>) {
f.call(self)
}
}
impl<const RK: usize> BlockCipherEncBackend for Aria<RK> {
#[inline]
fn encrypt_block(&self, mut block: InOut<'_, '_, Block<Self>>) {
let mut p0 = u128::from_be_bytes((*block.get_in()).into());
let mut p1;
for i in (0..RK - 3).step_by(2) {
p1 = fo(p0 ^ self.ek[i]);
p0 = fe(p1 ^ self.ek[i + 1]);
}
let p1 = fo(p0 ^ self.ek[RK - 3]);
let c = sl2(p1 ^ self.ek[RK - 2]) ^ self.ek[RK - 1];
block.get_out().copy_from_slice(&c.to_be_bytes());
}
}
impl<const RK: usize> BlockCipherDecrypt for Aria<RK> {
#[inline]
fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = Self::BlockSize>) {
f.call(self)
}
}
impl<const RK: usize> BlockCipherDecBackend for Aria<RK> {
#[inline]
fn decrypt_block(&self, mut block: InOut<'_, '_, Block<Self>>) {
let mut c0 = u128::from_be_bytes((*block.get_in()).into());
let mut c1;
for i in (0..RK - 3).step_by(2) {
c1 = fo(c0 ^ self.dk[i]);
c0 = fe(c1 ^ self.dk[i + 1]);
}
let c1 = fo(c0 ^ self.dk[RK - 3]);
let p = sl2(c1 ^ self.dk[RK - 2]) ^ self.dk[RK - 1];
block.get_out().copy_from_slice(&p.to_be_bytes());
}
}
impl<const RK: usize> Drop for Aria<RK> {
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
{
self.ek.zeroize();
self.dk.zeroize();
}
}
}
#[cfg(feature = "zeroize")]
impl<const RK: usize> ZeroizeOnDrop for Aria<RK> {}
pub type Aria128 = Aria<13>;
pub type Aria192 = Aria<15>;
pub type Aria256 = Aria<17>;