1use crate::error::{Error, Result};
6use getrandom;
7
8pub fn constant_time_compare(a: &[u8], b: &[u8]) -> bool {
21 if a.len() != b.len() {
22 return false;
23 }
24
25 let mut result = 0u8;
26 for (x, y) in a.iter().zip(b.iter()) {
27 result |= x ^ y;
28 }
29 result == 0
30}
31
32pub fn random_bytes(length: usize) -> Result<Vec<u8>> {
46 if length == 0 {
48 return Err(Error::InvalidMessageSize { max: 0, actual: 0 });
49 }
50
51 const MAX_RANDOM_SIZE: usize = 1024 * 1024; if length > MAX_RANDOM_SIZE {
54 return Err(Error::InvalidMessageSize {
55 max: MAX_RANDOM_SIZE,
56 actual: length,
57 });
58 }
59
60 let mut bytes = vec![0u8; length];
61 getrandom::fill(&mut bytes).map_err(|_| Error::RandomGenerationFailed {
62 operation: "random_bytes".to_string(),
63 })?;
64
65 Ok(bytes)
66}
67
68pub fn random_nonce(length: usize) -> Result<Vec<u8>> {
78 random_bytes(length)
79}
80
81pub fn bytes_to_hex(bytes: &[u8]) -> String {
91 bytes.iter().map(|b| format!("{b:02x}")).collect()
92}
93
94pub fn hex_to_bytes(hex: &str) -> Result<Vec<u8>> {
108 if hex.is_empty() {
110 return Err(Error::InvalidMessageSize { max: 0, actual: 0 });
111 }
112
113 if hex.len() % 2 != 0 {
114 return Err(Error::InternalError {
115 operation: "hex_to_bytes".to_string(),
116 details: "Hex string length must be even".to_string(),
117 });
118 }
119
120 const MAX_HEX_SIZE: usize = 1024 * 1024; if hex.len() > MAX_HEX_SIZE {
123 return Err(Error::InvalidMessageSize {
124 max: MAX_HEX_SIZE,
125 actual: hex.len(),
126 });
127 }
128
129 let mut bytes = Vec::with_capacity(hex.len() / 2);
130 for i in (0..hex.len()).step_by(2) {
131 let byte = u8::from_str_radix(&hex[i..i + 2], 16).map_err(|_| Error::InternalError {
132 operation: "hex_to_bytes".to_string(),
133 details: "Invalid hex character".to_string(),
134 })?;
135 bytes.push(byte);
136 }
137 Ok(bytes)
138}
139
140pub fn secure_zeroize(data: &mut [u8]) {
149 for byte in data.iter_mut() {
150 *byte = 0;
151 }
152}
153
154pub fn validate_data_size(data: &[u8], min_size: usize, max_size: usize) -> Result<()> {
166 if data.len() < min_size {
167 return Err(Error::InvalidMessageSize {
168 max: min_size,
169 actual: data.len(),
170 });
171 }
172
173 if data.len() > max_size {
174 return Err(Error::InvalidMessageSize {
175 max: max_size,
176 actual: data.len(),
177 });
178 }
179
180 Ok(())
181}
182
183pub fn random_key(size: usize) -> Result<Vec<u8>> {
193 if size == 0 {
195 return Err(Error::InvalidKeySize {
196 expected: 1,
197 actual: 0,
198 });
199 }
200
201 const MAX_KEY_SIZE: usize = 1024 * 1024; if size > MAX_KEY_SIZE {
204 return Err(Error::InvalidKeySize {
205 expected: MAX_KEY_SIZE,
206 actual: size,
207 });
208 }
209
210 random_bytes(size)
211}
212
213#[cfg(test)]
214mod tests {
215 use super::*;
216
217 #[test]
218 fn test_constant_time_compare() {
219 let a = vec![1, 2, 3, 4];
220 let b = vec![1, 2, 3, 4];
221 let c = vec![1, 2, 3, 5];
222 let d = vec![1, 2, 3];
223
224 assert!(constant_time_compare(&a, &b));
225 assert!(!constant_time_compare(&a, &c));
226 assert!(!constant_time_compare(&a, &d));
227 }
228
229 #[test]
230 fn test_random_bytes() {
231 let bytes1 = random_bytes(16).expect("Random bytes generation should succeed");
233 let bytes2 = random_bytes(32).expect("Random bytes generation should succeed");
234
235 assert_eq!(bytes1.len(), 16);
236 assert_eq!(bytes2.len(), 32);
237
238 assert_ne!(bytes1, bytes2);
240
241 assert!(random_bytes(0).is_err());
243 }
244
245 #[test]
246 fn test_bytes_to_hex() {
247 let bytes = vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
248 let hex = bytes_to_hex(&bytes);
249 assert_eq!(hex, "0123456789abcdef");
250 }
251
252 #[test]
253 fn test_hex_to_bytes() {
254 let hex = "0123456789abcdef";
255 let bytes = hex_to_bytes(hex).expect("Hex to bytes conversion should succeed");
256 assert_eq!(bytes, vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
257
258 assert!(hex_to_bytes("123").is_err()); assert!(hex_to_bytes("").is_err()); }
262
263 #[test]
264 fn test_secure_zeroize() {
265 let mut data = vec![1, 2, 3, 4, 5];
266 secure_zeroize(&mut data);
267 assert_eq!(data, vec![0, 0, 0, 0, 0]);
268 }
269
270 #[test]
271 fn test_validate_data_size() {
272 let data = vec![1, 2, 3, 4];
273
274 assert!(validate_data_size(&data, 1, 10).is_ok());
276 assert!(validate_data_size(&data, 4, 4).is_ok());
277
278 assert!(validate_data_size(&data, 5, 10).is_err()); assert!(validate_data_size(&data, 1, 3).is_err()); }
282
283 #[test]
284 fn test_random_key() {
285 let key = random_key(32).expect("Random key generation should succeed");
286 assert_eq!(key.len(), 32);
287
288 assert!(random_key(0).is_err());
290 }
291}