1use crate::{CryptoError, HashAlgorithm, Result};
4use digest::Digest;
5
6pub fn sha256(data: &[u8]) -> Vec<u8> {
8 let mut hasher = sha2::Sha256::new();
9 hasher.update(data);
10 hasher.finalize().to_vec()
11}
12
13pub fn sha512(data: &[u8]) -> Vec<u8> {
15 let mut hasher = sha2::Sha512::new();
16 hasher.update(data);
17 hasher.finalize().to_vec()
18}
19
20pub fn blake3(data: &[u8]) -> Vec<u8> {
22 let mut hasher = blake3::Hasher::new();
23 hasher.update(data);
24 hasher.finalize().as_bytes().to_vec()
25}
26
27pub fn hash(data: &[u8], algorithm: HashAlgorithm) -> Result<Vec<u8>> {
29 match algorithm {
30 HashAlgorithm::Sha256 => Ok(sha256(data)),
31 HashAlgorithm::Sha512 => Ok(sha512(data)),
32 HashAlgorithm::Blake3 => Ok(blake3(data)),
33 }
34}
35
36pub fn hash_hex(data: &[u8], algorithm: HashAlgorithm) -> Result<String> {
38 let hash = hash(data, algorithm)?;
39 Ok(hex_encode(&hash))
40}
41
42pub fn hex_encode(data: &[u8]) -> String {
44 data.iter().map(|b| format!("{:02x}", b)).collect()
45}
46
47pub fn hex_decode(s: &str) -> Result<Vec<u8>> {
49 if !s.len().is_multiple_of(2) {
50 return Err(CryptoError::HashError("Invalid hex string".to_string()));
51 }
52
53 (0..s.len())
54 .step_by(2)
55 .map(|i| {
56 u8::from_str_radix(&s[i..i + 2], 16)
57 .map_err(|_| CryptoError::HashError("Invalid hex".to_string()))
58 })
59 .collect()
60}
61
62pub fn hmac_sha256(key: &[u8], data: &[u8]) -> Vec<u8> {
64 use hmac::{Hmac, Mac};
65 use sha2::Sha256;
66
67 let mut mac =
68 Hmac::<Sha256>::new_from_slice(key).expect("HMAC-SHA256 supports arbitrary key sizes");
69 mac.update(data);
70 mac.finalize().into_bytes().to_vec()
71}
72
73pub fn hash_concat(data: &[&[u8]], algorithm: HashAlgorithm) -> Result<Vec<u8>> {
75 match algorithm {
76 HashAlgorithm::Sha256 => {
77 let mut h = sha2::Sha256::new();
78 for d in data {
79 h.update(d);
80 }
81 Ok(h.finalize().to_vec())
82 }
83 HashAlgorithm::Sha512 => {
84 let mut h = sha2::Sha512::new();
85 for d in data {
86 h.update(d);
87 }
88 Ok(h.finalize().to_vec())
89 }
90 HashAlgorithm::Blake3 => {
91 let mut h = blake3::Hasher::new();
92 for d in data {
93 h.update(d);
94 }
95 Ok(h.finalize().as_bytes().to_vec())
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_sha256() {
106 let data = b"hello world";
107 let hash = sha256(data);
108 assert_eq!(hash.len(), 32);
109 }
110
111 #[test]
112 fn test_sha512() {
113 let data = b"hello world";
114 let hash = sha512(data);
115 assert_eq!(hash.len(), 64);
116 }
117
118 #[test]
119 fn test_blake3() {
120 let data = b"hello world";
121 let hash = blake3(data);
122 assert_eq!(hash.len(), 32);
123 }
124
125 #[test]
126 fn test_hex_encode_decode() {
127 let original = b"test data";
128 let encoded = hex_encode(original);
129 let decoded = hex_decode(&encoded).unwrap();
130 assert_eq!(original.as_slice(), decoded.as_slice());
131 }
132
133 #[test]
134 fn test_hmac_sha256() {
135 let key = b"secret_key";
136 let data = b"message";
137 let hmac = hmac_sha256(key, data);
138 assert_eq!(hmac.len(), 32);
139 }
140}