light_hasher/
sha256.rs

1use crate::{
2    errors::HasherError,
3    zero_bytes::{sha256::ZERO_BYTES, ZeroBytes},
4    zero_indexed_leaf::sha256::ZERO_INDEXED_LEAF,
5    Hash, Hasher,
6};
7
8/// Compile-time assertion trait that ensures a generic Hasher type is SHA256.
9/// Used by LightHasherSha macro to enforce SHA256-only implementation at compile time.
10pub trait RequireSha256: Hasher {
11    const ASSERT: () = assert!(
12        Self::ID == 1,
13        "DataHasher for LightHasherSha only works with SHA256 (ID=1). Example: your_struct.hash::<Sha256>()?"
14    );
15}
16
17impl<T: Hasher> RequireSha256 for T {}
18
19#[derive(Clone, Copy)] // To allow using with zero copy Solana accounts.
20pub struct Sha256;
21
22impl Hasher for Sha256 {
23    const ID: u8 = 1;
24    fn hash(val: &[u8]) -> Result<Hash, HasherError> {
25        Self::hashv(&[val])
26    }
27
28    fn hashv(vals: &[&[u8]]) -> Result<Hash, HasherError> {
29        #[cfg(not(target_os = "solana"))]
30        {
31            use sha2::{Digest, Sha256};
32
33            let mut hasher = Sha256::default();
34            for val in vals {
35                hasher.update(val);
36            }
37            Ok(hasher.finalize().into())
38        }
39        // Call via a system call to perform the calculation
40        #[cfg(target_os = "solana")]
41        {
42            use crate::HASH_BYTES;
43
44            let mut hash_result = [0; HASH_BYTES];
45            unsafe {
46                crate::syscalls::sol_sha256(
47                    vals as *const _ as *const u8,
48                    vals.len() as u64,
49                    &mut hash_result as *mut _ as *mut u8,
50                );
51            }
52            Ok(hash_result)
53        }
54    }
55
56    fn zero_bytes() -> ZeroBytes {
57        ZERO_BYTES
58    }
59
60    fn zero_indexed_leaf() -> [u8; 32] {
61        ZERO_INDEXED_LEAF
62    }
63}