#![no_std]
#![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"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
pub const STATE_WORDS: usize = 24;
fn bash_s(
mut w0: u64,
mut w1: u64,
mut w2: u64,
m1: u32,
n1: u32,
m2: u32,
n2: u32,
) -> (u64, u64, u64) {
let t0 = w0.rotate_left(m1);
w0 ^= w1 ^ w2;
let t1 = w1 ^ w0.rotate_left(n1);
w1 = t0 ^ t1;
w2 ^= w2.rotate_left(m2) ^ t1.rotate_left(n2);
let t0 = !w2;
let t1 = w0 | w2;
let t2 = w0 & w1;
let t0 = t0 | w1;
w1 ^= t1;
w2 ^= t2;
w0 ^= t0;
(w0, w1, w2)
}
pub fn bash_f(state: &mut [u64; STATE_WORDS]) {
let mut c: u64 = 0x3BF5080AC8BA94B1;
for _ in 0..STATE_WORDS {
let (mut m1, mut n1, mut m2, mut n2) = (8, 53, 14, 1);
for j in 0..8 {
let (s0, s1, s2) = bash_s(state[j], state[8 + j], state[16 + j], m1, n1, m2, n2);
state[j] = s0;
state[8 + j] = s1;
state[16 + j] = s2;
(m1, n1, m2, n2) = ((7 * m1) % 64, (7 * n1) % 64, (7 * m2) % 64, (7 * n2) % 64);
}
const INDEXES: [usize; STATE_WORDS] = [
15, 10, 9, 12, 11, 14, 13, 8, 17, 16, 19, 18, 21, 20, 23, 22, 6, 3, 0, 5, 2, 7, 4, 1,
];
*state = INDEXES.map(|i| state[i]);
state[23] ^= c;
if c & 1 == 0 {
c >>= 1;
} else {
c = (c >> 1) ^ 0xDC2BE1997FE0D8AE;
}
}
}
#[test]
fn test_bash_s() {
let w0 = 0xB194BAC80A08F53Bu64.swap_bytes();
let w1 = 0xE12BDC1AE28257ECu64.swap_bytes();
let w2 = 0xE9DEE72C8F0C0FA6u64.swap_bytes();
let (w0_out, w1_out, w2_out) = bash_s(w0, w1, w2, 8, 53, 14, 1);
assert_eq!(w0_out, 0x479E76129979DC5Fu64.swap_bytes());
assert_eq!(w1_out, 0x0F2B2C93ED128EDDu64.swap_bytes());
assert_eq!(w2_out, 0x41009B1B112DFEF3u64.swap_bytes());
}