1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7)]
8#![forbid(unsafe_code)]
9
10#[inline(always)]
12const fn round_constant(round: u64) -> u64 {
13 ((0xFu64 - round) << 4) | round
14}
15
16const MAX_ROUNDS: usize = 12;
18
19pub type State = [u64; 5];
21
22#[inline(always)]
24const fn round(state: &mut State, c: u64) {
25 let [mut x0, mut x1, mut x2, mut x3, mut x4] = *state;
26
27 x2 ^= c;
29
30 let t0 = x0 ^ x4;
35 let t1 = !x4;
36 let t2 = t1 | x3;
37 let t3 = x1 ^ x2;
38 let t4 = x3 ^ x2;
39 let t5 = x3 ^ x4;
40 let t6 = t0 | x1;
41 let t7 = x0 | t5;
42 let t8 = t4 | t3;
43 x1 = t0 ^ t8;
44 x3 = t3 ^ t7;
45 let t11 = x2 & t3;
46 let t12 = t6 ^ t5;
47 x2 = t3 ^ t2;
48 x0 = t12 ^ t11;
49 x4 = t0 ^ t12;
50
51 *state = [
53 x0 ^ x0.rotate_right(19) ^ x0.rotate_right(28),
54 x1 ^ x1.rotate_right(61) ^ x1.rotate_right(39),
55 x2 ^ x2.rotate_right(1) ^ x2.rotate_right(6),
56 x3 ^ x3.rotate_right(10) ^ x3.rotate_right(17),
57 x4 ^ x4.rotate_right(7) ^ x4.rotate_right(41),
58 ];
59}
60
61#[inline]
65pub const fn permute<const ROUNDS: usize>(state: &mut State) {
66 const { assert!(ROUNDS <= MAX_ROUNDS) };
67
68 #[cfg(not(ascon_backend = "soft-compact"))]
69 {
70 macro_rules! unroll_round {
71 ($state:ident, $round:literal, $rounds:expr) => {
72 if $round >= MAX_ROUNDS - $rounds {
73 let rc = round_constant($round);
74 round($state, rc);
75 }
76 };
77 }
78
79 unroll_round!(state, 0, ROUNDS);
80 unroll_round!(state, 1, ROUNDS);
81 unroll_round!(state, 2, ROUNDS);
82 unroll_round!(state, 3, ROUNDS);
83 unroll_round!(state, 4, ROUNDS);
84 unroll_round!(state, 5, ROUNDS);
85 unroll_round!(state, 6, ROUNDS);
86 unroll_round!(state, 7, ROUNDS);
87 unroll_round!(state, 8, ROUNDS);
88 unroll_round!(state, 9, ROUNDS);
89 unroll_round!(state, 10, ROUNDS);
90 unroll_round!(state, 11, ROUNDS);
91 }
92
93 #[cfg(ascon_backend = "soft-compact")]
94 {
95 let mut i = MAX_ROUNDS - ROUNDS;
96 while i < MAX_ROUNDS {
97 round(state, round_constant(i as u64));
98 i += 1;
99 }
100 }
101}
102
103#[inline]
105pub const fn permute12(state: &mut State) {
106 permute::<12>(state);
107}
108
109#[inline]
111pub const fn permute8(state: &mut State) {
112 permute::<8>(state);
113}
114
115#[inline]
117pub const fn permute6(state: &mut State) {
118 permute::<6>(state);
119}