dd_merkle_tree/merkle/
hashing_algorithm.rs

1#[cfg(target_arch = "wasm32")]
2pub mod hashing_wasm {
3    use sha2::{Sha256, Digest};
4    use sha3::Keccak256;
5
6    pub fn sha256(val: &[u8]) -> [u8;32] {
7        let mut hasher = Sha256::new();
8        hasher.update(val);
9        hasher.finalize().into()
10    }
11
12    pub fn keccak256(val: &[u8]) -> [u8;32] {
13        let mut hasher = Keccak256::new();
14        hasher.update(val);
15        hasher.finalize().into()
16    }
17}
18#[cfg(target_arch = "wasm32")]
19use hashing_wasm::{sha256, keccak256};
20
21#[cfg(not(target_arch = "wasm32"))]
22use anchor_lang::prelude::*;
23#[cfg(not(target_arch = "wasm32"))]
24mod hashing {
25    use solana_program::{hash, keccak};
26
27    pub fn sha256(val: &[u8]) -> [u8;32] {
28        hash::hash(val).to_bytes()
29    }
30
31    pub fn keccak256(val: &[u8]) -> [u8;32] {
32        keccak::hash(val).to_bytes()
33    }
34}
35#[cfg(not(target_arch = "wasm32"))]
36use hashing::{sha256, keccak256};
37
38#[derive(Debug, Clone, PartialEq)]
39#[cfg_attr(not(target_arch = "wasm32"), derive(AnchorSerialize, AnchorDeserialize))]
40pub enum HashingAlgorithm {
41    Sha256 = 0,
42    Sha256d = 1,
43    Keccak = 2,
44    Keccakd = 3
45}
46
47impl From<HashingAlgorithm> for u8 {
48    fn from(value: HashingAlgorithm) -> Self {
49        match value {
50            HashingAlgorithm::Sha256 => 0,
51            HashingAlgorithm::Sha256d => 1,
52            HashingAlgorithm::Keccak => 2,
53            HashingAlgorithm::Keccakd => 3,
54        }
55    }
56}
57
58impl From<u8> for HashingAlgorithm {
59    fn from(value: u8) -> HashingAlgorithm {
60        match value {
61            1 => HashingAlgorithm::Sha256d,
62            2 => HashingAlgorithm::Keccak,
63            3 => HashingAlgorithm::Keccakd,
64            _ => HashingAlgorithm::Sha256,
65        }
66    }
67}
68
69impl HashingAlgorithm {
70    pub fn hash(&self, b: &[u8], s: usize) -> Vec<u8> {
71        let s = match s == 0 || s > 32 {
72            true => 32,
73            false => s
74        };
75        match self {
76            HashingAlgorithm::Sha256 => sha256(b)[..s].to_vec(),
77            HashingAlgorithm::Keccak => keccak256(b)[..s].to_vec(),
78            HashingAlgorithm::Sha256d | HashingAlgorithm::Keccakd => self.double_hash(b, s)
79        }
80    }
81
82    pub fn double_hash(&self, b: &[u8], s: usize) -> Vec<u8> {
83        let s = match s == 0 || s > 32 {
84            true => 32,
85            false => s
86        };
87        match self {
88            HashingAlgorithm::Sha256 | HashingAlgorithm::Sha256d => sha256(&sha256(b))[..s].to_vec(),
89            HashingAlgorithm::Keccak | HashingAlgorithm::Keccakd => keccak256(&keccak256(b))[..s].to_vec(),
90        }
91    }
92}