rust-bitcoin-unsafe-fast/hashes/src/sha1/crypto.rs

49 lines
1.6 KiB
Rust

// SPDX-License-Identifier: CC0-1.0
use super::{HashEngine, BLOCK_SIZE};
impl HashEngine {
// Basic unoptimized algorithm from Wikipedia
pub(super) fn process_block(&mut self) {
debug_assert_eq!(self.buffer.len(), BLOCK_SIZE);
let mut w = [0u32; 80];
for (w_val, buff_bytes) in w.iter_mut().zip(self.buffer.chunks_exact(4)) {
*w_val = u32::from_be_bytes(buff_bytes.try_into().expect("4 bytes slice"))
}
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 = self.h[0];
let mut b = self.h[1];
let mut c = self.h[2];
let mut d = self.h[3];
let mut e = self.h[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;
}
self.h[0] = self.h[0].wrapping_add(a);
self.h[1] = self.h[1].wrapping_add(b);
self.h[2] = self.h[2].wrapping_add(c);
self.h[3] = self.h[3].wrapping_add(d);
self.h[4] = self.h[4].wrapping_add(e);
}
}