crypto_bigint/uint/
concat.rs

1// TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits.
2macro_rules! impl_concat {
3    ($(($name:ident, $bits:expr)),+) => {
4        $(
5            impl $name {
6                /// Concatenate the two values, with `self` as most significant and `rhs`
7                /// as the least significant.
8                pub const fn concat(&self, rhs: &Self) -> UInt<{nlimbs!($bits) * 2}> {
9                    let mut limbs = [Limb::ZERO; nlimbs!($bits) * 2];
10                    let mut i = 0;
11                    let mut j = 0;
12
13                    while j < nlimbs!($bits) {
14                        limbs[i] = rhs.limbs[j];
15                        i += 1;
16                        j += 1;
17                    }
18
19                    j = 0;
20                    while j < nlimbs!($bits) {
21                        limbs[i] = self.limbs[j];
22                        i += 1;
23                        j += 1;
24                    }
25
26                    UInt { limbs }
27                }
28            }
29
30            impl Concat for $name {
31                type Output = UInt<{nlimbs!($bits) * 2}>;
32
33                fn concat(&self, rhs: &Self) -> Self::Output {
34                    self.concat(rhs)
35                }
36            }
37
38            impl From<($name, $name)> for UInt<{nlimbs!($bits) * 2}> {
39                fn from(nums: ($name, $name)) -> UInt<{nlimbs!($bits) * 2}> {
40                    nums.0.concat(&nums.1)
41                }
42            }
43        )+
44     };
45}
46
47#[cfg(test)]
48mod tests {
49    use crate::{U128, U64};
50
51    #[test]
52    fn concat() {
53        let hi = U64::from_u64(0x0011223344556677);
54        let lo = U64::from_u64(0x8899aabbccddeeff);
55        assert_eq!(
56            hi.concat(&lo),
57            U128::from_be_hex("00112233445566778899aabbccddeeff")
58        );
59    }
60}