solana_sha256_hasher/
lib.rs

1#![no_std]
2#[cfg(any(feature = "sha2", not(target_os = "solana")))]
3use sha2::{Digest, Sha256};
4#[cfg(target_os = "solana")]
5use solana_define_syscall::define_syscall;
6use solana_hash::Hash;
7
8#[cfg(any(feature = "sha2", not(target_os = "solana")))]
9#[derive(Clone, Default)]
10pub struct Hasher {
11    hasher: Sha256,
12}
13
14#[cfg(any(feature = "sha2", not(target_os = "solana")))]
15impl Hasher {
16    pub fn hash(&mut self, val: &[u8]) {
17        self.hasher.update(val);
18    }
19    pub fn hashv(&mut self, vals: &[&[u8]]) {
20        for val in vals {
21            self.hash(val);
22        }
23    }
24    pub fn result(self) -> Hash {
25        let bytes: [u8; solana_hash::HASH_BYTES] = self.hasher.finalize().into();
26        bytes.into()
27    }
28}
29
30#[cfg(target_os = "solana")]
31define_syscall!(fn sol_sha256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64);
32
33/// Return a Sha256 hash for the given data.
34pub fn hashv(vals: &[&[u8]]) -> Hash {
35    // Perform the calculation inline, calling this from within a program is
36    // not supported
37    #[cfg(not(target_os = "solana"))]
38    {
39        let mut hasher = Hasher::default();
40        hasher.hashv(vals);
41        hasher.result()
42    }
43    // Call via a system call to perform the calculation
44    #[cfg(target_os = "solana")]
45    {
46        let mut hash_result = [0; solana_hash::HASH_BYTES];
47        unsafe {
48            sol_sha256(
49                vals as *const _ as *const u8,
50                vals.len() as u64,
51                &mut hash_result as *mut _ as *mut u8,
52            );
53        }
54        Hash::new_from_array(hash_result)
55    }
56}
57
58/// Return a Sha256 hash for the given data.
59pub fn hash(val: &[u8]) -> Hash {
60    hashv(&[val])
61}
62
63/// Return the hash of the given hash extended with the given value.
64pub fn extend_and_hash(id: &Hash, val: &[u8]) -> Hash {
65    let mut hash_data = id.as_ref().to_vec();
66    hash_data.extend_from_slice(val);
67    hash(&hash_data)
68}