crypto_bigint/modular/
div_by_2.rs1#[cfg(feature = "alloc")]
2use crate::{BoxedUint, ConstantTimeSelect};
3use crate::{Odd, Uint};
4
5pub(crate) const fn div_by_2<const LIMBS: usize>(
6 a: &Uint<LIMBS>,
7 modulus: &Odd<Uint<LIMBS>>,
8) -> Uint<LIMBS> {
9 let (half, is_odd) = a.shr1_with_carry();
23 let half_modulus = modulus.0.shr1();
24
25 let if_even = half;
26 let if_odd = half
27 .wrapping_add(&half_modulus)
28 .wrapping_add(&Uint::<LIMBS>::ONE);
29
30 Uint::<LIMBS>::select(&if_even, &if_odd, is_odd)
31}
32
33#[cfg(feature = "alloc")]
34pub(crate) fn div_by_2_boxed(a: &BoxedUint, modulus: &Odd<BoxedUint>) -> BoxedUint {
35 debug_assert_eq!(a.bits_precision(), modulus.bits_precision());
36
37 let (mut half, is_odd) = a.shr1_with_carry();
38 let half_modulus = modulus.shr1();
39
40 let if_odd = half
41 .wrapping_add(&half_modulus)
42 .wrapping_add(&BoxedUint::one_with_precision(a.bits_precision()));
43
44 half.ct_assign(&if_odd, is_odd);
45
46 half
47}