use crate::{hash::Hash, masked_keccak::MaskedKeccak};
use std::prelude::v1::*;
use zkp_primefield::FieldElement;
use zkp_u256::U256;
pub trait Hashable {
fn hash(&self) -> Hash;
}
impl Hashable for Hash {
fn hash(&self) -> Hash {
self.clone()
}
}
impl Hashable for U256 {
fn hash(&self) -> Hash {
Hash::new(self.to_bytes_be())
}
}
impl Hashable for FieldElement {
fn hash(&self) -> Hash {
self.as_montgomery().hash()
}
}
impl<T: Hashable> Hashable for &T {
fn hash(&self) -> Hash {
(*self).hash()
}
}
impl<T: Hashable> Hashable for &[T] {
fn hash(&self) -> Hash {
if self.len() == 1 {
self[0].hash()
} else {
let mut hasher = MaskedKeccak::new();
for value in self.iter() {
hasher.update(value.hash().as_bytes());
}
hasher.hash()
}
}
}
impl<T: Hashable> Hashable for Vec<T> {
fn hash(&self) -> Hash {
self.as_slice().hash()
}
}