use blake3::Hasher as Blake3Hasher;
use hmac::{Hmac, Mac};
use sha3::{Digest, Sha3_256, Sha3_512};
use crate::crypto::constants::HashType;
pub fn hash_data(data: &[u8], hash_type: HashType) -> Vec<u8> {
match hash_type {
HashType::Sha3_256 => Sha3_256::digest(data).to_vec(),
HashType::Sha3_512 => Sha3_512::digest(data).to_vec(),
HashType::Blake3 => {
let mut hasher = Blake3Hasher::new();
hasher.update(data);
hasher.finalize().as_bytes().to_vec()
}
}
}
pub fn create_hmac(key: &[u8], data: &[u8], hash_type: HashType) -> Vec<u8> {
match hash_type {
HashType::Sha3_256 => {
let mut mac =
Hmac::<Sha3_256>::new_from_slice(key).expect("HMAC accepts any key length");
mac.update(data);
mac.finalize().into_bytes().to_vec()
}
HashType::Sha3_512 => {
let mut mac =
Hmac::<Sha3_512>::new_from_slice(key).expect("HMAC accepts any key length");
mac.update(data);
mac.finalize().into_bytes().to_vec()
}
HashType::Blake3 => {
let mut key32 = [0_u8; 32];
let copy_len = key.len().min(32);
key32[..copy_len].copy_from_slice(&key[..copy_len]);
let mut hasher = Blake3Hasher::new_keyed(&key32);
hasher.update(data);
hasher.finalize().as_bytes().to_vec()
}
}
}
pub fn create_hash_chain(hash_types: &[HashType], data: &[u8]) -> Vec<u8> {
let mut result = data.to_vec();
for hash_type in hash_types.iter().rev() {
result = hash_data(&result, *hash_type);
}
result
}