Skip to main content

crypto_bigint/uint/
resize.rs

1//! Support for converting between [`Uint`] instances with different sizes.
2
3use super::Uint;
4use crate::{Choice, CtOption};
5
6impl<const LIMBS: usize> Uint<LIMBS> {
7    /// Construct a [`Uint<T>`] from the unsigned integer value,
8    /// truncating the upper bits if the value is too large to be
9    /// represented.
10    #[inline(always)]
11    #[must_use]
12    pub const fn resize<const T: usize>(&self) -> Uint<T> {
13        self.as_uint_ref().to_uint_resize()
14    }
15
16    /// Construct a [`Uint<T>`] from the unsigned integer value, returning a [`CtOption`]
17    /// which is `is_none` if the upper limbs were non-zero.
18    #[inline(always)]
19    #[must_use]
20    pub const fn resize_checked<const T: usize>(&self) -> CtOption<Uint<T>> {
21        let is_some = if T < LIMBS {
22            self.as_uint_ref().trailing(T).is_zero()
23        } else {
24            Choice::TRUE
25        };
26        CtOption::new(self.resize(), is_some)
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use crate::{U64, U128};
33
34    #[test]
35    fn resize_larger() {
36        let u = U64::from_be_hex("AAAAAAAABBBBBBBB");
37        let u2: U128 = u.resize();
38        assert_eq!(u2, U128::from_be_hex("0000000000000000AAAAAAAABBBBBBBB"));
39        let u3: Option<U128> = u.resize_checked().into_option();
40        assert_eq!(
41            u3,
42            Some(U128::from_be_hex("0000000000000000AAAAAAAABBBBBBBB"))
43        );
44    }
45
46    #[test]
47    fn resize_smaller() {
48        let u = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
49        let u2: U64 = u.resize();
50        assert_eq!(u2, U64::from_be_hex("CCCCCCCCDDDDDDDD"));
51        let u3: Option<U64> = u.resize_checked().into_option();
52        assert_eq!(u3, None);
53        let u4 = U128::ONE.resize_checked().into_option();
54        assert_eq!(u4, Some(U64::ONE));
55    }
56}