Skip to content

Commit

Permalink
Optimize add to avoid overflow check (#520)
Browse files Browse the repository at this point in the history
* optimize add to avoid overflow check

* ensure function is evaluated at compile time
  • Loading branch information
schouhy authored Aug 31, 2023
1 parent a22d3b4 commit 4aa2613
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions math/src/field/fields/montgomery_backed_prime_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ where
&M::MODULUS,
&Self::MU,
);
const MODULUS_HAS_ONE_SPARE_BIT: bool = Self::modulus_has_one_spare_bit();

/// Computes `- modulus^{-1} mod 2^{64}`
/// This algorithm is given by Dussé and Kaliski Jr. in
Expand Down Expand Up @@ -97,7 +98,8 @@ where
/// Checks whether the most significant limb of the modulus is at
/// most `0x7FFFFFFFFFFFFFFE`. This check is useful since special
/// optimizations exist for this kind of moduli.
const fn moduli_has_one_spare_bit() -> bool {
#[inline(always)]
const fn modulus_has_one_spare_bit() -> bool {
M::MODULUS.limbs[0] < (1u64 << 63) - 1
}
}
Expand All @@ -111,21 +113,23 @@ where
#[inline(always)]
fn add(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
let (sum, overflow) = UnsignedInteger::add(a, b);
if !overflow {
if Self::MODULUS_HAS_ONE_SPARE_BIT {
if sum >= M::MODULUS {
sum - M::MODULUS
} else {
sum
}
} else {
} else if overflow || sum >= M::MODULUS {
let (diff, _) = UnsignedInteger::sub(&sum, &M::MODULUS);
diff
} else {
sum
}
}

#[inline(always)]
fn mul(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType {
if Self::moduli_has_one_spare_bit() {
if Self::MODULUS_HAS_ONE_SPARE_BIT {
MontgomeryAlgorithms::cios_optimized_for_moduli_with_one_spare_bit(
a,
b,
Expand Down

0 comments on commit 4aa2613

Please sign in to comment.