1use num_bigint::BigUint;
2
3use crate::UtilsError;
4
5pub fn bigint_to_le_bytes_array<const BYTES_SIZE: usize>(
8 bigint: &BigUint,
9) -> Result<[u8; BYTES_SIZE], UtilsError> {
10 let mut array = [0u8; BYTES_SIZE];
11 let bytes = bigint.to_bytes_le();
12
13 if bytes.len() > BYTES_SIZE {
14 return Err(UtilsError::InputTooLarge(BYTES_SIZE));
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], UtilsError> {
26 let mut array = [0u8; BYTES_SIZE];
27 let bytes = bigint.to_bytes_be();
28
29 if bytes.len() > BYTES_SIZE {
30 return Err(UtilsError::InputTooLarge(BYTES_SIZE));
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], UtilsError> = bigint_to_be_bytes_array(&b8);
248 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
249 let res: Result<[u8; 7], UtilsError> = bigint_to_be_bytes_array(&b8);
250 assert!(matches!(res, Err(UtilsError::InputTooLarge(7))));
251 let res: Result<[u8; 8], UtilsError> = 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], UtilsError> = bigint_to_le_bytes_array(&b8);
256 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
257 let res: Result<[u8; 7], UtilsError> = bigint_to_le_bytes_array(&b8);
258 assert!(matches!(res, Err(UtilsError::InputTooLarge(7))));
259 let res: Result<[u8; 8], UtilsError> = 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], UtilsError> = bigint_to_be_bytes_array(&b16);
264 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
265 let res: Result<[u8; 15], UtilsError> = bigint_to_be_bytes_array(&b16);
266 assert!(matches!(res, Err(UtilsError::InputTooLarge(15))));
267 let res: Result<[u8; 16], UtilsError> = 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], UtilsError> = bigint_to_le_bytes_array(&b16);
272 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
273 let res: Result<[u8; 15], UtilsError> = bigint_to_le_bytes_array(&b16);
274 assert!(matches!(res, Err(UtilsError::InputTooLarge(15))));
275 let res: Result<[u8; 16], UtilsError> = 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], UtilsError> = bigint_to_be_bytes_array(&b32);
280 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
281 let res: Result<[u8; 31], UtilsError> = bigint_to_be_bytes_array(&b32);
282 assert!(matches!(res, Err(UtilsError::InputTooLarge(31))));
283 let res: Result<[u8; 32], UtilsError> = 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], UtilsError> = bigint_to_le_bytes_array(&b32);
288 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
289 let res: Result<[u8; 31], UtilsError> = bigint_to_le_bytes_array(&b32);
290 assert!(matches!(res, Err(UtilsError::InputTooLarge(31))));
291 let res: Result<[u8; 32], UtilsError> = 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], UtilsError> = bigint_to_be_bytes_array(&b64);
296 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
297 let res: Result<[u8; 63], UtilsError> = bigint_to_be_bytes_array(&b64);
298 assert!(matches!(res, Err(UtilsError::InputTooLarge(63))));
299 let res: Result<[u8; 64], UtilsError> = 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], UtilsError> = bigint_to_le_bytes_array(&b64);
304 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
305 let res: Result<[u8; 63], UtilsError> = bigint_to_le_bytes_array(&b64);
306 assert!(matches!(res, Err(UtilsError::InputTooLarge(63))));
307 let res: Result<[u8; 64], UtilsError> = 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], UtilsError> = bigint_to_be_bytes_array(&b128);
312 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
313 let res: Result<[u8; 127], UtilsError> = bigint_to_be_bytes_array(&b128);
314 assert!(matches!(res, Err(UtilsError::InputTooLarge(127))));
315 let res: Result<[u8; 128], UtilsError> = bigint_to_be_bytes_array(&b128);
316 assert!(res.is_ok());
317
318 let b128 = BigUint::from_bytes_le(&[1; 128]);
319 let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b128);
320 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
321 let res: Result<[u8; 127], UtilsError> = bigint_to_le_bytes_array(&b128);
322 assert!(matches!(res, Err(UtilsError::InputTooLarge(127))));
323 let res: Result<[u8; 128], UtilsError> = bigint_to_le_bytes_array(&b128);
324 assert!(res.is_ok());
325
326 let b256 = BigUint::from_bytes_be(&[1; 256]);
327 let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b256);
328 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
329 let res: Result<[u8; 255], UtilsError> = bigint_to_be_bytes_array(&b256);
330 assert!(matches!(res, Err(UtilsError::InputTooLarge(255))));
331 let res: Result<[u8; 256], UtilsError> = bigint_to_be_bytes_array(&b256);
332 assert!(res.is_ok());
333
334 let b256 = BigUint::from_bytes_le(&[1; 256]);
335 let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b256);
336 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
337 let res: Result<[u8; 255], UtilsError> = bigint_to_le_bytes_array(&b256);
338 assert!(matches!(res, Err(UtilsError::InputTooLarge(255))));
339 let res: Result<[u8; 256], UtilsError> = bigint_to_le_bytes_array(&b256);
340 assert!(res.is_ok());
341
342 let b512 = BigUint::from_bytes_be(&[1; 512]);
343 let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b512);
344 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
345 let res: Result<[u8; 511], UtilsError> = bigint_to_be_bytes_array(&b512);
346 assert!(matches!(res, Err(UtilsError::InputTooLarge(511))));
347 let res: Result<[u8; 512], UtilsError> = bigint_to_be_bytes_array(&b512);
348 assert!(res.is_ok());
349
350 let b512 = BigUint::from_bytes_le(&[1; 512]);
351 let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b512);
352 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
353 let res: Result<[u8; 511], UtilsError> = bigint_to_le_bytes_array(&b512);
354 assert!(matches!(res, Err(UtilsError::InputTooLarge(511))));
355 let res: Result<[u8; 512], UtilsError> = bigint_to_le_bytes_array(&b512);
356 assert!(res.is_ok());
357
358 let b768 = BigUint::from_bytes_be(&[1; 768]);
359 let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b768);
360 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
361 let res: Result<[u8; 767], UtilsError> = bigint_to_be_bytes_array(&b768);
362 assert!(matches!(res, Err(UtilsError::InputTooLarge(767))));
363 let res: Result<[u8; 768], UtilsError> = bigint_to_be_bytes_array(&b768);
364 assert!(res.is_ok());
365
366 let b768 = BigUint::from_bytes_le(&[1; 768]);
367 let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b768);
368 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
369 let res: Result<[u8; 767], UtilsError> = bigint_to_le_bytes_array(&b768);
370 assert!(matches!(res, Err(UtilsError::InputTooLarge(767))));
371 let res: Result<[u8; 768], UtilsError> = bigint_to_le_bytes_array(&b768);
372 assert!(res.is_ok());
373
374 let b1024 = BigUint::from_bytes_be(&[1; 1024]);
375 let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b1024);
376 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
377 let res: Result<[u8; 1023], UtilsError> = bigint_to_be_bytes_array(&b1024);
378 assert!(matches!(res, Err(UtilsError::InputTooLarge(1023))));
379 let res: Result<[u8; 1024], UtilsError> = bigint_to_be_bytes_array(&b1024);
380 assert!(res.is_ok());
381
382 let b1024 = BigUint::from_bytes_le(&[1; 1024]);
383 let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b1024);
384 assert!(matches!(res, Err(UtilsError::InputTooLarge(1))));
385 let res: Result<[u8; 1023], UtilsError> = bigint_to_le_bytes_array(&b1024);
386 assert!(matches!(res, Err(UtilsError::InputTooLarge(1023))));
387 let res: Result<[u8; 1024], UtilsError> = bigint_to_le_bytes_array(&b1024);
388 assert!(res.is_ok());
389 }
390}