use crate::hasher;
use crate::{Hash, HashAlgorithm};
use base_xx::ByteVec;
use base_xx::SerialiseError;
use sha3::{Digest, Keccak512 as Keccak512Impl};
use std::sync::Arc;
pub struct Keccak512 {}
impl Keccak512 {
#[must_use = "the computed hash is returned in the Ok value"]
pub fn try_from_bytes(bytes: &ByteVec) -> Result<Arc<Hash>, SerialiseError> {
let mut hasher = Keccak512Impl::new();
let bytes = bytes.get_bytes();
hasher.update(bytes);
let result = hasher.finalize();
let bytes = result.to_vec();
if bytes.len() != 64 {
return Err(SerialiseError::new("Invalid hash length".to_string()));
}
Ok(Arc::new(Hash::new(
HashAlgorithm::KECCAK512,
ByteVec::new(Arc::new(bytes)),
)))
}
}
impl hasher::Hasher for Keccak512 {
fn try_hash(byte_vec: Arc<ByteVec>) -> Result<Arc<Hash>, SerialiseError> {
Self::try_from_bytes(byte_vec.as_ref())
}
}
#[cfg(test)]
mod tests {
use slogger::debug;
use base_xx::{ByteVec, Encoding};
use super::*;
#[test]
pub fn test_keccak512() {
let test = ByteVec::new(Arc::new(b"this is a really good test".to_vec()));
match Hash::try_hash(Arc::new(test), HashAlgorithm::KECCAK512) {
Ok(hash) => match hash.try_to_byte_vec() {
Ok(bytes) => match bytes.try_encode(Encoding::Base36) {
Ok(serialised) => {
let serialised = serialised.get_string();
debug!("sha256 {serialised}");
assert_eq!(
serialised,
"38ysawi0duc9mzovh3lzq5juv9ka63ursns1igg86xddp4mwftwjbsa2czjohoo84vwtw7plbczix59ywdcn3ttjbxluh6tgaoycq"
);
}
Err(error) => debug!("serialisation error: {error:?}"),
},
Err(error) => debug!("serialisation error: {error:?}"),
},
Err(error) => debug!("hash error: {error:?}"),
}
}
}