Skip to content

Commit 8602622

Browse files
committed
Implemented div_by_2 for BoxedResidue
1 parent db33158 commit 8602622

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/modular/boxed_residue.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ use std::sync::Arc;
2121
#[cfg(feature = "zeroize")]
2222
use zeroize::Zeroize;
2323

24+
fn div_by_2(a: &BoxedUint, modulus: &BoxedUint) -> BoxedUint {
25+
let (half, is_odd) = a.shr1_with_carry();
26+
let half_modulus = modulus.shr1();
27+
28+
let if_even = half.clone();
29+
let if_odd = half
30+
.wrapping_add(&half_modulus)
31+
.wrapping_add(&BoxedUint::one_with_precision(a.bits_precision()));
32+
33+
BoxedUint::conditional_select(&if_even, &if_odd, is_odd)
34+
}
35+
2436
/// Parameters to efficiently go to/from the Montgomery form for an odd modulus whose size and value
2537
/// are both chosen at runtime.
2638
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -159,6 +171,18 @@ impl BoxedResidue {
159171
}
160172
}
161173

174+
/// Performs the modular division by 2, that is for given `x` returns `y`
175+
/// such that `y * 2 = x mod p`. This means:
176+
/// - if `x` is even, returns `x / 2`,
177+
/// - if `x` is odd, returns `(x + p) / 2`
178+
/// (since the modulus `p` in Montgomery form is always odd, this divides entirely).
179+
pub fn div_by_2(&self) -> Self {
180+
Self {
181+
montgomery_form: div_by_2(&self.montgomery_form, &self.residue_params.modulus),
182+
residue_params: self.residue_params.clone(),
183+
}
184+
}
185+
162186
/// Instantiates a new [`BoxedResidue`] that represents an integer modulo the provided params.
163187
#[cfg(feature = "std")]
164188
pub fn new_with_arc(mut integer: BoxedUint, residue_params: Arc<BoxedResidueParams>) -> Self {

0 commit comments

Comments
 (0)