rsa: Stop using Nonnegative in RsaKeyPair to check d.

Check `d` by processing it as a `OwnedModulus` like we do for the
other moduli. This should make the checking more consistent.

As a nice side effect, this eliminates the last non-test usage of
`Nonnegative` and elimnates more now-dead `Nonnegative` code.
This commit is contained in:
Brian Smith 2023-11-22 19:01:26 -08:00
parent 2ad2fcb912
commit 76ce919997
5 changed files with 15 additions and 31 deletions

View File

@ -20,7 +20,7 @@ pub mod bigint;
pub mod montgomery;
mod n0;
#[cfg(feature = "alloc")]
#[cfg(all(test, feature = "alloc"))]
mod nonnegative;
#[allow(dead_code)]

View File

@ -42,7 +42,6 @@ pub(crate) use self::{
private_exponent::PrivateExponent,
};
use super::n0::N0;
pub(crate) use super::nonnegative::Nonnegative;
use crate::{
arithmetic::montgomery::*,
bits::BitLength,
@ -703,21 +702,6 @@ pub fn elem_verify_equal_consttime<M, E>(
}
}
// TODO: Move these methods from `Nonnegative` to `Modulus`.
impl Nonnegative {
pub fn verify_less_than_modulus<M>(&self, m: &Modulus<M>) -> Result<(), error::Unspecified> {
if self.limbs().len() > m.limbs().len() {
return Err(error::Unspecified);
}
if self.limbs().len() == m.limbs().len() {
if limb::limbs_less_than_limbs_consttime(self.limbs(), m.limbs()) != LimbMask::True {
return Err(error::Unspecified);
}
}
Ok(())
}
}
/// r *= a
fn limbs_mont_mul(r: &mut [Limb], a: &[Limb], m: &[Limb], n0: &N0, _cpu_features: cpu::Features) {
debug_assert_eq!(r.len(), m.len());
@ -789,7 +773,7 @@ prefixed_extern! {
#[cfg(test)]
mod tests {
use super::*;
use super::{super::nonnegative::Nonnegative, *};
use crate::test;
// Type-level representation of an arbitrary modulus.

View File

@ -146,13 +146,18 @@ impl<M> OwnedModulus<M> {
})
}
pub fn to_elem<L>(&self, l: &Modulus<L>) -> Result<Elem<L, Unencoded>, error::Unspecified> {
pub fn verify_less_than<L>(&self, l: &Modulus<L>) -> Result<(), error::Unspecified> {
if self.len_bits() > l.len_bits()
|| (self.limbs.len() == l.limbs().len()
&& limb::limbs_less_than_limbs_consttime(&self.limbs, l.limbs()) != LimbMask::True)
{
return Err(error::Unspecified);
}
Ok(())
}
pub fn to_elem<L>(&self, l: &Modulus<L>) -> Result<Elem<L, Unencoded>, error::Unspecified> {
self.verify_less_than(l)?;
let mut limbs = BoxedLimbs::zero(l.limbs.len());
limbs[..self.limbs.len()].copy_from_slice(&self.limbs);
Ok(Elem {

View File

@ -14,7 +14,7 @@
use crate::{
bits, error,
limb::{self, Limb, LimbMask, LIMB_BYTES},
limb::{self, Limb, LIMB_BYTES},
};
use alloc::{vec, vec::Vec};
@ -37,10 +37,6 @@ impl Nonnegative {
Ok((Self { limbs }, r_bits))
}
#[inline]
pub fn is_odd(&self) -> bool {
limb::limbs_are_even_constant_time(&self.limbs) != LimbMask::True
}
#[inline]
pub fn limbs(&self) -> &[Limb] {
&self.limbs

View File

@ -338,18 +338,15 @@ impl KeyPair {
// First, validate `2**half_n_bits < d`. Since 2**half_n_bits has a bit
// length of half_n_bits + 1, this check gives us 2**half_n_bits <= d,
// and knowing d is odd makes the inequality strict.
let (d, d_bits) = bigint::Nonnegative::from_be_bytes_with_bit_length(d)
.map_err(|_| error::KeyRejected::invalid_encoding())?;
if !(n_bits.half_rounded_up() < d_bits) {
let d = bigint::OwnedModulus::<D>::from_be_bytes(d, cpu_features)
.map_err(|_| error::KeyRejected::invalid_component())?;
if !(n_bits.half_rounded_up() < d.len_bits()) {
return Err(KeyRejected::inconsistent_components());
}
// XXX: This check should be `d < LCM(p - 1, q - 1)`, but we don't have
// a good way of calculating LCM, so it is omitted, as explained above.
d.verify_less_than_modulus(n)
d.verify_less_than(n)
.map_err(|error::Unspecified| KeyRejected::inconsistent_components())?;
if !d.is_odd() {
return Err(KeyRejected::invalid_component());
}
// Step 6.b is omitted as explained above.
@ -501,6 +498,8 @@ enum P {}
#[derive(Copy, Clone)]
enum Q {}
enum D {}
impl KeyPair {
/// Computes the signature of `msg` and writes it into `signature`.
///