arb_hash/
lib.rs

1pub fn arb_hash<const LEN: usize, const RND: u64>(mut input: [u8; LEN]) -> [u8; LEN] {
2    const SHIFTS: [u32; 5] = [1, 2, 3, 5, 7];
3    let original = input;
4    for _rnd in 0..RND {
5        for b_shift in 0..LEN {
6            for elem in 0..LEN {
7                let shift = SHIFTS[(b_shift + elem) % 5];
8                let c_index = (elem + 2) % LEN;
9                input[elem] = input[elem].wrapping_add(input[(elem + 1) % LEN]);
10                input[c_index] ^= input[elem];
11                input[c_index] = input[c_index].rotate_left(shift);
12            }
13        }
14    }
15    for elem in 0..LEN {
16        input[elem] ^= original[elem];
17    }
18    input
19}
20
21#[test]
22fn arb_hash_test() {
23    assert_eq!(
24        arb_hash::<8, 3>([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
25        [0xF2, 0x04, 0xF7, 0x45, 0xC2, 0x0D, 0xEA, 0xEA]
26    );
27}