groestl/
compress512.rs

1#![allow(clippy::needless_range_loop)]
2use crate::table::TABLE;
3use core::{convert::TryInto, u64};
4
5pub(crate) const COLS: usize = 8;
6const ROUNDS: u64 = 10;
7
8#[inline(always)]
9fn column(x: &[u64; COLS], c: [usize; 8]) -> u64 {
10    let mut t = 0;
11    for i in 0..8 {
12        let sl = 8 * (7 - i);
13        let idx = ((x[c[i]] >> sl) & 0xFF) as usize;
14        t ^= TABLE[i][idx];
15    }
16    t
17}
18
19#[inline(always)]
20fn rndq(mut x: [u64; COLS], r: u64) -> [u64; COLS] {
21    for i in 0..COLS {
22        x[i] ^= u64::MAX.wrapping_sub((i as u64) << 4) ^ r;
23    }
24    [
25        column(&x, [1, 3, 5, 7, 0, 2, 4, 6]),
26        column(&x, [2, 4, 6, 0, 1, 3, 5, 7]),
27        column(&x, [3, 5, 7, 1, 2, 4, 6, 0]),
28        column(&x, [4, 6, 0, 2, 3, 5, 7, 1]),
29        column(&x, [5, 7, 1, 3, 4, 6, 0, 2]),
30        column(&x, [6, 0, 2, 4, 5, 7, 1, 3]),
31        column(&x, [7, 1, 3, 5, 6, 0, 2, 4]),
32        column(&x, [0, 2, 4, 6, 7, 1, 3, 5]),
33    ]
34}
35
36#[inline(always)]
37fn rndp(mut x: [u64; COLS], r: u64) -> [u64; COLS] {
38    for i in 0..COLS {
39        x[i] ^= ((i as u64) << 60) ^ r;
40    }
41    [
42        column(&x, [0, 1, 2, 3, 4, 5, 6, 7]),
43        column(&x, [1, 2, 3, 4, 5, 6, 7, 0]),
44        column(&x, [2, 3, 4, 5, 6, 7, 0, 1]),
45        column(&x, [3, 4, 5, 6, 7, 0, 1, 2]),
46        column(&x, [4, 5, 6, 7, 0, 1, 2, 3]),
47        column(&x, [5, 6, 7, 0, 1, 2, 3, 4]),
48        column(&x, [6, 7, 0, 1, 2, 3, 4, 5]),
49        column(&x, [7, 0, 1, 2, 3, 4, 5, 6]),
50    ]
51}
52
53pub(crate) fn compress(h: &mut [u64; COLS], block: &[u8; 64]) {
54    let mut q = [0u64; COLS];
55    for (chunk, v) in block.chunks_exact(8).zip(q.iter_mut()) {
56        *v = u64::from_be_bytes(chunk.try_into().unwrap());
57    }
58    let mut p = [0u64; COLS];
59    for i in 0..COLS {
60        p[i] = h[i] ^ q[i];
61    }
62    for i in 0..ROUNDS {
63        q = rndq(q, i);
64    }
65    for i in 0..ROUNDS {
66        p = rndp(p, i << 56);
67    }
68    for i in 0..COLS {
69        h[i] ^= q[i] ^ p[i];
70    }
71}
72
73pub(crate) fn p(h: &[u64; COLS]) -> [u64; COLS] {
74    let mut p = *h;
75    for i in 0..ROUNDS {
76        p = rndp(p, i << 56);
77    }
78    for i in 0..COLS {
79        p[i] ^= h[i];
80    }
81    p
82}