1use num_bigint::BigUint;
2
3use crate::HasherError;
4
5pub fn bigint_to_le_bytes_array<const BYTES_SIZE: usize>(
8 bigint: &BigUint,
9) -> Result<[u8; BYTES_SIZE], HasherError> {
10 let mut array = [0u8; BYTES_SIZE];
11 let bytes = bigint.to_bytes_le();
12
13 if bytes.len() > BYTES_SIZE {
14 return Err(HasherError::InvalidInputLength(BYTES_SIZE, bytes.len()));
15 }
16
17 array[..bytes.len()].copy_from_slice(bytes.as_slice());
18 Ok(array)
19}
20
21pub fn bigint_to_be_bytes_array<const BYTES_SIZE: usize>(
24 bigint: &BigUint,
25) -> Result<[u8; BYTES_SIZE], HasherError> {
26 let mut array = [0u8; BYTES_SIZE];
27 let bytes = bigint.to_bytes_be();
28
29 if bytes.len() > BYTES_SIZE {
30 return Err(HasherError::InvalidInputLength(BYTES_SIZE, bytes.len()));
31 }
32
33 let start_pos = BYTES_SIZE - bytes.len();
34 array[start_pos..].copy_from_slice(bytes.as_slice());
35 Ok(array)
36}
37
38#[cfg(test)]
39mod test {
40 use num_bigint::{RandBigInt, ToBigUint};
41 use rand::thread_rng;
42
43 use super::*;
44
45 const ITERATIONS: usize = 64;
46
47 #[test]
48 fn test_bigint_conversion_rand() {
49 let mut rng = thread_rng();
50
51 for _ in 0..ITERATIONS {
52 let b64 = rng.gen_biguint(32);
53 let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&b64).unwrap();
54 let b64_converted = BigUint::from_bytes_be(&b64_converted);
55 assert_eq!(b64, b64_converted);
56 let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&b64).unwrap();
57 let b64_converted = BigUint::from_bytes_le(&b64_converted);
58 assert_eq!(b64, b64_converted);
59
60 let b128 = rng.gen_biguint(128);
61 let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&b128).unwrap();
62 let b128_converted = BigUint::from_bytes_be(&b128_converted);
63 assert_eq!(b128, b128_converted);
64 let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&b128).unwrap();
65 let b128_converted = BigUint::from_bytes_le(&b128_converted);
66 assert_eq!(b128, b128_converted);
67
68 let b256 = rng.gen_biguint(256);
69 let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&b256).unwrap();
70 let b256_converted = BigUint::from_bytes_be(&b256_converted);
71 assert_eq!(b256, b256_converted);
72 let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&b256).unwrap();
73 let b256_converted = BigUint::from_bytes_le(&b256_converted);
74 assert_eq!(b256, b256_converted);
75
76 let b320 = rng.gen_biguint(320);
77 let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&b320).unwrap();
78 let b320_converted = BigUint::from_bytes_be(&b320_converted);
79 assert_eq!(b320, b320_converted);
80 let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&b320).unwrap();
81 let b320_converted = BigUint::from_bytes_le(&b320_converted);
82 assert_eq!(b320, b320_converted);
83
84 let b384 = rng.gen_biguint(384);
85 let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&b384).unwrap();
86 let b384_converted = BigUint::from_bytes_be(&b384_converted);
87 assert_eq!(b384, b384_converted);
88 let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&b384).unwrap();
89 let b384_converted = BigUint::from_bytes_le(&b384_converted);
90 assert_eq!(b384, b384_converted);
91
92 let b448 = rng.gen_biguint(448);
93 let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&b448).unwrap();
94 let b448_converted = BigUint::from_bytes_be(&b448_converted);
95 assert_eq!(b448, b448_converted);
96 let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&b448).unwrap();
97 let b448_converted = BigUint::from_bytes_le(&b448_converted);
98 assert_eq!(b448, b448_converted);
99
100 let b768 = rng.gen_biguint(768);
101 let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&b768).unwrap();
102 let b768_converted = BigUint::from_bytes_be(&b768_converted);
103 assert_eq!(b768, b768_converted);
104 let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&b768).unwrap();
105 let b768_converted = BigUint::from_bytes_le(&b768_converted);
106 assert_eq!(b768, b768_converted);
107
108 let b832 = rng.gen_biguint(832);
109 let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&b832).unwrap();
110 let b832_converted = BigUint::from_bytes_be(&b832_converted);
111 assert_eq!(b832, b832_converted);
112 let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&b832).unwrap();
113 let b832_converted = BigUint::from_bytes_le(&b832_converted);
114 assert_eq!(b832, b832_converted);
115 }
116 }
117
118 #[test]
119 fn test_bigint_conversion_zero() {
120 let zero = 0_u32.to_biguint().unwrap();
121
122 let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&zero).unwrap();
123 let b64_converted = BigUint::from_bytes_be(&b64_converted);
124 assert_eq!(zero, b64_converted);
125 let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&zero).unwrap();
126 let b64_converted = BigUint::from_bytes_le(&b64_converted);
127 assert_eq!(zero, b64_converted);
128
129 let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&zero).unwrap();
130 let b128_converted = BigUint::from_bytes_be(&b128_converted);
131 assert_eq!(zero, b128_converted);
132 let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&zero).unwrap();
133 let b128_converted = BigUint::from_bytes_le(&b128_converted);
134 assert_eq!(zero, b128_converted);
135
136 let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&zero).unwrap();
137 let b256_converted = BigUint::from_bytes_be(&b256_converted);
138 assert_eq!(zero, b256_converted);
139 let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&zero).unwrap();
140 let b256_converted = BigUint::from_bytes_le(&b256_converted);
141 assert_eq!(zero, b256_converted);
142
143 let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&zero).unwrap();
144 let b320_converted = BigUint::from_bytes_be(&b320_converted);
145 assert_eq!(zero, b320_converted);
146 let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&zero).unwrap();
147 let b320_converted = BigUint::from_bytes_le(&b320_converted);
148 assert_eq!(zero, b320_converted);
149
150 let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&zero).unwrap();
151 let b384_converted = BigUint::from_bytes_be(&b384_converted);
152 assert_eq!(zero, b384_converted);
153 let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&zero).unwrap();
154 let b384_converted = BigUint::from_bytes_le(&b384_converted);
155 assert_eq!(zero, b384_converted);
156
157 let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&zero).unwrap();
158 let b448_converted = BigUint::from_bytes_be(&b448_converted);
159 assert_eq!(zero, b448_converted);
160 let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&zero).unwrap();
161 let b448_converted = BigUint::from_bytes_le(&b448_converted);
162 assert_eq!(zero, b448_converted);
163
164 let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&zero).unwrap();
165 let b768_converted = BigUint::from_bytes_be(&b768_converted);
166 assert_eq!(zero, b768_converted);
167 let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&zero).unwrap();
168 let b768_converted = BigUint::from_bytes_le(&b768_converted);
169 assert_eq!(zero, b768_converted);
170
171 let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&zero).unwrap();
172 let b832_converted = BigUint::from_bytes_be(&b832_converted);
173 assert_eq!(zero, b832_converted);
174 let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&zero).unwrap();
175 let b832_converted = BigUint::from_bytes_le(&b832_converted);
176 assert_eq!(zero, b832_converted);
177 }
178
179 #[test]
180 fn test_bigint_conversion_one() {
181 let one = 1_u32.to_biguint().unwrap();
182
183 let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&one).unwrap();
184 let b64_converted = BigUint::from_bytes_be(&b64_converted);
185 assert_eq!(one, b64_converted);
186 let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&one).unwrap();
187 let b64_converted = BigUint::from_bytes_le(&b64_converted);
188 assert_eq!(one, b64_converted);
189 let b64 = BigUint::from_bytes_be(&[0, 0, 0, 0, 0, 0, 0, 1]);
190 assert_eq!(one, b64);
191 let b64 = BigUint::from_bytes_le(&[1, 0, 0, 0, 0, 0, 0, 0]);
192 assert_eq!(one, b64);
193
194 let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&one).unwrap();
195 let b128_converted = BigUint::from_bytes_be(&b128_converted);
196 assert_eq!(one, b128_converted);
197 let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&one).unwrap();
198 let b128_converted = BigUint::from_bytes_le(&b128_converted);
199 assert_eq!(one, b128_converted);
200
201 let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&one).unwrap();
202 let b256_converted = BigUint::from_bytes_be(&b256_converted);
203 assert_eq!(one, b256_converted);
204 let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&one).unwrap();
205 let b256_converted = BigUint::from_bytes_le(&b256_converted);
206 assert_eq!(one, b256_converted);
207
208 let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&one).unwrap();
209 let b320_converted = BigUint::from_bytes_be(&b320_converted);
210 assert_eq!(one, b320_converted);
211 let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&one).unwrap();
212 let b320_converted = BigUint::from_bytes_le(&b320_converted);
213 assert_eq!(one, b320_converted);
214
215 let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&one).unwrap();
216 let b384_converted = BigUint::from_bytes_be(&b384_converted);
217 assert_eq!(one, b384_converted);
218 let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&one).unwrap();
219 let b384_converted = BigUint::from_bytes_le(&b384_converted);
220 assert_eq!(one, b384_converted);
221
222 let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&one).unwrap();
223 let b448_converted = BigUint::from_bytes_be(&b448_converted);
224 assert_eq!(one, b448_converted);
225 let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&one).unwrap();
226 let b448_converted = BigUint::from_bytes_le(&b448_converted);
227 assert_eq!(one, b448_converted);
228
229 let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&one).unwrap();
230 let b768_converted = BigUint::from_bytes_be(&b768_converted);
231 assert_eq!(one, b768_converted);
232 let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&one).unwrap();
233 let b768_converted = BigUint::from_bytes_le(&b768_converted);
234 assert_eq!(one, b768_converted);
235
236 let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&one).unwrap();
237 let b832_converted = BigUint::from_bytes_be(&b832_converted);
238 assert_eq!(one, b832_converted);
239 let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&one).unwrap();
240 let b832_converted = BigUint::from_bytes_le(&b832_converted);
241 assert_eq!(one, b832_converted);
242 }
243
244 #[test]
245 fn test_bigint_conversion_invalid_size() {
246 let b8 = BigUint::from_bytes_be(&[1; 8]);
247 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b8);
248 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 8))));
249 let res: Result<[u8; 7], HasherError> = bigint_to_be_bytes_array(&b8);
250 assert!(matches!(res, Err(HasherError::InvalidInputLength(7, 8))));
251 let res: Result<[u8; 8], HasherError> = bigint_to_be_bytes_array(&b8);
252 assert!(res.is_ok());
253
254 let b8 = BigUint::from_bytes_le(&[1; 8]);
255 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b8);
256 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 8))));
257 let res: Result<[u8; 7], HasherError> = bigint_to_le_bytes_array(&b8);
258 assert!(matches!(res, Err(HasherError::InvalidInputLength(7, 8))));
259 let res: Result<[u8; 8], HasherError> = bigint_to_le_bytes_array(&b8);
260 assert!(res.is_ok());
261
262 let b16 = BigUint::from_bytes_be(&[1; 16]);
263 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b16);
264 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 16))));
265 let res: Result<[u8; 15], HasherError> = bigint_to_be_bytes_array(&b16);
266 assert!(matches!(res, Err(HasherError::InvalidInputLength(15, 16))));
267 let res: Result<[u8; 16], HasherError> = bigint_to_be_bytes_array(&b16);
268 assert!(res.is_ok());
269
270 let b16 = BigUint::from_bytes_le(&[1; 16]);
271 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b16);
272 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 16))));
273 let res: Result<[u8; 15], HasherError> = bigint_to_le_bytes_array(&b16);
274 assert!(matches!(res, Err(HasherError::InvalidInputLength(15, 16))));
275 let res: Result<[u8; 16], HasherError> = bigint_to_le_bytes_array(&b16);
276 assert!(res.is_ok());
277
278 let b32 = BigUint::from_bytes_be(&[1; 32]);
279 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b32);
280 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 32))));
281 let res: Result<[u8; 31], HasherError> = bigint_to_be_bytes_array(&b32);
282 assert!(matches!(res, Err(HasherError::InvalidInputLength(31, 32))));
283 let res: Result<[u8; 32], HasherError> = bigint_to_be_bytes_array(&b32);
284 assert!(res.is_ok());
285
286 let b32 = BigUint::from_bytes_le(&[1; 32]);
287 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b32);
288 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 32))));
289 let res: Result<[u8; 31], HasherError> = bigint_to_le_bytes_array(&b32);
290 assert!(matches!(res, Err(HasherError::InvalidInputLength(31, 32))));
291 let res: Result<[u8; 32], HasherError> = bigint_to_le_bytes_array(&b32);
292 assert!(res.is_ok());
293
294 let b64 = BigUint::from_bytes_be(&[1; 64]);
295 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b64);
296 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 64))));
297 let res: Result<[u8; 63], HasherError> = bigint_to_be_bytes_array(&b64);
298 assert!(matches!(res, Err(HasherError::InvalidInputLength(63, 64))));
299 let res: Result<[u8; 64], HasherError> = bigint_to_be_bytes_array(&b64);
300 assert!(res.is_ok());
301
302 let b64 = BigUint::from_bytes_le(&[1; 64]);
303 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b64);
304 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 64))));
305 let res: Result<[u8; 63], HasherError> = bigint_to_le_bytes_array(&b64);
306 assert!(matches!(res, Err(HasherError::InvalidInputLength(63, 64))));
307 let res: Result<[u8; 64], HasherError> = bigint_to_le_bytes_array(&b64);
308 assert!(res.is_ok());
309
310 let b128 = BigUint::from_bytes_be(&[1; 128]);
311 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b128);
312 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 128))));
313 let res: Result<[u8; 127], HasherError> = bigint_to_be_bytes_array(&b128);
314 assert!(matches!(
315 res,
316 Err(HasherError::InvalidInputLength(127, 128))
317 ));
318 let res: Result<[u8; 128], HasherError> = bigint_to_be_bytes_array(&b128);
319 assert!(res.is_ok());
320
321 let b128 = BigUint::from_bytes_le(&[1; 128]);
322 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b128);
323 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 128))));
324 let res: Result<[u8; 127], HasherError> = bigint_to_le_bytes_array(&b128);
325 assert!(matches!(
326 res,
327 Err(HasherError::InvalidInputLength(127, 128))
328 ));
329 let res: Result<[u8; 128], HasherError> = bigint_to_le_bytes_array(&b128);
330 assert!(res.is_ok());
331
332 let b256 = BigUint::from_bytes_be(&[1; 256]);
333 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b256);
334 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 256))));
335 let res: Result<[u8; 255], HasherError> = bigint_to_be_bytes_array(&b256);
336 assert!(matches!(
337 res,
338 Err(HasherError::InvalidInputLength(255, 256))
339 ));
340 let res: Result<[u8; 256], HasherError> = bigint_to_be_bytes_array(&b256);
341 assert!(res.is_ok());
342
343 let b256 = BigUint::from_bytes_le(&[1; 256]);
344 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b256);
345 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 256))));
346 let res: Result<[u8; 255], HasherError> = bigint_to_le_bytes_array(&b256);
347 assert!(matches!(
348 res,
349 Err(HasherError::InvalidInputLength(255, 256))
350 ));
351 let res: Result<[u8; 256], HasherError> = bigint_to_le_bytes_array(&b256);
352 assert!(res.is_ok());
353
354 let b512 = BigUint::from_bytes_be(&[1; 512]);
355 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b512);
356 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 512))));
357 let res: Result<[u8; 511], HasherError> = bigint_to_be_bytes_array(&b512);
358 assert!(matches!(
359 res,
360 Err(HasherError::InvalidInputLength(511, 512))
361 ));
362 let res: Result<[u8; 512], HasherError> = bigint_to_be_bytes_array(&b512);
363 assert!(res.is_ok());
364
365 let b512 = BigUint::from_bytes_le(&[1; 512]);
366 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b512);
367 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 512))));
368 let res: Result<[u8; 511], HasherError> = bigint_to_le_bytes_array(&b512);
369 assert!(matches!(
370 res,
371 Err(HasherError::InvalidInputLength(511, 512))
372 ));
373 let res: Result<[u8; 512], HasherError> = bigint_to_le_bytes_array(&b512);
374 assert!(res.is_ok());
375
376 let b768 = BigUint::from_bytes_be(&[1; 768]);
377 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b768);
378 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 768))));
379 let res: Result<[u8; 767], HasherError> = bigint_to_be_bytes_array(&b768);
380 assert!(matches!(
381 res,
382 Err(HasherError::InvalidInputLength(767, 768))
383 ));
384 let res: Result<[u8; 768], HasherError> = bigint_to_be_bytes_array(&b768);
385 assert!(res.is_ok());
386
387 let b768 = BigUint::from_bytes_le(&[1; 768]);
388 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b768);
389 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 768))));
390 let res: Result<[u8; 767], HasherError> = bigint_to_le_bytes_array(&b768);
391 assert!(matches!(
392 res,
393 Err(HasherError::InvalidInputLength(767, 768))
394 ));
395 let res: Result<[u8; 768], HasherError> = bigint_to_le_bytes_array(&b768);
396 assert!(res.is_ok());
397
398 let b1024 = BigUint::from_bytes_be(&[1; 1024]);
399 let res: Result<[u8; 1], HasherError> = bigint_to_be_bytes_array(&b1024);
400 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 1024))));
401 let res: Result<[u8; 1023], HasherError> = bigint_to_be_bytes_array(&b1024);
402 assert!(matches!(
403 res,
404 Err(HasherError::InvalidInputLength(1023, 1024))
405 ));
406 let res: Result<[u8; 1024], HasherError> = bigint_to_be_bytes_array(&b1024);
407 assert!(res.is_ok());
408
409 let b1024 = BigUint::from_bytes_le(&[1; 1024]);
410 let res: Result<[u8; 1], HasherError> = bigint_to_le_bytes_array(&b1024);
411 assert!(matches!(res, Err(HasherError::InvalidInputLength(1, 1024))));
412 let res: Result<[u8; 1023], HasherError> = bigint_to_le_bytes_array(&b1024);
413 assert!(matches!(
414 res,
415 Err(HasherError::InvalidInputLength(1023, 1024))
416 ));
417 let res: Result<[u8; 1024], HasherError> = bigint_to_le_bytes_array(&b1024);
418 assert!(res.is_ok());
419 }
420}