crypto_bigint/uint/
split.rs1use crate::{Split, SplitEven, Uint};
2
3impl<const LIMBS: usize> Uint<LIMBS> {
4 #[must_use]
6 pub const fn split<const HALF_LIMBS: usize>(&self) -> (Uint<HALF_LIMBS>, Uint<HALF_LIMBS>)
7 where
8 Self: SplitEven<Output = Uint<HALF_LIMBS>>,
9 {
10 self.split_resize()
11 }
12
13 #[inline]
15 #[must_use]
16 pub const fn split_mixed<const LO_LIMBS: usize, const HI_LIMBS: usize>(
17 &self,
18 ) -> (Uint<LO_LIMBS>, Uint<HI_LIMBS>)
19 where
20 Self: Split<LO_LIMBS, Output = Uint<HI_LIMBS>>,
21 {
22 self.split_resize()
23 }
24
25 #[inline(always)]
28 #[must_use]
29 pub const fn split_checked<const LO_LIMBS: usize, const HI_LIMBS: usize>(
30 &self,
31 ) -> Option<(Uint<LO_LIMBS>, Uint<HI_LIMBS>)> {
32 if LO_LIMBS + HI_LIMBS == LIMBS {
33 Some(self.split_resize())
34 } else {
35 None
36 }
37 }
38
39 #[inline(always)]
43 #[must_use]
44 pub const fn split_resize<const LO_LIMBS: usize, const HI_LIMBS: usize>(
45 &self,
46 ) -> (Uint<LO_LIMBS>, Uint<HI_LIMBS>) {
47 let lo_len = if LO_LIMBS <= LIMBS { LO_LIMBS } else { LIMBS };
48 let (src_lo, src_hi) = self.as_uint_ref().split_at(lo_len);
49 (src_lo.to_uint_resize(), src_hi.to_uint_resize())
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use crate::{BitOps, U64, U128, U192, U256, Uint};
56
57 #[test]
58 fn split() {
59 let (lo, hi) = U128::from_be_hex("00112233445566778899aabbccddeeff").split();
60 assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
61 assert_eq!(hi, U64::from_u64(0x0011223344556677));
62 }
63
64 #[test]
65 fn split_checked() {
66 let Some((lo, hi)) = U128::from_be_hex("00112233445566778899aabbccddeeff").split_checked()
67 else {
68 panic!("invalid split")
69 };
70 assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
71 assert_eq!(hi, U64::from_u64(0x0011223344556677));
72
73 assert!(
74 U128::from_be_hex("00112233445566778899aabbccddeeff")
75 .split_checked::<8, 10>()
76 .is_none()
77 );
78 }
79
80 #[test]
81 fn split_resize_small() {
82 let (lo, hi) = U256::MAX.split_resize();
83 assert_eq!(lo, U64::MAX);
84 assert_eq!(hi, U64::MAX);
85 }
86
87 #[test]
88 fn split_resize_large() {
89 let (lo, hi) = U128::from_be_hex("00112233445566778899aabbccddeeff").split_resize();
90 assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
91 assert_eq!(hi, U128::from_u64(0x0011223344556677));
92 }
93
94 #[test]
95 fn infer_sizes() {
96 let (lo, hi) = U128::ONE.split();
97 assert_eq!(lo.bits_precision(), 64);
98 assert_eq!(lo, Uint::ONE);
99 assert_eq!(hi.bits_precision(), 64);
100 assert_eq!(hi, Uint::ZERO);
101
102 let (lo, hi) = U192::ONE.split_mixed();
103 assert_eq!(lo, U64::ONE);
104 assert_eq!(hi.bits_precision(), 128);
105 assert_eq!(hi, Uint::ZERO);
106 }
107}