ciphercore_base/
bytes.rs

1use crate::data_types::scalar_size_in_bytes;
2use crate::data_types::{ScalarType, BIT};
3use crate::errors::Result;
4
5use std::ops::Not;
6
7pub(super) fn add_u64(val1: u64, val2: u64, modulus: Option<u64>) -> u64 {
8    match modulus {
9        Some(m) => {
10            let val = val1 as u128 + val2 as u128;
11            (val % m as u128) as u64
12        }
13        None => val1.wrapping_add(val2),
14    }
15}
16
17pub(super) fn add_u128(val1: u128, val2: u128, modulus: Option<u128>) -> u128 {
18    let val = (val1).wrapping_add(val2);
19    match modulus {
20        Some(m) => val % m,
21        None => val,
22    }
23}
24
25pub(super) fn multiply_u64(val1: u64, val2: u64, modulus: Option<u64>) -> u64 {
26    match modulus {
27        Some(m) => {
28            let val = val1 as u128 * val2 as u128;
29            (val % m as u128) as u64
30        }
31        None => val1.wrapping_mul(val2),
32    }
33}
34
35pub(super) fn multiply_u128(val1: u128, val2: u128, modulus: Option<u128>) -> u128 {
36    let val = val1.wrapping_mul(val2);
37    match modulus {
38        Some(m) => val % m,
39        None => val,
40    }
41}
42
43pub fn add_vectors_u64(vec1: &[u64], vec2: &[u64], modulus: Option<u64>) -> Result<Vec<u64>> {
44    if vec1.len() != vec2.len() {
45        return Err(runtime_error!(
46            "Vectors of different lengths can't be summed"
47        ));
48    }
49    let mut res = vec![];
50    for i in 0..vec1.len() {
51        res.push(add_u64(vec1[i], vec2[i], modulus));
52    }
53    Ok(res)
54}
55
56pub fn add_vectors_u128(vec1: &[u128], vec2: &[u128], modulus: Option<u128>) -> Result<Vec<u128>> {
57    if vec1.len() != vec2.len() {
58        return Err(runtime_error!(
59            "Vectors of different lengths can't be summed"
60        ));
61    }
62    let mut res = vec![];
63    for i in 0..vec1.len() {
64        res.push(add_u128(vec1[i], vec2[i], modulus));
65    }
66    Ok(res)
67}
68
69pub fn sum_vector_u64(vec: &[u64], modulus: Option<u64>) -> u64 {
70    let mut res = 0;
71    for a in vec {
72        res = add_u64(res, *a, modulus);
73    }
74    res
75}
76
77pub fn dot_vectors_u64(vec1: &[u64], vec2: &[u64], modulus: Option<u64>) -> Result<u64> {
78    if vec1.len() != vec2.len() {
79        return Err(runtime_error!(
80            "Vectors of different lengths can't be summed"
81        ));
82    }
83    let mut res = 0;
84    for i in 0..vec1.len() {
85        res = add_u64(res, multiply_u64(vec1[i], vec2[i], modulus), modulus);
86    }
87    Ok(res)
88}
89
90pub fn dot_vectors_u128(vec1: &[u128], vec2: &[u128], modulus: Option<u128>) -> Result<u128> {
91    if vec1.len() != vec2.len() {
92        return Err(runtime_error!(
93            "Vectors of different lengths can't be summed"
94        ));
95    }
96    let mut res = 0;
97    for i in 0..vec1.len() {
98        res = add_u128(res, multiply_u128(vec1[i], vec2[i], modulus), modulus);
99    }
100    Ok(res)
101}
102
103pub fn subtract_vectors_u64(vec1: &[u64], vec2: &[u64], modulus: Option<u64>) -> Result<Vec<u64>> {
104    if vec1.len() != vec2.len() {
105        return Err(runtime_error!(
106            "Vectors of different lengths can't be subtracted"
107        ));
108    }
109    let mut res = vec![];
110    match modulus {
111        Some(m) => {
112            for i in 0..vec1.len() {
113                let mut val = vec1[i] as u128 + (m - vec2[i] % m) as u128;
114                val %= m as u128;
115                res.push(val as u64);
116            }
117        }
118        None => {
119            for i in 0..vec1.len() {
120                res.push(vec1[i].wrapping_sub(vec2[i]));
121            }
122        }
123    }
124    Ok(res)
125}
126pub fn subtract_vectors_u128(
127    vec1: &[u128],
128    vec2: &[u128],
129    modulus: Option<u128>,
130) -> Result<Vec<u128>> {
131    if vec1.len() != vec2.len() {
132        return Err(runtime_error!(
133            "Vectors of different lengths can't be subtracted"
134        ));
135    }
136    let mut res = vec![];
137    for i in 0..vec1.len() {
138        let val = u128::wrapping_sub(vec1[i], vec2[i]);
139        res.push(val);
140    }
141    if let Some(m) = modulus {
142        Ok(res.iter().map(|x| (x % m)).collect())
143    } else {
144        Ok(res)
145    }
146}
147pub fn multiply_vectors_u64(vec1: &[u64], vec2: &[u64], modulus: Option<u64>) -> Result<Vec<u64>> {
148    if vec1.len() != vec2.len() {
149        return Err(runtime_error!(
150            "Vectors of different lengths can't be multiplied"
151        ));
152    }
153    let mut res = vec![];
154    for i in 0..vec1.len() {
155        res.push(multiply_u64(vec1[i], vec2[i], modulus));
156    }
157    Ok(res)
158}
159pub fn multiply_vectors_u128(
160    vec1: &[u128],
161    vec2: &[u128],
162    modulus: Option<u128>,
163) -> Result<Vec<u128>> {
164    if vec1.len() != vec2.len() {
165        return Err(runtime_error!(
166            "Vectors of different lengths can't be multiplied"
167        ));
168    }
169    let mut res = vec![];
170    for i in 0..vec1.len() {
171        res.push(multiply_u128(vec1[i], vec2[i], modulus));
172    }
173    Ok(res)
174}
175
176/// Converts any integer of standard type to u64. This is a generic version of the `as u64`
177/// command that is not supported by any trait in the standard library and thus cannot
178/// support generic input.
179fn as_u64<T: TryInto<u64> + Not<Output = T> + Copy>(x: T) -> Result<u64> {
180    match x.try_into() {
181        Ok(ux) => Ok(ux), // x is a positive integer (try_into passed)
182        Err(_) => {
183            // x is a negative signed integer (try_into failed)
184            // flip the bits of x including the sign bit
185            // e.g. x = 10111000 -> 01000111
186            let neg_x = !x;
187            // now neg_x is a positive integer that should pass through try_into
188            // e.g 01000111 -> 0..001000111
189            let neg_x_u64 = match neg_x.try_into() {
190                Ok(m) => m,
191                Err(_) => {
192                    return Err(runtime_error!("The integer of this size is not supported"));
193                }
194            };
195            // flip the bits again
196            Ok(!neg_x_u64)
197        }
198    }
199}
200
201/// Converts any integer of standard type to u128. This is a generic version of the `as u128`
202/// command that is not supported by any trait in the standard library and thus cannot
203/// support generic input.
204fn as_u128<T: TryInto<u128> + Not<Output = T> + Copy>(x: T) -> Result<u128> {
205    match x.try_into() {
206        Ok(ux) => Ok(ux), // x is a positive integer (try_into passed)
207        Err(_) => {
208            // x is a negative signed integer (try_into failed)
209            // flip the bits of x including the sign bit
210            // e.g. x = 10111000 -> 01000111
211            let neg_x = !x;
212            //now neg_x is a positive integer that should pass through try_into
213            // e.g 01000111 -> 0..001000111
214            let neg_x_u128 = match neg_x.try_into() {
215                Ok(m) => m,
216                Err(_) => {
217                    return Err(runtime_error!("The integer of this size is not supported"));
218                }
219            };
220            // flip the bits again
221            Ok(!neg_x_u128)
222        }
223    }
224}
225
226/// Bytes are presented in the little-endian order
227pub fn vec_to_bytes<T: TryInto<u128> + Not<Output = T> + TryInto<u8> + Copy>(
228    x: &[T],
229    st: ScalarType,
230) -> Result<Vec<u8>> {
231    let mut x_bytes = vec![];
232    match st {
233        BIT => {
234            let iter = x.chunks(8);
235            for slice in iter.clone() {
236                let mut x_byte = 0u8;
237                for (i, bit) in slice.iter().enumerate() {
238                    let bit_u8: u8 = match (*bit).try_into() {
239                        Ok(b) => {
240                            if b > 1 {
241                                return Err(runtime_error!("Input is not a bit"));
242                            } else {
243                                b
244                            }
245                        }
246                        Err(_) => {
247                            return Err(runtime_error!("Input is not a bit"));
248                        }
249                    };
250                    x_byte += bit_u8 << i;
251                }
252                x_bytes.push(x_byte);
253            }
254        }
255        _ => {
256            let byte_length = scalar_size_in_bytes(st) as usize;
257            let x_u128s = vec_as_u128(x)?;
258            for x_u128 in x_u128s {
259                let x_elem_bytes = x_u128.to_le_bytes();
260                for x_elem_byte in x_elem_bytes.iter().take(byte_length) {
261                    x_bytes.push(*x_elem_byte);
262                }
263            }
264        }
265    }
266    Ok(x_bytes)
267}
268
269/// Bytes are presented in the little-endian order
270pub fn vec_u64_to_bytes<T: TryInto<u64> + Not<Output = T> + TryInto<u8> + Copy>(
271    x: &[T],
272    st: ScalarType,
273) -> Result<Vec<u8>> {
274    let mut x_bytes = vec![];
275    match st {
276        BIT => {
277            let iter = x.chunks(8);
278            for slice in iter.clone() {
279                let mut x_byte = 0u8;
280                for (i, bit) in slice.iter().enumerate() {
281                    let bit_u8: u8 = match (*bit).try_into() {
282                        Ok(b) => {
283                            if b > 1 {
284                                return Err(runtime_error!("Input is not a bit"));
285                            } else {
286                                b
287                            }
288                        }
289                        Err(_) => {
290                            return Err(runtime_error!("Input is not a bit"));
291                        }
292                    };
293                    x_byte += bit_u8 << i;
294                }
295                x_bytes.push(x_byte);
296            }
297        }
298        _ => {
299            let byte_length = scalar_size_in_bytes(st) as usize;
300            let x_u64s = vec_as_u64(x)?;
301            for x_u64 in x_u64s {
302                let x_elem_bytes = x_u64.to_le_bytes();
303                for x_elem_byte in x_elem_bytes.iter().take(byte_length) {
304                    x_bytes.push(*x_elem_byte);
305                }
306            }
307        }
308    }
309    Ok(x_bytes)
310}
311
312pub fn vec_as_u64<T: TryInto<u64> + Not<Output = T> + Copy>(x: &[T]) -> Result<Vec<u64>> {
313    x.iter().map(|x| as_u64(*x)).collect::<Result<_>>()
314}
315
316pub fn vec_as_u128<T: TryInto<u128> + Not<Output = T> + Copy>(x: &[T]) -> Result<Vec<u128>> {
317    x.iter().map(|x| as_u128(*x)).collect::<Result<_>>()
318}
319
320/// Can return excess zero elements when ScalarType = BIT and
321/// the number of bits in bytes is bigger than the actual number of packed bits
322pub fn vec_u64_from_bytes(x: &[u8], st: ScalarType) -> Result<Vec<u64>> {
323    let mut x_u64s = vec![];
324    match st {
325        BIT => {
326            for byte in x {
327                for i in 0..8 {
328                    let bit = ((byte >> i) & 1) as u64;
329                    x_u64s.push(bit);
330                }
331            }
332        }
333        _ => {
334            let byte_length = scalar_size_in_bytes(st) as usize;
335            // Whether to look at the leading bit when padding to 8 bytes.
336            let pad_with_sign_bit = st.is_signed() && byte_length < 8;
337            // E.g. 0xFFFFFFFFFFFF0000 if byte_length == 2.
338            let sign_mask = match pad_with_sign_bit {
339                false => 0,
340                true => u64::MAX ^ ((1 << (byte_length * 8)) - 1),
341            };
342            if x.len() % byte_length != 0 {
343                return Err(runtime_error!("Incompatible vector and scalar type"));
344            }
345            for x_slice in x.chunks_exact(byte_length) {
346                let mut res = 0u64;
347                for (i, xi) in x_slice.iter().enumerate() {
348                    res += (*xi as u64) << (i * 8);
349                }
350                if pad_with_sign_bit {
351                    let sign_bit = res >> (byte_length * 8 - 1);
352                    if sign_bit == 1 {
353                        res |= sign_mask;
354                    }
355                }
356                x_u64s.push(res);
357            }
358        }
359    }
360    Ok(x_u64s)
361}
362
363pub fn vec_u128_from_bytes(x: &[u8], st: ScalarType) -> Result<Vec<u128>> {
364    let mut x_u128s = vec![];
365    match st {
366        BIT => {
367            for byte in x {
368                for i in 0..8 {
369                    let bit = ((byte >> i) & 1) as u128;
370                    x_u128s.push(bit);
371                }
372            }
373        }
374        _ => {
375            let byte_length = scalar_size_in_bytes(st) as usize;
376            // Whether to look at the leading bit when padding to 8 bytes.
377            let pad_with_sign_bit = st.is_signed() && byte_length < 16;
378            // E.g. 0xFFFFFFFFFFFF0000 if byte_length == 2.
379            let sign_mask = match pad_with_sign_bit {
380                false => 0,
381                true => u128::MAX ^ ((1 << (byte_length * 8)) - 1),
382            };
383            if x.len() % byte_length != 0 {
384                return Err(runtime_error!("Incompatible vector and scalar type"));
385            }
386            for x_slice in x.chunks_exact(byte_length) {
387                let mut res = 0;
388                for (i, xi) in x_slice.iter().enumerate() {
389                    res += (*xi as u128) << (i * 8);
390                }
391                if pad_with_sign_bit {
392                    let sign_bit = res >> (byte_length * 8 - 1);
393                    if sign_bit == 1 {
394                        res |= sign_mask;
395                    }
396                }
397                x_u128s.push(res);
398            }
399        }
400    }
401    Ok(x_u128s)
402}
403
404#[cfg(test)]
405mod tests {
406    use super::*;
407    use crate::data_types::{
408        BIT, INT128, INT16, INT32, INT64, INT8, UINT128, UINT16, UINT32, UINT64, UINT8,
409    };
410
411    #[test]
412    fn test_as_u64_as_u128() {
413        //correct input
414        for x in [u8::MIN, u8::MAX, 0] {
415            assert_eq!(x as u64, as_u64(x).unwrap());
416            assert_eq!(x as u128, as_u128(x).unwrap());
417        }
418        for x in [i8::MIN, i8::MAX, 0] {
419            assert_eq!(x as u64, as_u64(x).unwrap());
420            assert_eq!(x as u128, as_u128(x).unwrap());
421        }
422        for x in [u16::MIN, u16::MAX, 0] {
423            assert_eq!(x as u64, as_u64(x).unwrap());
424            assert_eq!(x as u128, as_u128(x).unwrap());
425        }
426        for x in [i16::MIN, i16::MAX, 0] {
427            assert_eq!(x as u64, as_u64(x).unwrap());
428            assert_eq!(x as u128, as_u128(x).unwrap());
429        }
430        for x in [u32::MIN, u32::MAX, 0] {
431            assert_eq!(x as u64, as_u64(x).unwrap());
432            assert_eq!(x as u128, as_u128(x).unwrap());
433        }
434        for x in [i32::MIN, i32::MAX, 0] {
435            assert_eq!(x as u64, as_u64(x).unwrap());
436            assert_eq!(x as u128, as_u128(x).unwrap());
437        }
438        for x in [u64::MIN, u64::MAX, 0] {
439            assert_eq!(x as u64, as_u64(x).unwrap());
440            assert_eq!(x as u128, as_u128(x).unwrap());
441        }
442        for x in [i64::MIN, i64::MAX, 0] {
443            assert_eq!(x as u64, as_u64(x).unwrap());
444            assert_eq!(x as u128, as_u128(x).unwrap());
445        }
446        for x in [i128::MIN, i128::MAX, 0] {
447            assert_eq!(x as u128, as_u128(x).unwrap());
448        }
449
450        //malformed input
451        assert!(as_u64(i128::MAX).is_err());
452    }
453
454    fn vec_to_bytes_helper<
455        T: TryInto<u128> + TryInto<u64> + Not<Output = T> + TryInto<u8> + Copy,
456    >(
457        ints: &Vec<T>,
458        bytes: &Vec<u8>,
459        st: ScalarType,
460    ) {
461        let ints_bytes = vec_to_bytes(&ints, st).unwrap();
462        if st.size_in_bits() <= 64 {
463            let from_u64_bytes = vec_u64_to_bytes(&ints, st).unwrap();
464            assert_eq!(ints_bytes, from_u64_bytes);
465        }
466        assert_eq!(ints_bytes, *bytes);
467    }
468    #[test]
469    fn test_vec_to_bytes() {
470        // correct input
471        vec_to_bytes_helper(&vec![0; 1], &vec![0u8], BIT);
472        vec_to_bytes_helper(&vec![1; 12], &vec![255u8, 15u8], BIT);
473        vec_to_bytes_helper(
474            &vec![0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1],
475            &vec![78u8, 9u8],
476            BIT,
477        );
478
479        vec_to_bytes_helper(&vec![0u8, 0u8], &vec![0u8, 0u8], UINT8);
480        vec_to_bytes_helper(&vec![u8::MAX, 100u8], &vec![u8::MAX, 100u8], UINT8);
481
482        vec_to_bytes_helper(&vec![0u16, 0u16], &vec![0u8; 4], UINT16);
483        vec_to_bytes_helper(
484            &vec![u16::MAX, 100u16],
485            &vec![u8::MAX, u8::MAX, 100u8, 0u8],
486            UINT16,
487        );
488
489        vec_to_bytes_helper(&vec![0u32, 0u32], &vec![0u8; 8], UINT32);
490        vec_to_bytes_helper(&vec![u32::MAX, u32::MAX], &vec![u8::MAX; 8], UINT32);
491
492        vec_to_bytes_helper(&vec![0u64, 0u64], &vec![0u8; 16], UINT64);
493        vec_to_bytes_helper(&vec![u64::MAX, u64::MAX], &vec![u8::MAX; 16], UINT64);
494
495        vec_to_bytes_helper(&vec![0u128, 0u128], &vec![0u8; 32], UINT128);
496        vec_to_bytes_helper(&vec![u128::MAX, u128::MAX], &vec![u8::MAX; 32], UINT128);
497
498        vec_to_bytes_helper(&vec![0i8, 0i8], &vec![0u8; 2], INT8);
499        vec_to_bytes_helper(&vec![i8::MIN, i8::MAX], &vec![128u8, 127u8], INT8);
500        vec_to_bytes_helper(&vec![-100i8, 120i8], &vec![156u8, 120u8], INT8);
501
502        vec_to_bytes_helper(&vec![0i16, 0i16], &vec![0u8; 4], INT16);
503        vec_to_bytes_helper(
504            &vec![i16::MIN, i16::MAX],
505            &vec![0u8, 128u8, 255u8, 127u8],
506            INT16,
507        );
508        vec_to_bytes_helper(
509            &vec![-30_000i16, 20_000i16],
510            &vec![208u8, 138u8, 32u8, 78u8],
511            INT16,
512        );
513
514        vec_to_bytes_helper(&vec![0i32, 0i32], &vec![0u8; 8], INT32);
515        vec_to_bytes_helper(
516            &vec![i32::MIN, i32::MAX],
517            &vec![0u8, 0u8, 0u8, 128u8, 255u8, 255u8, 255u8, 127u8],
518            INT32,
519        );
520        vec_to_bytes_helper(
521            &vec![-2_000_000_002i32, 1_900_000_017i32],
522            &vec![254u8, 107u8, 202u8, 136u8, 17u8, 179u8, 63u8, 113u8],
523            INT32,
524        );
525
526        vec_to_bytes_helper(&vec![0i64, 0i64], &vec![0u8; 16], INT64);
527        vec_to_bytes_helper(
528            &vec![i64::MIN, i64::MAX],
529            &vec![
530                0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
531                255u8, 127u8,
532            ],
533            INT64,
534        );
535        vec_to_bytes_helper(
536            &vec![-9_000_000_000_000_000_808i64, 9_100_000_000_000_000_808i64],
537            &vec![
538                216u8, 252u8, 123u8, 29u8, 175u8, 147u8, 25u8, 131u8, 40u8, 3u8, 14u8, 64u8, 201u8,
539                177u8, 73u8, 126u8,
540            ],
541            INT64,
542        );
543
544        vec_to_bytes_helper(&vec![0i128, 0i128], &vec![0u8; 32], INT128);
545        vec_to_bytes_helper(
546            &vec![i128::MIN, i128::MAX],
547            &vec![
548                0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8,
549                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
550                255u8, 255u8, 255u8, 127u8,
551            ],
552            INT128,
553        );
554        vec_to_bytes_helper(
555            &vec![
556                -170_000_000_000_000_000_000_000_000_000_000_000_808i128,
557                170_000_000_000_000_000_000_000_000_000_000_000_808i128,
558            ],
559            &vec![
560                216u8, 252u8, 255u8, 255u8, 95u8, 95u8, 200u8, 239u8, 150u8, 75u8, 129u8, 204u8,
561                225u8, 48u8, 27u8, 128u8, 40u8, 3u8, 0u8, 0u8, 160u8, 160u8, 55u8, 16u8, 105u8,
562                180u8, 126u8, 51u8, 30u8, 207u8, 228u8, 127u8,
563            ],
564            INT128,
565        );
566
567        // malformed input
568        let e = vec_to_bytes(&vec![3, 0], BIT);
569        assert!(e.is_err());
570        let e = vec_to_bytes(&vec![-1, 0], BIT);
571        assert!(e.is_err());
572        let e = vec_u64_to_bytes(&vec![i128::MAX], UINT32);
573        assert!(e.is_err());
574    }
575
576    fn vec_u64_from_bytes_helper(bytes: &Vec<u8>, ints: &Vec<u64>, st: ScalarType) {
577        let bytes_ints = vec_u64_from_bytes(&bytes, st).unwrap();
578        assert_eq!(bytes_ints, *ints);
579    }
580
581    #[test]
582    fn test_vec_u64_from_bytes() {
583        // correct input
584        vec_u64_from_bytes_helper(&vec![0u8], &vec![0; 8], BIT);
585        vec_u64_from_bytes_helper(
586            &vec![129u8, 2u8],
587            &vec![1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
588            BIT,
589        );
590
591        vec_u64_from_bytes_helper(&vec![0u8, 0u8], &vec![0u64, 0u64], UINT8);
592        vec_u64_from_bytes_helper(&vec![255u8, 128u8], &vec![255u64, 128u64], UINT8);
593
594        vec_u64_from_bytes_helper(&vec![0u8; 4], &vec![0u64; 2], UINT16);
595        vec_u64_from_bytes_helper(
596            &vec![255u8, 255u8, 10u8, 100u8],
597            &vec![(1u64 << 16) - 1, 25610u64],
598            UINT16,
599        );
600
601        vec_u64_from_bytes_helper(&vec![0u8; 8], &vec![0u64; 2], UINT32);
602        vec_u64_from_bytes_helper(
603            &vec![255u8, 255u8, 255u8, 255u8, 128u8, 119u8, 142u8, 6u8],
604            &vec![(1u64 << 32) - 1u64, 110_000_000u64],
605            UINT32,
606        );
607
608        vec_u64_from_bytes_helper(&vec![0u8; 16], &vec![0u64; 2], UINT64);
609        vec_u64_from_bytes_helper(
610            &vec![
611                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 1u8, 0u8, 75u8, 205u8,
612                106u8, 204u8, 134u8, 1u8,
613            ],
614            &vec![u64::MAX, 110_000_000_000_000_001u64],
615            UINT64,
616        );
617
618        vec_u64_from_bytes_helper(&vec![0u8, 0u8], &vec![0u64, 0u64], INT8);
619        vec_u64_from_bytes_helper(&vec![255u8, 128u8], &vec![-1i8 as u64, -128i8 as u64], INT8);
620
621        vec_u64_from_bytes_helper(&vec![0u8; 4], &vec![0u64; 2], INT16);
622        vec_u64_from_bytes_helper(
623            &vec![255u8, 255u8, 10u8, 100u8],
624            &vec![-1i16 as u64, 25610u64],
625            INT16,
626        );
627        vec_u64_from_bytes_helper(
628            &vec![156u8, 254u8, 10u8, 100u8],
629            &vec![-356i16 as u64, 25610u64],
630            INT16,
631        );
632
633        vec_u64_from_bytes_helper(&vec![0u8; 8], &vec![0u64; 2], INT32);
634        vec_u64_from_bytes_helper(
635            &vec![255u8, 255u8, 255u8, 255u8, 128u8, 119u8, 142u8, 6u8],
636            &vec![-1i32 as u64, 110_000_000u64],
637            INT32,
638        );
639        vec_u64_from_bytes_helper(
640            &vec![155u8, 200u8, 250u8, 185u8, 128u8, 119u8, 142u8, 6u8],
641            &vec![-1_174_746_981i32 as u64, 110_000_000u64],
642            INT32,
643        );
644
645        vec_u64_from_bytes_helper(&vec![0u8; 16], &vec![0u64; 2], INT64);
646        vec_u64_from_bytes_helper(
647            &vec![
648                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 1u8, 0u8, 75u8, 205u8,
649                106u8, 204u8, 134u8, 1u8,
650            ],
651            &vec![u64::MAX, 110_000_000_000_000_001u64],
652            INT64,
653        );
654        vec_u64_from_bytes_helper(
655            &vec![
656                206u8, 254u8, 155u8, 156u8, 205u8, 252u8, 200u8, 245u8, 1u8, 0u8, 75u8, 205u8,
657                106u8, 204u8, 134u8, 1u8,
658            ],
659            &vec![17_710_683_494_660_439_758u64, 110_000_000_000_000_001u64],
660            INT64,
661        );
662
663        // malformed input
664        let e = vec_u64_from_bytes(&vec![0u8, 0u8, 0u8], UINT16);
665        assert!(e.is_err());
666    }
667    fn vec_u128_from_bytes_helper(bytes: &Vec<u8>, ints: &Vec<u128>, st: ScalarType) {
668        let bytes_ints = vec_u128_from_bytes(&bytes, st).unwrap();
669        assert_eq!(bytes_ints, *ints);
670    }
671    #[test]
672    fn test_vec_u128_from_bytes() {
673        // correct input
674        vec_u128_from_bytes_helper(&vec![0u8], &vec![0; 8], BIT);
675        vec_u128_from_bytes_helper(
676            &vec![129u8, 2u8],
677            &vec![1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
678            BIT,
679        );
680
681        vec_u128_from_bytes_helper(&vec![0u8, 0u8], &vec![0u128, 0u128], UINT8);
682        vec_u128_from_bytes_helper(&vec![255u8, 128u8], &vec![255u128, 128u128], UINT8);
683
684        vec_u128_from_bytes_helper(&vec![0u8; 4], &vec![0u128; 2], UINT16);
685        vec_u128_from_bytes_helper(
686            &vec![255u8, 255u8, 10u8, 100u8],
687            &vec![(1u128 << 16) - 1, 25610u128],
688            UINT16,
689        );
690
691        vec_u128_from_bytes_helper(&vec![0u8; 8], &vec![0u128; 2], UINT32);
692        vec_u128_from_bytes_helper(
693            &vec![255u8, 255u8, 255u8, 255u8, 128u8, 119u8, 142u8, 6u8],
694            &vec![(1u128 << 32) - 1u128, 110_000_000u128],
695            UINT32,
696        );
697
698        vec_u128_from_bytes_helper(&vec![0u8; 16], &vec![0u128; 2], UINT64);
699        vec_u128_from_bytes_helper(
700            &vec![
701                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 1u8, 0u8, 75u8, 205u8,
702                106u8, 204u8, 134u8, 1u8,
703            ],
704            &vec![u64::MAX as u128, 110_000_000_000_000_001u128],
705            UINT64,
706        );
707        vec_u128_from_bytes_helper(&vec![0u8; 32], &vec![0u128; 2], UINT128);
708        vec_u128_from_bytes_helper(
709            &vec![
710                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
711                255u8, 255u8, 255u8, 255u8, 40u8, 3u8, 0u8, 0u8, 160u8, 160u8, 55u8, 16u8, 105u8,
712                180u8, 126u8, 51u8, 30u8, 207u8, 228u8, 127u8,
713            ],
714            &vec![
715                u128::MAX as u128,
716                170_000_000_000_000_000_000_000_000_000_000_000_808u128,
717            ],
718            UINT128,
719        );
720
721        vec_u128_from_bytes_helper(&vec![0u8, 0u8], &vec![0u128, 0u128], INT8);
722        vec_u128_from_bytes_helper(
723            &vec![255u8, 128u8],
724            &vec![-1i8 as u128, -128i8 as u128],
725            INT8,
726        );
727
728        vec_u128_from_bytes_helper(&vec![0u8; 4], &vec![0u128; 2], INT16);
729        vec_u128_from_bytes_helper(
730            &vec![255u8, 255u8, 10u8, 100u8],
731            &vec![-1i16 as u128, 25610u128],
732            INT16,
733        );
734        vec_u128_from_bytes_helper(
735            &vec![156u8, 254u8, 10u8, 100u8],
736            &vec![-356i16 as u128, 25610u128],
737            INT16,
738        );
739
740        vec_u128_from_bytes_helper(&vec![0u8; 8], &vec![0u128; 2], INT32);
741        vec_u128_from_bytes_helper(
742            &vec![255u8, 255u8, 255u8, 255u8, 128u8, 119u8, 142u8, 6u8],
743            &vec![-1i32 as u128, 110_000_000u128],
744            INT32,
745        );
746        vec_u128_from_bytes_helper(
747            &vec![155u8, 200u8, 250u8, 185u8, 128u8, 119u8, 142u8, 6u8],
748            &vec![-1_174_746_981i32 as u128, 110_000_000u128],
749            INT32,
750        );
751
752        vec_u128_from_bytes_helper(&vec![0u8; 16], &vec![0u128; 2], INT64);
753        vec_u128_from_bytes_helper(
754            &vec![
755                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 1u8, 0u8, 75u8, 205u8,
756                106u8, 204u8, 134u8, 1u8,
757            ],
758            &vec![-1i64 as u128, 110_000_000_000_000_001u128],
759            INT64,
760        );
761        vec_u128_from_bytes_helper(
762            &vec![
763                206u8, 254u8, 155u8, 156u8, 205u8, 252u8, 200u8, 245u8, 1u8, 0u8, 75u8, 205u8,
764                106u8, 204u8, 134u8, 1u8,
765            ],
766            &vec![
767                -736_060_579_049_111_858_i64 as u128,
768                110_000_000_000_000_001u128,
769            ],
770            INT64,
771        );
772
773        vec_u128_from_bytes_helper(&vec![0u8; 32], &vec![0u128; 2], INT128);
774        vec_u128_from_bytes_helper(
775            &vec![
776                255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
777                255u8, 255u8, 255u8, 255u8, 40u8, 3u8, 0u8, 0u8, 160u8, 160u8, 55u8, 16u8, 105u8,
778                180u8, 126u8, 51u8, 30u8, 207u8, 228u8, 127u8,
779            ],
780            &vec![
781                -1i128 as u128,
782                170_000_000_000_000_000_000_000_000_000_000_000_808u128,
783            ],
784            INT128,
785        );
786        vec_u128_from_bytes_helper(
787            &vec![
788                216u8, 252u8, 255u8, 255u8, 95u8, 95u8, 200u8, 239u8, 150u8, 75u8, 129u8, 204u8,
789                225u8, 48u8, 27u8, 128u8, 40u8, 3u8, 0u8, 0u8, 160u8, 160u8, 55u8, 16u8, 105u8,
790                180u8, 126u8, 51u8, 30u8, 207u8, 228u8, 127u8,
791            ],
792            &vec![
793                -170_000_000_000_000_000_000_000_000_000_000_000_808i128 as u128,
794                170_000_000_000_000_000_000_000_000_000_000_000_808u128,
795            ],
796            INT128,
797        );
798
799        // malformed input
800        let e = vec_u64_from_bytes(&vec![0u8, 0u8, 0u8], UINT16);
801        assert!(e.is_err());
802    }
803}