Skip to content

Commit

Permalink
rsa: Use dynamic checks for widening conversions.
Browse files Browse the repository at this point in the history
Remove `SmallerModulus` and instead do the check dynamically. This
eliminates the last `unsafe impl` regarding the modulus
relationships. The uses of `elem_widen` won't ever fail but since
they are in an already-fallible function they wo't hurt.
  • Loading branch information
briansmith committed Nov 24, 2023
1 parent bc8f271 commit a8da5bd
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 19 deletions.
22 changes: 7 additions & 15 deletions src/arithmetic/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,6 @@ mod boxed_limbs;
mod modulus;
mod private_exponent;

/// A modulus *s* that is smaller than another modulus *l* so every element of
/// ℤ/sℤ is also an element of ℤ/lℤ.
///
/// # Safety
///
/// Some logic may assume that the invariant holds when accessing limbs within
/// a value, e.g. by assuming the larger modulus has at least as many limbs.
/// TODO: Any such logic should be encapsulated here, or this trait should be
/// made non-`unsafe`. (In retrospect, this shouldn't have been made an `unsafe`
/// trait preemptively.)
pub unsafe trait SmallerModulus<L> {}

pub trait PublicModulus {}

/// Elements of ℤ/mℤ for some modulus *m*.
Expand Down Expand Up @@ -224,13 +212,17 @@ where
}
}

pub fn elem_widen<Larger, Smaller: SmallerModulus<Larger>>(
pub fn elem_widen<Larger, Smaller>(
a: Elem<Smaller, Unencoded>,
m: &Modulus<Larger>,
) -> Elem<Larger, Unencoded> {
smaller_modulus_bits: BitLength,
) -> Result<Elem<Larger, Unencoded>, error::Unspecified> {
if smaller_modulus_bits >= m.len_bits() {
return Err(error::Unspecified);

Check warning on line 221 in src/arithmetic/bigint.rs

View check run for this annotation

Codecov / codecov/patch

src/arithmetic/bigint.rs#L221

Added line #L221 was not covered by tests
}
let mut r = m.zero();
r.limbs[..a.limbs.len()].copy_from_slice(&a.limbs);
r
Ok(r)
}

// TODO: Document why this works for all Montgomery factors.
Expand Down
7 changes: 3 additions & 4 deletions src/rsa/keypair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,9 @@ fn elem_exp_consttime<M>(

#[derive(Copy, Clone)]
enum P {}
unsafe impl bigint::SmallerModulus<N> for P {}

#[derive(Copy, Clone)]
enum Q {}
unsafe impl bigint::SmallerModulus<N> for Q {}

impl KeyPair {
/// Computes the signature of `msg` and writes it into `signature`.
Expand Down Expand Up @@ -589,11 +587,12 @@ impl KeyPair {
// necessary because `h < p` and `p * q == n` implies `h * q < n`.
// Modular arithmetic is used simply to avoid implementing
// non-modular arithmetic.
let h = bigint::elem_widen(h, n);
let p_bits = self.p.modulus.len_bits();
let h = bigint::elem_widen(h, n, p_bits)?;
let q_mod_n = self.q.modulus.to_elem(n)?;
let q_mod_n = bigint::elem_mul(n_one, q_mod_n, n);
let q_times_h = bigint::elem_mul(&q_mod_n, h, n);
let m_2 = bigint::elem_widen(m_2, n);
let m_2 = bigint::elem_widen(m_2, n, q_bits)?;
let m = bigint::elem_add(m_2, q_times_h, n);

// Step 2.b.v isn't needed since there are only two primes.
Expand Down

0 comments on commit a8da5bd

Please sign in to comment.