1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
//! Provides hashing abstractions and implementations including SHA256 and a default dummy hasher.
use sha2::Digest;
/// A trait representing a generic hash function.
///
/// This allows the Merkle tree to use any hash function that conforms to this interface.
pub trait Hasher: Send + Sync {
/// Hashes a sequence of bytes and returns the resulting hash as a hexadecimal string.
fn hash(&self, input: &[u8]) -> String;
}
/// A dummy hasher used for testing or demonstration purposes.
///
/// Always returns a static hash value.
#[derive(Clone, Default)]
pub struct DummyHasher;
impl Hasher for DummyHasher {
fn hash(&self, input: &[u8]) -> String {
let sum: u32 = input.iter().map(|&b| b as u32).sum();
format!("hash_{:x}", sum)
}
}
#[derive(Clone)]
/// A hasher implementation using the SHA-256 cryptographic hash function.
pub struct SHA256Hasher;
impl Default for SHA256Hasher {
fn default() -> Self {
Self::new()
}
}
impl SHA256Hasher {
pub fn new() -> Self {
Self {}
}
}
impl Hasher for SHA256Hasher {
fn hash(&self, input: &[u8]) -> String {
let mut hasher = sha2::Sha256::new();
hasher.update(input);
hex::encode(hasher.finalize())
}
}
#[derive(Clone)]
/// A hasher implementation using the Keccak256 cryptographic hash function.
pub struct Keccak256Hasher;
impl Default for Keccak256Hasher {
fn default() -> Self {
Self::new()
}
}
impl Keccak256Hasher {
pub fn new() -> Self {
Self {}
}
}
impl Hasher for Keccak256Hasher {
fn hash(&self, input: &[u8]) -> String {
let mut hasher = sha3::Keccak256::new();
hasher.update(input);
hex::encode(hasher.finalize())
}
}
#[derive(Clone)]
/// A hasher implementation using the Blake3 cryptographic hash function.
pub struct Blake3Hasher;
impl Default for Blake3Hasher {
fn default() -> Self {
Self::new()
}
}
impl Blake3Hasher {
pub fn new() -> Self {
Self {}
}
}
impl Hasher for Blake3Hasher {
fn hash(&self, input: &[u8]) -> String {
let mut hasher = blake3::Hasher::new();
hasher.update(input);
hasher.finalize().to_hex().to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sha256_hasher_with_known_input() {
let hasher = SHA256Hasher;
let input = "hello".as_bytes();
let expected_hash = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
#[test]
fn test_sha256_hasher_empty_string() {
let hasher = SHA256Hasher;
let input = &[];
let expected_hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
#[test]
fn test_keccak256_hasher_with_known_input() {
let hasher = Keccak256Hasher;
let input = "hello".as_bytes();
let expected_hash = "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
#[test]
fn test_keccak256_hasher_empty_string() {
let hasher = Keccak256Hasher;
let input = &[];
let expected_hash = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
#[test]
fn test_blake3_hasher_with_known_input() {
let hasher = Blake3Hasher;
let input = "hello".as_bytes();
let expected_hash = "ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200f";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
#[test]
fn test_blake3_hasher_empty_string() {
let hasher = Blake3Hasher;
let input = &[];
let expected_hash = "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262";
let actual_hash = hasher.hash(input);
assert_eq!(actual_hash, expected_hash);
}
}
|