use crate::hasher::NextHash;
use crate::hasher::buffer::Buffer;
use crypto::{sha2::Sha512, digest::Digest};
pub struct HasherSHA512 {
alg: Sha512,
buffer: Buffer,
}
impl HasherSHA512 {
const SIZE: usize = 512 / 8;
const PREVSIZE: usize = HasherSHA512::SIZE / 2;
pub const OUTSIZE: usize = HasherSHA512::SIZE;
pub fn new(seed: &Vec<u8>) -> HasherSHA512 {
HasherSHA512 {
alg: Sha512::new(),
buffer: Buffer::new(seed,
HasherSHA512::SIZE,
HasherSHA512::PREVSIZE),
}
}
}
impl NextHash for HasherSHA512 {
fn get_size(&self) -> usize {
HasherSHA512::OUTSIZE
}
fn next(&mut self) -> &[u8] {
self.buffer.next_count();
self.alg.input(self.buffer.hashalg_input());
self.alg.result(self.buffer.hashalg_output());
self.alg.reset();
return &self.buffer.get_result()[..HasherSHA512::OUTSIZE];
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cmp_result() {
let mut a = HasherSHA512::new(&vec![1,2,3]);
assert_eq!(a.next(),
vec![190, 149, 3, 95, 94, 39, 66, 152, 48, 160, 195, 187, 7, 43, 208, 248,
47, 37, 122, 0, 108, 73, 97, 168, 239, 225, 234, 13, 64, 228, 129, 67,
114, 41, 107, 214, 206, 87, 144, 22, 129, 242, 236, 130, 90, 86, 219, 77,
197, 237, 185, 115, 19, 127, 135, 142, 247, 60, 0, 40, 143, 199, 201, 141]);
assert_eq!(a.next(),
vec![40, 40, 150, 50, 148, 27, 213, 226, 36, 132, 130, 106, 145, 251, 214, 237,
221, 166, 21, 188, 210, 196, 105, 79, 207, 1, 63, 89, 29, 20, 188, 129,
111, 217, 183, 160, 253, 221, 178, 81, 168, 139, 198, 103, 38, 195, 53, 79,
67, 162, 85, 204, 132, 211, 166, 143, 221, 71, 234, 195, 221, 49, 30, 218]);
}
#[test]
fn test_seed_equal() {
let mut a = HasherSHA512::new(&vec![1,2,3]);
let mut b = HasherSHA512::new(&vec![1,2,3]);
let mut res_a = vec![];
let mut res_b = vec![];
for _ in 0..2 {
res_a.push(a.next().to_vec());
res_b.push(b.next().to_vec());
}
assert_eq!(res_a[0], res_b[0]);
assert_eq!(res_a[1], res_b[1]);
assert_ne!(res_a[0], res_a[1]);
assert_ne!(res_b[0], res_b[1]);
}
#[test]
fn test_seed_diff() {
let mut a = HasherSHA512::new(&vec![1,2,3]);
let mut b = HasherSHA512::new(&vec![1,2,4]);
let mut res_a = vec![];
let mut res_b = vec![];
for _ in 0..2 {
res_a.push(a.next().to_vec());
res_b.push(b.next().to_vec());
}
assert_ne!(res_a[0], res_b[0]);
assert_ne!(res_a[1], res_b[1]);
assert_ne!(res_a[0], res_a[1]);
assert_ne!(res_b[0], res_b[1]);
}
}