1use hmac::{Hmac, Mac};
2use ripemd::{Digest as RipemdDigest, Ripemd160};
3use sha2::{Digest, Sha256, Sha512};
4
5pub trait HashableForVec {
6 fn hash256(&self) -> Vec<u8>;
7 fn ripemd160(&self) -> Vec<u8>;
8 fn sha256_ripemd160(&self) -> Vec<u8>;
9 fn hmac_sha512(&self, key: &[u8]) -> Vec<u8>;
10}
11
12impl HashableForVec for [u8] {
13 fn hash256(&self) -> Vec<u8> {
14 let mut hasher = Sha256::new();
15 hasher.update(self);
16 hasher.finalize().to_vec()
17 }
18
19 fn ripemd160(&self) -> Vec<u8> {
20 let mut hasher = Ripemd160::new();
21 hasher.update(self);
22 hasher.finalize().to_vec()
23 }
24
25 fn sha256_ripemd160(&self) -> Vec<u8> {
26 let mut sha256 = Sha256::new();
27 sha256.update(self);
28 let sha_result = sha256.finalize();
29
30 let mut ripemd = Ripemd160::new();
31 ripemd.update(&sha_result);
32 ripemd.finalize().to_vec()
33 }
34
35 fn hmac_sha512(&self, key: &[u8]) -> Vec<u8> {
36 type HmacSha512 = Hmac<Sha512>;
37 let mut mac = HmacSha512::new_from_slice(key).expect("HMAC can take key of any size");
38 mac.update(self);
39 mac.finalize().into_bytes().to_vec()
40 }
41}
42
43impl HashableForVec for Vec<u8> {
44 fn hash256(&self) -> Vec<u8> {
45 self.as_slice().hash256()
46 }
47
48 fn ripemd160(&self) -> Vec<u8> {
49 self.as_slice().ripemd160()
50 }
51
52 fn sha256_ripemd160(&self) -> Vec<u8> {
53 self.as_slice().sha256_ripemd160()
54 }
55
56 fn hmac_sha512(&self, key: &[u8]) -> Vec<u8> {
57 self.as_slice().hmac_sha512(key)
58 }
59}
60
61fn hex_encode(bytes: &[u8]) -> String {
62 hex::encode(bytes)
63}
64
65pub trait HashableForString {
66 fn hash256(&self) -> String;
67 fn ripemd160(&self) -> String;
68 fn sha256_ripemd160(&self) -> String;
69 fn hmac_sha512(&self, key: &str) -> String;
70 fn hash160(&self) -> String;
71}
72
73impl HashableForString for String {
74 fn hash256(&self) -> String {
75 hex_encode(&self.as_bytes().hash256())
76 }
77
78 fn ripemd160(&self) -> String {
79 hex_encode(&self.as_bytes().ripemd160())
80 }
81
82 fn sha256_ripemd160(&self) -> String {
83 hex_encode(&self.as_bytes().sha256_ripemd160())
84 }
85
86 fn hmac_sha512(&self, key: &str) -> String {
87 hex_encode(&self.as_bytes().hmac_sha512(key.as_bytes()))
88 }
89
90 fn hash160(&self) -> String {
91 let hash = self.as_bytes().sha256_ripemd160();
92 bs58::encode(&hash[..]).into_string()
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_hash256_for_bytes() {
102 let data = b"hello world";
103 let expected = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9";
104 let result = data.hash256();
105 assert_eq!(hex_encode(&result), expected);
106 }
107
108 #[test]
109 fn test_hash256_for_string() {
110 let data = String::from("hello world");
111 let expected = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9";
112 assert_eq!(data.hash256(), expected);
113 }
114
115 #[test]
116 fn test_ripemd160_for_bytes() {
117 let data = b"hello world";
118 let expected = "98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f";
120 let result = data.ripemd160();
121 assert_eq!(hex_encode(&result), expected);
122 }
123
124 #[test]
125 fn test_ripemd160_for_string() {
126 let data = String::from("hello world");
127 let expected = "98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f";
128 assert_eq!(data.ripemd160(), expected);
129 }
130
131 #[test]
132 fn test_sha256_ripemd160_for_bytes() {
133 let data = b"hello world";
134 let expected = "d7d5ee7824ff93f94c3055af9382c86c68b5ca92";
136 let result = data.sha256_ripemd160();
137 assert_eq!(hex_encode(&result), expected);
138 }
139
140 #[test]
141 fn test_sha256_ripemd160_for_string() {
142 let data = String::from("hello world");
143 let expected = "d7d5ee7824ff93f94c3055af9382c86c68b5ca92"; assert_eq!(data.sha256_ripemd160(), expected);
145 }
146
147 #[test]
148 fn test_hmac_sha512_for_bytes() {
149 let data = b"hello world";
150 let key = b"secret";
151 let expected = "6d32239b01dd1750557211629313d95e4f4fcb8ee517e443990ac1afc7562bfd74ffa6118387efd9e168ff86d1da5cef4a55edc63cc4ba289c4c3a8b4f7bdfc2";
153 let result = data.hmac_sha512(key);
154 assert_eq!(hex_encode(&result), expected);
155 }
156
157 #[test]
158 fn test_hmac_sha512_for_string() {
159 let data = String::from("hello world");
160 let key = "secret";
161 let expected = "6d32239b01dd1750557211629313d95e4f4fcb8ee517e443990ac1afc7562bfd74ffa6118387efd9e168ff86d1da5cef4a55edc63cc4ba289c4c3a8b4f7bdfc2";
162 assert_eq!(data.hmac_sha512(key), expected);
163 }
164
165 #[test]
166 fn test_hash160_for_string() {
167 let data = String::from("hello world");
168 let expected = "41QPk1SP3NZmiQxd5jY6HWh1tRcD";
170 assert_eq!(data.hash160(), expected);
171 }
172
173 #[test]
174 fn test_ripemd160_test_vectors() {
175 let test_vectors: &[(&str, &str)] = &[
176 ("", "9c1185a5c5e9fc54612808977ee8f548b2258d31"),
177 ("a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
178 ("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
179 ("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"),
180 ("abcdefghijklmnopqrstuvwxyz", "f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
181 (
182 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
183 "12a053384a9c0c88e405a06c27dcf49ada62eb2b",
184 ),
185 (
186 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
187 "b0e20b6e3116640286ed3a87a5713079b21f5189",
188 ),
189 (
191 "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
192 "9b752e45573d4b39f4dbd3323cab82bf63326bfb",
193 ),
194 (&"a".repeat(1_000_000), "52783243c1697bdbe16d37f97f68f08325dc1528"),
195 ];
196
197 for &(input, expected_hash) in test_vectors {
198 let hash = input.as_bytes().ripemd160();
199 let hex_string = to_hex_string(&hash);
200 assert_eq!(hex_string, expected_hash);
201 }
202 }
203
204 fn to_hex_string(bytes: &[u8]) -> String {
207 bytes.iter().map(|byte| format!("{byte:02x}")).collect()
208 }
209}