1use sha2::Digest as Sha2Digest;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum HashFunction {
10 Sha2_256,
12 Sha3_256,
14}
15
16pub fn sha2_256(data: &[u8]) -> [u8; 32] {
29 let mut hasher = sha2::Sha256::new();
30 hasher.update(data);
31 let result = hasher.finalize();
32 let mut output = [0u8; 32];
33 output.copy_from_slice(&result);
34 output
35}
36
37pub fn sha3_256(data: &[u8]) -> [u8; 32] {
50 let mut hasher = sha3::Sha3_256::new();
51 hasher.update(data);
52 let result = hasher.finalize();
53 let mut output = [0u8; 32];
54 output.copy_from_slice(&result);
55 output
56}
57
58#[allow(dead_code)] pub fn sha3_256_of<I, T>(items: I) -> [u8; 32]
61where
62 I: IntoIterator<Item = T>,
63 T: AsRef<[u8]>,
64{
65 let mut hasher = sha3::Sha3_256::new();
66 for item in items {
67 hasher.update(item.as_ref());
68 }
69 let result = hasher.finalize();
70 let mut output = [0u8; 32];
71 output.copy_from_slice(&result);
72 output
73}
74
75#[allow(dead_code)] pub fn signing_message(domain: &str, bcs_bytes: &[u8]) -> [u8; 32] {
81 sha3_256_of([format!("APTOS::{domain}").as_bytes(), bcs_bytes])
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_sha2_256() {
90 let hash = sha2_256(b"hello world");
91 assert_eq!(hash.len(), 32);
92 let expected =
94 hex::decode("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9")
95 .unwrap();
96 assert_eq!(hash.as_slice(), expected.as_slice());
97 }
98
99 #[test]
100 fn test_sha3_256() {
101 let hash = sha3_256(b"hello world");
102 assert_eq!(hash.len(), 32);
103 let sha2_hash = sha2_256(b"hello world");
105 assert_ne!(hash, sha2_hash);
106 }
107
108 #[test]
109 fn test_sha3_256_of_multiple() {
110 let hash1 = sha3_256(b"helloworld");
111 let hash2 = sha3_256_of([b"hello".as_slice(), b"world".as_slice()]);
112 assert_eq!(hash1, hash2);
113 }
114
115 #[test]
116 fn test_signing_message() {
117 let msg = signing_message("RawTransaction", b"transaction_bytes");
118 assert_eq!(msg.len(), 32);
119 }
120}