crypto_bigint/uint/
concat.rs

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