accumulate_client/codec/
hash_helper.rs1use crate::codec::{canonical_json, sha256_bytes};
7use serde_json::Value;
8
9#[derive(Debug, Clone, Copy)]
11pub struct HashHelper;
12
13impl HashHelper {
14 pub fn sha256(data: &[u8]) -> [u8; 32] {
16 sha256_bytes(data)
17 }
18
19 pub fn sha256_hex(data: &[u8]) -> String {
21 hex::encode(sha256_bytes(data))
22 }
23
24 pub fn sha256_json(json_data: &Value) -> [u8; 32] {
26 let canonical = canonical_json(json_data);
27 sha256_bytes(canonical.as_bytes())
28 }
29
30 pub fn sha256_json_hex(json_data: &Value) -> String {
32 let canonical = canonical_json(json_data);
33 hex::encode(sha256_bytes(canonical.as_bytes()))
34 }
35
36 pub fn bytes_to_hex(bytes: &[u8]) -> String {
38 hex::encode(bytes)
39 }
40
41 pub fn hex_to_bytes(hex_str: &str) -> Result<Vec<u8>, hex::FromHexError> {
43 hex::decode(hex_str)
44 }
45
46 pub fn hash_string(data: &str) -> [u8; 32] {
48 sha256_bytes(data.as_bytes())
49 }
50
51 pub fn hash_string_hex(data: &str) -> String {
53 hex::encode(sha256_bytes(data.as_bytes()))
54 }
55
56 pub fn double_hash(data: &[u8]) -> [u8; 32] {
58 let first_hash = sha256_bytes(data);
59 sha256_bytes(&first_hash)
60 }
61
62 pub fn double_hash_hex(data: &[u8]) -> String {
64 hex::encode(Self::double_hash(data))
65 }
66
67 pub fn bytes_equal(a: &[u8], b: &[u8]) -> bool {
69 a == b
70 }
71
72 pub fn verify_hash(data: &[u8], expected_hash: &[u8; 32]) -> bool {
74 &sha256_bytes(data) == expected_hash
75 }
76
77 pub fn verify_hash_hex(data: &[u8], expected_hex: &str) -> bool {
79 let computed_hash = hex::encode(sha256_bytes(data));
80 computed_hash == expected_hex
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use serde_json::json;
88
89 #[test]
90 fn test_sha256_basic() {
91 let data = b"Hello, World!";
92 let hash = HashHelper::sha256(data);
93 let hash_hex = HashHelper::sha256_hex(data);
94
95 assert_eq!(hash.len(), 32);
96 assert_eq!(hash_hex.len(), 64);
97 assert_eq!(hash_hex, hex::encode(hash));
98 }
99
100 #[test]
101 fn test_json_hashing() {
102 let json_data = json!({
103 "test": "data",
104 "number": 42
105 });
106
107 let hash = HashHelper::sha256_json(&json_data);
108 let hash_hex = HashHelper::sha256_json_hex(&json_data);
109
110 assert_eq!(hash.len(), 32);
111 assert_eq!(hash_hex, hex::encode(hash));
112 }
113
114 #[test]
115 fn test_deterministic_json_hashing() {
116 let json1 = json!({"b": 2, "a": 1});
117 let json2 = json!({"a": 1, "b": 2});
118
119 let hash1 = HashHelper::sha256_json_hex(&json1);
120 let hash2 = HashHelper::sha256_json_hex(&json2);
121
122 assert_eq!(hash1, hash2);
124 }
125
126 #[test]
127 fn test_double_hash() {
128 let data = b"test data";
129 let single_hash = HashHelper::sha256(data);
130 let double_hash = HashHelper::double_hash(data);
131
132 assert_ne!(single_hash, double_hash);
134
135 let expected_double = HashHelper::sha256(&single_hash);
137 assert_eq!(double_hash, expected_double);
138 }
139
140 #[test]
141 fn test_hex_conversion() {
142 let data = b"test";
143 let hex = HashHelper::bytes_to_hex(data);
144 let bytes_back = HashHelper::hex_to_bytes(&hex).unwrap();
145
146 assert_eq!(data, &bytes_back[..]);
147 }
148
149 #[test]
150 fn test_hash_verification() {
151 let data = b"verification test";
152 let hash = HashHelper::sha256(data);
153 let hash_hex = HashHelper::sha256_hex(data);
154
155 assert!(HashHelper::verify_hash(data, &hash));
156 assert!(HashHelper::verify_hash_hex(data, &hash_hex));
157
158 assert!(!HashHelper::verify_hash(b"wrong data", &hash));
160 assert!(!HashHelper::verify_hash_hex(b"wrong data", &hash_hex));
161 }
162}