Slightly easier-to-modify hash code.

This commit is contained in:
Nathan Vegdahl 2022-08-25 19:56:38 -07:00
parent 7d7ab1acf1
commit e25e28d88b

View File

@ -121,38 +121,31 @@ fn add_buffer_to_state(state: &mut [u64; 4], buffer: &[u8]) {
/// The main mix function. Mixes the passed hash state.
///
/// Inspired by Skein 1.3, and using its MIX function.
///
/// The mix rotation constants are:
/// - 40 50
/// - 27 21
///
/// They were selected by an exhaustive search of the four-constant
/// space, selecting for the best single-bit diffusion at a small
/// number of rounds.
///
/// The permute table is:
/// - Indices: 0 1 2 3
/// - Become: 0 1 3 2
#[inline(always)]
fn mix_state(state: &mut [u64; 4], rounds: usize) {
for _ in 0..rounds {
// MIX function.
state[0] = state[0].wrapping_add(state[2]);
state[2] = state[2].rotate_left(40) ^ state[0];
state[1] = state[1].wrapping_add(state[3]);
state[3] = state[3].rotate_left(50) ^ state[1];
// Permute.
state.swap(2, 3);
const ROTATIONS: &[[u32; 4]] = &[
[40, 50, 27, 21],
[40, 50, 27, 21],
[40, 50, 27, 21],
[40, 50, 27, 21],
];
for round in 0..rounds {
let rot = ROTATIONS[round % ROTATIONS.len()];
// MIX function.
state[0] = state[0].wrapping_add(state[2]);
state[2] = state[2].rotate_left(27) ^ state[0];
state[2] = state[2].rotate_left(rot[0]) ^ state[0];
state[1] = state[1].wrapping_add(state[3]);
state[3] = state[3].rotate_left(21) ^ state[1];
state[3] = state[3].rotate_left(rot[1]) ^ state[1];
// Permute.
state.swap(2, 3);
// We flip the indices we use below, as if we did
// a [0 1 2 3] -> [0 1 3 2] permutation.
// MIX function.
state[0] = state[0].wrapping_add(state[3]);
state[3] = state[3].rotate_left(rot[2]) ^ state[0];
state[1] = state[1].wrapping_add(state[2]);
state[2] = state[2].rotate_left(rot[3]) ^ state[1];
}
}