#[cfg(feature = "sha")]
use crypto::hashes::sha::SHA256;
#[cfg(feature = "sha")]
use crypto::hashes::sha::SHA256_LEN;
pub const SHA_ALG_NAME: &str = "sha-256";
pub trait Hasher: Sync + Send {
fn digest(&self, input: &[u8]) -> Vec<u8>;
fn alg_name(&self) -> &'static str;
fn encoded_digest(&self, disclosure: &str) -> String {
let hash = self.digest(disclosure.as_bytes());
multibase::Base::Base64Url.encode(hash)
}
}
#[derive(Default, Clone, Copy)]
#[cfg(feature = "sha")]
pub struct Sha256Hasher;
#[cfg(feature = "sha")]
impl Sha256Hasher {
pub fn new() -> Self {
Sha256Hasher {}
}
}
#[cfg(feature = "sha")]
impl Hasher for Sha256Hasher {
fn digest(&self, input: &[u8]) -> Vec<u8> {
let mut digest: [u8; SHA256_LEN] = Default::default();
SHA256(input, &mut digest);
digest.to_vec()
}
fn alg_name(&self) -> &'static str {
SHA_ALG_NAME
}
}
#[cfg(test)]
mod test {
use crate::Hasher;
use crate::Sha256Hasher;
#[test]
fn test1() {
let disclosure = "WyI2cU1RdlJMNWhhaiIsICJmYW1pbHlfbmFtZSIsICJNw7ZiaXVzIl0";
let hasher = Sha256Hasher::new();
let hash = hasher.encoded_digest(disclosure);
assert_eq!("uutlBuYeMDyjLLTpf6Jxi7yNkEF35jdyWMn9U7b_RYY", hash);
}
#[test]
fn test2() {
let disclosure =
"WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImVtYWlsIiwgIlwidW51c3VhbCBlbWFpbCBhZGRyZXNzXCJAZXhhbXBsZS5qcCJd";
let hasher = Sha256Hasher::new();
let hash = hasher.encoded_digest(disclosure);
assert_eq!("Kuet1yAa0HIQvYnOVd59hcViO9Ug6J2kSfqYRBeowvE", hash);
}
#[test]
fn test3() {
let disclosure = "WyJsa2x4RjVqTVlsR1RQVW92TU5JdkNBIiwgIkZSIl0";
let hasher = Sha256Hasher::new();
let hash = hasher.encoded_digest(disclosure);
assert_eq!("w0I8EKcdCtUPkGCNUrfwVp2xEgNjtoIDlOxc9-PlOhs", hash);
}
}