Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions benches/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ fn bench_division(c: &mut Criterion) {
b.iter_batched(
|| {
let x = U256::random(&mut OsRng);
let y = Limb::random(&mut OsRng);
let r = Reciprocal::new(y);
let mut y = Limb::random(&mut OsRng);
if y == Limb::ZERO {
y = Limb::ONE;
}
let r = Reciprocal::new(NonZero::new(y).unwrap());
(x, r)
},
|(x, r)| black_box(x.div_rem_limb_with_reciprocal(&r)),
Expand Down
24 changes: 15 additions & 9 deletions src/modular/dyn_residue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use super::{
residue::{Residue, ResidueParams},
Retrieve,
};
use crate::{Limb, Uint, Word};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use crate::{Integer, Limb, NonZero, Uint, Word};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

/// Parameters to efficiently go to/from the Montgomery form for an odd modulus provided at runtime.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand All @@ -35,13 +35,19 @@ pub struct DynResidueParams<const LIMBS: usize> {
impl<const LIMBS: usize> DynResidueParams<LIMBS> {
/// 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.
pub fn new(modulus: &Uint<LIMBS>) -> CtOption<Self> {
let r = Uint::MAX.const_rem(modulus).0.wrapping_add(&Uint::ONE);
let r2 = Uint::const_rem_wide(r.square_wide(), modulus).0;
/// Returns `None` if the provided modulus is not odd.
pub fn new(modulus: &Uint<LIMBS>) -> Option<Self> {
if modulus.is_even().into() {
return None;
}

let nz_modulus = Option::from(NonZero::new(*modulus))?;

let r = Uint::MAX.rem(&nz_modulus).wrapping_add(&Uint::ONE);
let r2 = Uint::rem_wide(r.square_wide(), &nz_modulus);

// If the inverse does not exist, it means the modulus is odd.
let (inv_mod_limb, modulus_is_odd) = modulus.inv_mod2k_vartime(Word::BITS);
// Since the modulus is odd, the inverse exists.
let (inv_mod_limb, _is_some) = modulus.inv_mod2k_vartime(Word::BITS);
let mod_neg_inv = Limb(Word::MIN.wrapping_sub(inv_mod_limb.limbs[0].0));

let r3 = montgomery_reduction(&r2.square_wide(), modulus, mod_neg_inv);
Expand All @@ -54,7 +60,7 @@ impl<const LIMBS: usize> DynResidueParams<LIMBS> {
mod_neg_inv,
};

CtOption::new(params, modulus_is_odd.into())
Some(params)
}

/// Returns the modulus which was used to initialize these parameters.
Expand Down
6 changes: 4 additions & 2 deletions src/modular/residue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ mod pow;
mod sub;

use super::{div_by_2::div_by_2, reduction::montgomery_reduction, Retrieve};
use crate::{Limb, Uint, ZeroConstant};
use crate::{Limb, NonZero, Uint, ZeroConstant};
use core::{fmt::Debug, marker::PhantomData};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};

#[cfg(feature = "rand_core")]
use crate::{rand_core::CryptoRngCore, NonZero, Random, RandomMod};
use crate::{rand_core::CryptoRngCore, Random, RandomMod};

#[cfg(feature = "serde")]
use {
Expand All @@ -39,6 +39,8 @@ pub trait ResidueParams<const LIMBS: usize>:

/// The constant modulus
const MODULUS: Uint<LIMBS>;
/// The constant modulus pre-wrapped in NonZero
const MODULUS_NZ: NonZero<Uint<LIMBS>>;
/// Parameter used in Montgomery reduction
const R: Uint<LIMBS>;
/// R^2, used to move into Montgomery form
Expand Down
11 changes: 7 additions & 4 deletions src/modular/residue/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ macro_rules! impl_modulus {

res
};

// Can unwrap `NonZero::const_new()` here since `MODULUS` was asserted to be non-zero.
const MODULUS_NZ: $crate::NonZero<$uint_type> =
$crate::NonZero::<$uint_type>::const_new(Self::MODULUS).0;

const R: $uint_type = $crate::Uint::MAX
.const_rem(&Self::MODULUS)
.0
.rem(&Self::MODULUS_NZ)
.wrapping_add(&$crate::Uint::ONE);
const R2: $uint_type =
$crate::Uint::const_rem_wide(Self::R.square_wide(), &Self::MODULUS).0;
const R2: $uint_type = $crate::Uint::rem_wide(Self::R.square_wide(), &Self::MODULUS_NZ);
const MOD_NEG_INV: $crate::Limb = $crate::Limb(
$crate::Word::MIN.wrapping_sub(
Self::MODULUS
Expand Down
Loading