Skip to content

Commit

Permalink
Replace BoxedUint::new with ::zero_with_precision (#327)
Browse files Browse the repository at this point in the history
The two APIs are nearly identical. The only difference is the latter is
infallible and panics if an invalid precision is given.

This also changes `BoxedUint::max` to have the same behavior.

Whether they should panic is a debatable point. Indeed having both
options would be good, but it should probably return `CtOption` where
`BoxedUint::max` was returning `Option`.

Regardless, this removes duplication and makes the API at least more
consistent with itself.
  • Loading branch information
tarcieri authored Nov 27, 2023
1 parent 464673b commit e334064
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 37 deletions.
33 changes: 8 additions & 25 deletions src/uint/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,17 @@ impl BoxedUint {
.fold(Choice::from(1), |acc, limb| acc & limb.is_zero())
}

/// Create a new [`BoxedUint`] with the given number of bits of precision.
///
/// Returns `None` if the number of bits is not a multiple of the
/// [`Limb`] size.
pub fn new(bits_precision: usize) -> Option<Self> {
if bits_precision == 0 || bits_precision % Limb::BITS != 0 {
return None;
}

let nlimbs = bits_precision / Limb::BITS;

Some(Self {
limbs: vec![Limb::ZERO; nlimbs].into(),
})
}

/// Get the maximum value for a given number of bits of precision.
///
/// Returns `None` if the number of bits is not a multiple of the
/// [`Limb`] size.
pub fn max(bits_precision: usize) -> Option<Self> {
let mut ret = Self::new(bits_precision)?;

for limb in &mut *ret.limbs {
*limb = Limb::MAX;
}
/// Panics if the precision is not a multiple of [`Limb::BITS`].
pub fn max(bits_precision: usize) -> Self {
assert_eq!(
bits_precision % Limb::BITS,
0,
"precision is not a multiple of limb size"
);

Some(ret)
vec![Limb::MAX; bits_precision / Limb::BITS].into()
}

/// Create a [`BoxedUint`] from an array of [`Word`]s (i.e. word-sized unsigned
Expand Down
8 changes: 2 additions & 6 deletions src/uint/boxed/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ mod tests {

#[test]
fn adc_with_carry() {
let (res, carry) = BoxedUint::max(Limb::BITS)
.unwrap()
.adc(&BoxedUint::one(), Limb::ZERO);
let (res, carry) = BoxedUint::max(Limb::BITS).adc(&BoxedUint::one(), Limb::ZERO);
assert_eq!(res, BoxedUint::zero());
assert_eq!(carry, Limb::ONE);
}
Expand All @@ -54,9 +52,7 @@ mod tests {

#[test]
fn checked_add_overflow() {
let result = BoxedUint::max(Limb::BITS)
.unwrap()
.checked_add(&BoxedUint::one());
let result = BoxedUint::max(Limb::BITS).checked_add(&BoxedUint::one());
assert!(!bool::from(result.is_some()));
}
}
2 changes: 1 addition & 1 deletion src/uint/boxed/bit_and.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ mod tests {

#[test]
fn overlapping_and_ok() {
let result = BoxedUint::max(128).unwrap().wrapping_and(&BoxedUint::one());
let result = BoxedUint::max(128).wrapping_and(&BoxedUint::one());
assert_eq!(result, BoxedUint::one());
}
}
6 changes: 3 additions & 3 deletions src/uint/boxed/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ mod tests {
fn ct_gt() {
let a = BoxedUint::zero();
let b = BoxedUint::one();
let c = BoxedUint::max(64).unwrap();
let c = BoxedUint::max(64);

assert!(bool::from(b.ct_gt(&a)));
assert!(bool::from(c.ct_gt(&a)));
Expand All @@ -110,7 +110,7 @@ mod tests {
fn ct_lt() {
let a = BoxedUint::zero();
let b = BoxedUint::one();
let c = BoxedUint::max(64).unwrap();
let c = BoxedUint::max(64);

assert!(bool::from(a.ct_lt(&b)));
assert!(bool::from(a.ct_lt(&c)));
Expand All @@ -129,7 +129,7 @@ mod tests {
fn cmp() {
let a = BoxedUint::zero();
let b = BoxedUint::one();
let c = BoxedUint::max(64).unwrap();
let c = BoxedUint::max(64);

assert_eq!(a.cmp(&b), Ordering::Less);
assert_eq!(a.cmp(&c), Ordering::Less);
Expand Down
2 changes: 1 addition & 1 deletion src/uint/boxed/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod tests {
#[test]
fn sbb_with_borrow() {
let (res, borrow) = BoxedUint::zero().sbb(&BoxedUint::one(), Limb::ZERO);
assert_eq!(res, BoxedUint::max(Limb::BITS).unwrap());
assert_eq!(res, BoxedUint::max(Limb::BITS));
assert_eq!(borrow, Limb::MAX);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/boxed_uint_proptests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ proptest! {
match Option::<BoxedUint>::from(a.checked_add(&b)) {
Some(actual) => prop_assert_eq!(expected, to_biguint(&actual)),
None => {
let max = BoxedUint::max(a.bits()).unwrap();
let max = BoxedUint::max(a.bits());
prop_assert!(expected > to_biguint(&max));
}
}
Expand Down

0 comments on commit e334064

Please sign in to comment.