Skip to content

Commit

Permalink
Fix bernstein_yang_nlimbs! calculation (#610)
Browse files Browse the repository at this point in the history
The previous calculation of the number of unsaturated 62-bit limbs
needed to represent an integer of a given size was incorrect, leading to
miscomputed results as seen in #606.

This commit switches to a much simpler calculation based on
`div_ceiling(62)`, and also adds a const assertion that the computed
number of limbs is sufficient to hold a `$bits`-sized integer.
  • Loading branch information
tarcieri authored Jun 21, 2024
1 parent 2b81eae commit 8a821e9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ macro_rules! nlimbs {

/// Calculate the number of 62-bit unsaturated limbs required to represent the given number of bits when performing
/// Bernstein-Yang inversions.
///
/// We need to ensure that:
///
/// ```text
/// $bits <= (bernstein_yang_nlimbs($bits) * 62) - 64
/// ```
// TODO(tarcieri): replace with `generic_const_exprs` (rust-lang/rust#76560) when stable
macro_rules! bernstein_yang_nlimbs {
($bits:expr) => {
(($bits / 64) + (($bits / 64) * 2).div_ceil(64) + 1)
($bits + 64).div_ceil(62)
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/uint/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ macro_rules! impl_precompute_inverter_trait {
Self::Inverter::new(self, adjuster)
}
}

/// Const assertion that the unsaturated integer is sufficiently sized to hold the maximum
/// value represented by a saturated `$bits`-sized integer.
#[cfg(debug_assertions)]
#[allow(trivial_numeric_casts)]
const _: () = assert!((bernstein_yang_nlimbs!($bits as usize) * 62) - 64 >= $bits);
};
}

Expand Down

0 comments on commit 8a821e9

Please sign in to comment.