brine_tree/
hash.rs

1use bytemuck::{Pod, Zeroable};
2
3#[cfg(not(feature = "solana"))]
4use sha3::Digest;
5
6pub const HASH_BYTES: usize = 32;
7
8#[repr(C)]
9#[derive(Clone, Copy, PartialEq, Debug, Default, Pod, Zeroable)]
10pub struct Hash {
11   pub(crate) value: [u8; 32]
12}
13
14impl From<Hash> for [u8; HASH_BYTES] {
15    fn from(from: Hash) -> Self {
16        from.value
17    }
18}
19
20impl From<[u8; HASH_BYTES]> for Hash {
21    fn from(from: [u8; 32]) -> Self {
22        Self { value: from }
23    }
24}
25
26impl AsRef<[u8]> for Hash {
27    fn as_ref(&self) -> &[u8] {
28        &self.value
29    }
30}
31
32impl Hash {
33    pub const LEN: usize = HASH_BYTES;
34
35    pub fn new(hash_slice: &[u8]) -> Self {
36        Hash { value: <[u8; HASH_BYTES]>::try_from(hash_slice).unwrap() }
37    }
38
39    pub const fn new_from_array(hash_array: [u8; HASH_BYTES]) -> Self {
40        Self { value: hash_array }
41    }
42
43    pub fn to_bytes(self) -> [u8; HASH_BYTES] {
44        self.value
45    }
46}
47
48#[cfg(feature = "solana")]
49#[inline(always)]
50pub fn hashv(data: &[&[u8]]) -> Hash {
51    let res = solana_program::keccak::hashv(data);
52    Hash::new_from_array(res.to_bytes())
53}
54
55#[cfg(not(feature = "solana"))]
56#[inline(always)]
57pub fn hashv(data: &[&[u8]]) -> Hash {
58    let mut hasher = sha3::Keccak256::new();
59    for d in data {
60        hasher.update(d);
61    }
62    Hash::new_from_array(hasher.finalize().into())
63}
64
65#[cfg(feature = "solana")]
66#[inline(always)]
67pub fn hash(data: &[u8]) -> Hash {
68    let res = solana_program::keccak::hash(data);
69    Hash::new_from_array(res.to_bytes())
70}
71
72#[cfg(not(feature = "solana"))]
73#[inline(always)]
74pub fn hash(data: &[u8]) -> Hash {
75    let mut hasher = sha3::Keccak256::new();
76    hasher.update(data);
77    Hash::new_from_array(hasher.finalize().into())
78}