#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
)]
#![forbid(unsafe_code)]
#[inline(always)]
const fn round_constant(round: u64) -> u64 {
((0xFu64 - round) << 4) | round
}
const MAX_ROUNDS: usize = 12;
pub type State = [u64; 5];
#[inline(always)]
const fn round(state: &mut State, c: u64) {
let [mut x0, mut x1, mut x2, mut x3, mut x4] = *state;
x2 ^= c;
let t0 = x0 ^ x4;
let t1 = !x4;
let t2 = t1 | x3;
let t3 = x1 ^ x2;
let t4 = x3 ^ x2;
let t5 = x3 ^ x4;
let t6 = t0 | x1;
let t7 = x0 | t5;
let t8 = t4 | t3;
x1 = t0 ^ t8;
x3 = t3 ^ t7;
let t11 = x2 & t3;
let t12 = t6 ^ t5;
x2 = t3 ^ t2;
x0 = t12 ^ t11;
x4 = t0 ^ t12;
*state = [
x0 ^ x0.rotate_right(19) ^ x0.rotate_right(28),
x1 ^ x1.rotate_right(61) ^ x1.rotate_right(39),
x2 ^ x2.rotate_right(1) ^ x2.rotate_right(6),
x3 ^ x3.rotate_right(10) ^ x3.rotate_right(17),
x4 ^ x4.rotate_right(7) ^ x4.rotate_right(41),
];
}
#[inline]
pub const fn permute<const ROUNDS: usize>(state: &mut State) {
const { assert!(ROUNDS <= MAX_ROUNDS) };
#[cfg(not(ascon_backend = "soft-compact"))]
{
macro_rules! unroll_round {
($state:ident, $round:literal, $rounds:expr) => {
if $round >= MAX_ROUNDS - $rounds {
let rc = round_constant($round);
round($state, rc);
}
};
}
unroll_round!(state, 0, ROUNDS);
unroll_round!(state, 1, ROUNDS);
unroll_round!(state, 2, ROUNDS);
unroll_round!(state, 3, ROUNDS);
unroll_round!(state, 4, ROUNDS);
unroll_round!(state, 5, ROUNDS);
unroll_round!(state, 6, ROUNDS);
unroll_round!(state, 7, ROUNDS);
unroll_round!(state, 8, ROUNDS);
unroll_round!(state, 9, ROUNDS);
unroll_round!(state, 10, ROUNDS);
unroll_round!(state, 11, ROUNDS);
}
#[cfg(ascon_backend = "soft-compact")]
{
let mut i = MAX_ROUNDS - ROUNDS;
while i < MAX_ROUNDS {
round(state, round_constant(i as u64));
i += 1;
}
}
}
#[inline]
pub const fn permute12(state: &mut State) {
permute::<12>(state);
}
#[inline]
pub const fn permute8(state: &mut State) {
permute::<8>(state);
}
#[inline]
pub const fn permute6(state: &mut State) {
permute::<6>(state);
}