use blake2::Blake2b;
use blake2::digest::consts::U32;
use sha2::{Digest, Sha256};
use sha3::Sha3_256;
use crate::Hasher;
#[derive(Debug)]
pub(crate) struct Sha256Hasher;
impl Hasher for Sha256Hasher {
fn leaf(&self, data: &[u8]) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0x00]);
h.update(data);
h.finalize().to_vec()
}
fn node(&self, left: &[u8], right: &[u8]) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0x01]);
h.update(left);
h.update(right);
h.finalize().to_vec()
}
fn empty(&self) -> Vec<u8> {
Sha256::digest(b"").to_vec()
}
fn null(&self) -> Vec<u8> {
Sha256::digest([0x02]).to_vec()
}
fn hash(&self, data: &[u8]) -> Vec<u8> {
Sha256::digest(data).to_vec()
}
}
#[derive(Debug)]
pub(crate) struct Sha3Hasher;
impl Hasher for Sha3Hasher {
fn leaf(&self, data: &[u8]) -> Vec<u8> {
let mut h = Sha3_256::new();
h.update([0x00]);
h.update(data);
h.finalize().to_vec()
}
fn node(&self, left: &[u8], right: &[u8]) -> Vec<u8> {
let mut h = Sha3_256::new();
h.update([0x01]);
h.update(left);
h.update(right);
h.finalize().to_vec()
}
fn empty(&self) -> Vec<u8> {
Sha3_256::digest(b"").to_vec()
}
fn null(&self) -> Vec<u8> {
Sha3_256::digest([0x02]).to_vec()
}
fn hash(&self, data: &[u8]) -> Vec<u8> {
Sha3_256::digest(data).to_vec()
}
}
#[derive(Debug)]
pub(crate) struct Blake2bHasher;
impl Hasher for Blake2bHasher {
fn leaf(&self, data: &[u8]) -> Vec<u8> {
let mut h = Blake2b::<U32>::new();
Digest::update(&mut h, [0x00]);
Digest::update(&mut h, data);
h.finalize().to_vec()
}
fn node(&self, left: &[u8], right: &[u8]) -> Vec<u8> {
let mut h = Blake2b::<U32>::new();
Digest::update(&mut h, [0x01]);
Digest::update(&mut h, left);
Digest::update(&mut h, right);
h.finalize().to_vec()
}
fn empty(&self) -> Vec<u8> {
<Blake2b<U32> as Digest>::digest(b"").to_vec()
}
fn null(&self) -> Vec<u8> {
<Blake2b<U32> as Digest>::digest([0x02]).to_vec()
}
fn hash(&self, data: &[u8]) -> Vec<u8> {
<Blake2b<U32> as Digest>::digest(data).to_vec()
}
}
#[derive(Debug)]
pub(crate) struct AltHasher;
impl Hasher for AltHasher {
fn leaf(&self, data: &[u8]) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0x00, 0xFF]); h.update(data);
h.finalize().to_vec()
}
fn node(&self, left: &[u8], right: &[u8]) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0x01, 0xFF]);
h.update(left);
h.update(right);
h.finalize().to_vec()
}
fn empty(&self) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0xFF]);
h.finalize().to_vec()
}
fn null(&self) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0x02, 0xFF]);
h.finalize().to_vec()
}
fn hash(&self, data: &[u8]) -> Vec<u8> {
let mut h = Sha256::new();
h.update([0xFF]);
h.update(data);
h.finalize().to_vec()
}
}
pub(crate) fn new_hasher_for(alg_id: u64) -> Box<dyn Hasher> {
match alg_id % 3 {
0 => Box::new(Sha256Hasher),
1 => Box::new(Sha3Hasher),
2 => Box::new(Blake2bHasher),
_ => unreachable!(),
}
}