crypto_bigint/uint/
concat.rs

1use crate::{Concat, ConcatMixed, Limb, Uint};
2
3impl<const L: usize> Uint<L> {
4    /// Concatenate the two values, with `self` as least significant and `hi` as the most
5    /// significant.
6    pub const fn concat<const O: usize>(&self, hi: &Self) -> Uint<O>
7    where
8        Self: Concat<Output = Uint<O>>,
9    {
10        Uint::concat_mixed(self, hi)
11    }
12
13    /// Concatenate the two values, with `lo` as least significant and `hi`
14    /// as the most significant.
15    #[inline]
16    pub const fn concat_mixed<const H: usize, const O: usize>(lo: &Uint<L>, hi: &Uint<H>) -> Uint<O>
17    where
18        Self: ConcatMixed<Uint<H>, MixedOutput = Uint<O>>,
19    {
20        let top = L + H;
21        let top = if top < O { top } else { O };
22        let mut limbs = [Limb::ZERO; O];
23        let mut i = 0;
24
25        while i < top {
26            if i < L {
27                limbs[i] = lo.limbs[i];
28            } else {
29                limbs[i] = hi.limbs[i - L];
30            }
31            i += 1;
32        }
33
34        Uint { limbs }
35    }
36}
37
38impl<T> Concat for T
39where
40    T: ConcatMixed<T>,
41{
42    type Output = Self::MixedOutput;
43}
44
45#[cfg(test)]
46mod tests {
47    use crate::{ConcatMixed, U128, U192, U64};
48
49    #[test]
50    fn concat() {
51        let hi = U64::from_u64(0x0011223344556677);
52        let lo = U64::from_u64(0x8899aabbccddeeff);
53        assert_eq!(
54            lo.concat(&hi),
55            U128::from_be_hex("00112233445566778899aabbccddeeff")
56        );
57    }
58
59    #[test]
60    fn concat_mixed() {
61        let hi = U64::from_u64(0x0011223344556677);
62        let lo = U128::from_u128(0x8899aabbccddeeff_8899aabbccddeeff);
63        assert_eq!(
64            lo.concat_mixed(&hi),
65            U192::from_be_hex("00112233445566778899aabbccddeeff8899aabbccddeeff")
66        );
67        assert_eq!(
68            hi.concat_mixed(&lo),
69            U192::from_be_hex("8899aabbccddeeff8899aabbccddeeff0011223344556677")
70        );
71    }
72
73    #[test]
74    fn convert() {
75        let res: U128 = U64::ONE.split_mul(&U64::ONE).into();
76        assert_eq!(res, U128::ONE);
77
78        let res: U128 = U64::ONE.square_wide().into();
79        assert_eq!(res, U128::ONE);
80    }
81}