#![allow(clippy::unreadable_literal)]
#![allow(clippy::many_single_char_names)]
use internals::slice::SliceExt;
use super::{HashEngine, BLOCK_SIZE};
impl HashEngine {
pub(super) fn process_blocks(state: &mut [u32; 5], blocks: &[u8]) {
debug_assert!(!blocks.is_empty() && blocks.len().is_multiple_of(BLOCK_SIZE));
for block in blocks.chunks_exact(BLOCK_SIZE) {
let mut w = [0u32; 80];
for (w_val, buff_bytes) in w.iter_mut().zip(block.as_nonzero_chunks().0) {
*w_val = u32::from_be_bytes(*buff_bytes);
}
for i in 16..80 {
w[i] = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]).rotate_left(1);
}
let mut a = state[0];
let mut b = state[1];
let mut c = state[2];
let mut d = state[3];
let mut e = state[4];
for (i, &wi) in w.iter().enumerate() {
let (f, k) = match i {
0..=19 => ((b & c) | (!b & d), 0x5a827999),
20..=39 => (b ^ c ^ d, 0x6ed9eba1),
40..=59 => ((b & c) | (b & d) | (c & d), 0x8f1bbcdc),
60..=79 => (b ^ c ^ d, 0xca62c1d6),
_ => unreachable!(),
};
let new_a = a
.rotate_left(5)
.wrapping_add(f)
.wrapping_add(e)
.wrapping_add(k)
.wrapping_add(wi);
e = d;
d = c;
c = b.rotate_left(30);
b = a;
a = new_a;
}
state[0] = state[0].wrapping_add(a);
state[1] = state[1].wrapping_add(b);
state[2] = state[2].wrapping_add(c);
state[3] = state[3].wrapping_add(d);
state[4] = state[4].wrapping_add(e);
}
}
}