sp1_curves/
utils.rs

1use num::BigUint;
2
3pub fn biguint_to_bits_le(integer: &BigUint, num_bits: usize) -> Vec<bool> {
4    let byte_vec = integer.to_bytes_le();
5    let mut bits = Vec::new();
6    for byte in byte_vec {
7        for i in 0..8 {
8            bits.push(byte & (1 << i) != 0);
9        }
10    }
11    debug_assert!(bits.len() <= num_bits, "Number too large to fit in {num_bits} digits");
12    bits.resize(num_bits, false);
13    bits
14}
15
16pub fn biguint_to_limbs<const N: usize>(integer: &BigUint) -> [u8; N] {
17    let mut bytes = integer.to_bytes_le();
18    debug_assert!(bytes.len() <= N, "Number too large to fit in {N} limbs");
19    bytes.resize(N, 0u8);
20    let mut limbs = [0u8; N];
21    limbs.copy_from_slice(&bytes);
22    limbs
23}
24
25#[inline]
26pub fn biguint_from_limbs(limbs: &[u8]) -> BigUint {
27    BigUint::from_bytes_le(limbs)
28}
29
30cfg_if::cfg_if! {
31    if #[cfg(feature = "bigint-rug")] {
32        pub fn biguint_to_rug(integer: &BigUint) -> rug::Integer {
33            let mut int = rug::Integer::new();
34            unsafe {
35                int.assign_bytes_radix_unchecked(integer.to_bytes_be().as_slice(), 256, false);
36            }
37            int
38        }
39
40        pub fn rug_to_biguint(integer: &rug::Integer) -> BigUint {
41            let be_bytes = integer.to_digits::<u8>(rug::integer::Order::MsfBe);
42            BigUint::from_bytes_be(&be_bytes)
43        }
44    }
45}