crypto_bigint/modular/
div_by_2.rs1#[cfg(feature = "alloc")]
2use crate::{BoxedUint, Integer};
3use crate::{Limb, 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 is_odd = a.is_odd();
20 let (if_odd, carry) = a.carrying_add(modulus.as_ref(), Limb::ZERO);
21 let carry = Limb::select(Limb::ZERO, carry, is_odd);
22 Uint::<LIMBS>::select(a, &if_odd, is_odd)
23 .shr1()
24 .set_bit(Uint::<LIMBS>::BITS - 1, carry.is_nonzero())
25}
26
27#[cfg(feature = "alloc")]
28pub(crate) fn div_by_2_boxed(a: &BoxedUint, modulus: &Odd<BoxedUint>) -> BoxedUint {
29 let mut result = a.clone();
30 div_by_2_boxed_assign(&mut result, modulus);
31 result
32}
33
34#[cfg(feature = "alloc")]
35pub(crate) fn div_by_2_boxed_assign(a: &mut BoxedUint, modulus: &Odd<BoxedUint>) {
36 debug_assert_eq!(a.bits_precision(), modulus.bits_precision());
37
38 let is_odd = a.is_odd();
39 let carry = a.conditional_carrying_add_assign(modulus, is_odd);
40 a.shr1_assign();
41 a.set_bit(a.bits_precision() - 1, carry);
42}