Skip to content

Commit

Permalink
Make DynResidueParams::new fallible (#296)
Browse files Browse the repository at this point in the history
Renames the former `DynResidueParams::new_checked` to `::new`,
eliminating the potential panic condition and returning `CtOption`
instead.
  • Loading branch information
tarcieri authored Nov 21, 2023
1 parent b0a566c commit eba9b64
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 41 deletions.
8 changes: 4 additions & 4 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn bench_division<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
}

fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE));
let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE)).unwrap();
group.bench_function("multiplication, U256*U256", |b| {
b.iter_batched(
|| {
Expand All @@ -88,7 +88,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
});

let m = U256::random(&mut OsRng) | U256::ONE;
let params = DynResidueParams::new(&m);
let params = DynResidueParams::new(&m).unwrap();
group.bench_function("modpow, U256^U256", |b| {
b.iter_batched(
|| {
Expand Down Expand Up @@ -140,7 +140,7 @@ fn bench_montgomery_conversion<M: Measurement>(group: &mut BenchmarkGroup<'_, M>
)
});

let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE));
let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE)).unwrap();
group.bench_function("DynResidue creation", |b| {
b.iter_batched(
|| U256::random(&mut OsRng),
Expand All @@ -149,7 +149,7 @@ fn bench_montgomery_conversion<M: Measurement>(group: &mut BenchmarkGroup<'_, M>
)
});

let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE));
let params = DynResidueParams::new(&(U256::random(&mut OsRng) | U256::ONE)).unwrap();
group.bench_function("DynResidue retrieve", |b| {
b.iter_batched(
|| DynResidue::new(&U256::random(&mut OsRng), params),
Expand Down
36 changes: 5 additions & 31 deletions src/uint/modular/runtime_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,10 @@ impl<const LIMBS: usize> DynResidueParams<LIMBS> {
}
}

/// Instantiates a new set of `ResidueParams` representing the given `modulus`, which _must_ be odd.
/// If `modulus` is not odd, this function will panic; use [`new_checked`][`DynResidueParams::new_checked`] if you want to be able to detect an invalid modulus.
pub const fn new(modulus: &Uint<LIMBS>) -> Self {
// A valid modulus must be odd
if modulus.ct_is_odd().to_u8() == 0 {
panic!("modulus must be odd");
}

Self::generate_params(modulus)
}

/// Instantiates a new set of `ResidueParams` representing the given `modulus` if it is odd.
/// Returns a `CtOption` that is `None` if the provided modulus is not odd; this is a safer version of [`new`][`DynResidueParams::new`], which can panic.
#[deprecated(
since = "0.5.3",
note = "This functionality will be moved to `new` in a future release."
)]
pub fn new_checked(modulus: &Uint<LIMBS>) -> CtOption<Self> {
// A valid modulus must be odd.
///
/// Returns a `CtOption` that is `None` if the provided modulus is not odd.
pub fn new(modulus: &Uint<LIMBS>) -> CtOption<Self> {
CtOption::new(Self::generate_params(modulus), modulus.ct_is_odd().into())
}

Expand Down Expand Up @@ -273,28 +258,17 @@ mod test {
const LIMBS: usize = nlimbs!(64);

#[test]
#[allow(deprecated)]
// Test that a valid modulus yields `DynResidueParams`
fn test_valid_modulus() {
let valid_modulus = Uint::<LIMBS>::from(3u8);

DynResidueParams::<LIMBS>::new_checked(&valid_modulus).unwrap();
DynResidueParams::<LIMBS>::new(&valid_modulus);
DynResidueParams::<LIMBS>::new(&valid_modulus).unwrap();
}

#[test]
#[allow(deprecated)]
// Test that an invalid checked modulus does not yield `DynResidueParams`
fn test_invalid_checked_modulus() {
assert!(bool::from(
DynResidueParams::<LIMBS>::new_checked(&Uint::from(2u8)).is_none()
DynResidueParams::<LIMBS>::new(&Uint::from(2u8)).is_none()
))
}

#[test]
#[should_panic]
// Tets that an invalid modulus panics
fn test_invalid_modulus() {
DynResidueParams::<LIMBS>::new(&Uint::from(2u8));
}
}
3 changes: 2 additions & 1 deletion src/uint/modular/runtime_mod/runtime_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ mod tests {
fn add_overflow() {
let params = DynResidueParams::new(&U256::from_be_hex(
"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
));
))
.unwrap();

let x =
U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
Expand Down
3 changes: 2 additions & 1 deletion src/uint/modular/runtime_mod/runtime_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ mod tests {
fn sub_overflow() {
let params = DynResidueParams::new(&U256::from_be_hex(
"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
));
))
.unwrap();

let x =
U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
Expand Down
7 changes: 3 additions & 4 deletions tests/proptests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ proptest! {

let expected = to_uint(a_bi.modpow(&b_bi, &p_bi));

let params = DynResidueParams::new(&P);
let params = DynResidueParams::new(&P).unwrap();
let a_m = DynResidue::new(&a, params);
let actual = a_m.pow(&b).retrieve();

Expand All @@ -331,7 +331,6 @@ proptest! {

#[test]
fn residue_pow_bounded_exp(a in uint_mod_p(P), b in uint(), exponent_bits in any::<u8>()) {

let b_masked = b & (U256::ONE << exponent_bits.into()).wrapping_sub(&U256::ONE);

let a_bi = to_biguint(&a);
Expand All @@ -340,7 +339,7 @@ proptest! {

let expected = to_uint(a_bi.modpow(&b_bi, &p_bi));

let params = DynResidueParams::new(&P);
let params = DynResidueParams::new(&P).unwrap();
let a_m = DynResidue::new(&a, params);
let actual = a_m.pow_bounded_exp(&b, exponent_bits.into()).retrieve();

Expand All @@ -361,7 +360,7 @@ proptest! {
};
let expected = to_uint(expected);

let params = DynResidueParams::new(&P);
let params = DynResidueParams::new(&P).unwrap();
let a_m = DynResidue::new(&a, params);
let actual = a_m.div_by_2().retrieve();

Expand Down

0 comments on commit eba9b64

Please sign in to comment.