diff --git a/src/arithmetic/bigint.rs b/src/arithmetic/bigint.rs index 319738e931..71bdd16223 100644 --- a/src/arithmetic/bigint.rs +++ b/src/arithmetic/bigint.rs @@ -38,7 +38,7 @@ use self::boxed_limbs::BoxedLimbs; pub(crate) use self::{ - modulus::{Modulus, OwnedModulusWithOne, MODULUS_MAX_LIMBS}, + modulus::{Modulus, OwnedModulus, MODULUS_MAX_LIMBS}, private_exponent::PrivateExponent, }; use super::n0::N0; @@ -274,7 +274,7 @@ impl One { // values, using `LIMB_BITS` here, rather than `N0::LIMBS_USED * LIMB_BITS`, // is correct because R**2 will still be a multiple of the latter as // `N0::LIMBS_USED` is either one or two. - fn newRR(m: &Modulus) -> Self { + pub(crate) fn newRR(m: &Modulus) -> Self { // The number of limbs in the numbers involved. let w = m.limbs().len(); @@ -808,8 +808,8 @@ mod tests { |section, test_case| { assert_eq!(section, ""); - let m_ = consume_modulus::(test_case, "M", cpu_features); - let m = m_.modulus(); + let m = consume_modulus::(test_case, "M", cpu_features); + let m = m.modulus(); let expected_result = consume_elem(test_case, "ModExp", &m); let base = consume_elem(test_case, "A", &m); let e = { @@ -817,7 +817,7 @@ mod tests { PrivateExponent::from_be_bytes_for_test_only(untrusted::Input::from(&bytes), &m) .expect("valid exponent") }; - let base = into_encoded(base, &m_); + let base = into_encoded(base, &m); let actual_result = elem_exp_consttime(base, &e, &m).unwrap(); assert_elem_eq(&actual_result, &expected_result); @@ -838,14 +838,14 @@ mod tests { |section, test_case| { assert_eq!(section, ""); - let m_ = consume_modulus::(test_case, "M", cpu_features); - let m = m_.modulus(); + let m = consume_modulus::(test_case, "M", cpu_features); + let m = m.modulus(); let expected_result = consume_elem(test_case, "ModMul", &m); let a = consume_elem(test_case, "A", &m); let b = consume_elem(test_case, "B", &m); - let b = into_encoded(b, &m_); - let a = into_encoded(a, &m_); + let b = into_encoded(b, &m); + let a = into_encoded(a, &m); let actual_result = elem_mul(&a, b, &m); let actual_result = actual_result.into_unencoded(&m); assert_elem_eq(&actual_result, &expected_result); @@ -863,12 +863,12 @@ mod tests { |section, test_case| { assert_eq!(section, ""); - let m_ = consume_modulus::(test_case, "M", cpu_features); - let m = m_.modulus(); + let m = consume_modulus::(test_case, "M", cpu_features); + let m = m.modulus(); let expected_result = consume_elem(test_case, "ModSquare", &m); let a = consume_elem(test_case, "A", &m); - let a = into_encoded(a, &m_); + let a = into_encoded(a, &m); let actual_result = elem_squared(a, &m); let actual_result = actual_result.into_unencoded(&m); assert_elem_eq(&actual_result, &expected_result); @@ -896,7 +896,7 @@ mod tests { let other_modulus_len_bits = m_.len_bits(); let actual_result = elem_reduced(&a, &m, other_modulus_len_bits); - let oneRR = m_.oneRR(); + let oneRR = One::newRR(&m); let actual_result = elem_mul(oneRR.as_ref(), actual_result, &m); assert_elem_eq(&actual_result, &expected_result); @@ -930,7 +930,7 @@ mod tests { #[test] fn test_modulus_debug() { - let modulus = OwnedModulusWithOne::::from_be_bytes( + let modulus = OwnedModulus::::from_be_bytes( untrusted::Input::from(&[0xff; LIMB_BYTES * MODULUS_MIN_LIMBS]), cpu::features(), ) @@ -965,9 +965,9 @@ mod tests { test_case: &mut test::TestCase, name: &str, cpu_features: cpu::Features, - ) -> OwnedModulusWithOne { + ) -> OwnedModulus { let value = test_case.consume_bytes(name); - OwnedModulusWithOne::from_be_bytes(untrusted::Input::from(&value), cpu_features).unwrap() + OwnedModulus::from_be_bytes(untrusted::Input::from(&value), cpu_features).unwrap() } fn consume_nonnegative(test_case: &mut test::TestCase, name: &str) -> Nonnegative { @@ -983,7 +983,8 @@ mod tests { } } - fn into_encoded(a: Elem, m: &OwnedModulusWithOne) -> Elem { - elem_mul(m.oneRR().as_ref(), a, &m.modulus()) + fn into_encoded(a: Elem, m: &Modulus) -> Elem { + let oneRR = One::newRR(m); + elem_mul(oneRR.as_ref(), a, m) } } diff --git a/src/arithmetic/bigint/modulus.rs b/src/arithmetic/bigint/modulus.rs index 3476b74736..6f00f76d11 100644 --- a/src/arithmetic/bigint/modulus.rs +++ b/src/arithmetic/bigint/modulus.rs @@ -12,10 +12,7 @@ // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -use super::{ - super::{montgomery::RR, n0::N0}, - BoxedLimbs, Elem, One, PublicModulus, SmallerModulus, Unencoded, -}; +use super::{super::n0::N0, BoxedLimbs, Elem, PublicModulus, SmallerModulus, Unencoded}; use crate::{ bits::BitLength, cpu, error, @@ -37,7 +34,7 @@ pub const MODULUS_MAX_LIMBS: usize = super::super::BIGINT_MODULUS_MAX_LIMBS; /// for efficient Montgomery multiplication modulo *m*. The value must be odd /// and larger than 2. The larger-than-1 requirement is imposed, at least, by /// the modular inversion code. -pub struct OwnedModulusWithOne { +pub struct OwnedModulus { limbs: BoxedLimbs, // Also `value >= 3`. // n0 * N == -1 (mod r). @@ -77,26 +74,23 @@ pub struct OwnedModulusWithOne { // calculations instead of double-precision `u64` calculations. n0: N0, - oneRR: One, - len_bits: BitLength, cpu_features: cpu::Features, } -impl Clone for OwnedModulusWithOne { +impl Clone for OwnedModulus { fn clone(&self) -> Self { Self { limbs: self.limbs.clone(), n0: self.n0, - oneRR: self.oneRR.clone(), len_bits: self.len_bits, cpu_features: self.cpu_features, } } } -impl core::fmt::Debug for OwnedModulusWithOne { +impl core::fmt::Debug for OwnedModulus { fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> { fmt.debug_struct("Modulus") // TODO: Print modulus value. @@ -104,7 +98,7 @@ impl core::fmt::Debug for OwnedModulusWithOne { } } -impl OwnedModulusWithOne { +impl OwnedModulus { pub(crate) fn from_be_bytes( input: untrusted::Input, cpu_features: cpu::Features, @@ -151,31 +145,15 @@ impl OwnedModulusWithOne { }; let len_bits = limb::limbs_minimal_bits(&n); - let oneRR = { - let partial = Modulus { - limbs: &n, - n0, - len_bits, - m: PhantomData, - cpu_features, - }; - - One::newRR(&partial) - }; Ok(Self { limbs: n, n0, - oneRR, len_bits, cpu_features, }) } - pub fn oneRR(&self) -> &One { - &self.oneRR - } - pub fn to_elem(&self, l: &Modulus) -> Elem where M: SmallerModulus, @@ -202,7 +180,7 @@ impl OwnedModulusWithOne { } } -impl OwnedModulusWithOne { +impl OwnedModulus { pub fn be_bytes(&self) -> LeadingZerosStripped + Clone + '_> { LeadingZerosStripped::new(limb::unstripped_be_bytes(&self.limbs)) } diff --git a/src/rsa/keypair.rs b/src/rsa/keypair.rs index 1df036064c..06851a3743 100644 --- a/src/rsa/keypair.rs +++ b/src/rsa/keypair.rs @@ -18,7 +18,10 @@ use super::{ /// RSA PKCS#1 1.5 signatures. use crate::{ - arithmetic::{bigint, montgomery::R}, + arithmetic::{ + bigint, + montgomery::{R, RR}, + }, bits::BitLength, cpu, digest, error::{self, KeyRejected}, @@ -281,8 +284,8 @@ impl KeyPair { cpu_features, )?; - let n_one = public_key.inner().n().value().oneRR(); - let n = &public_key.inner().n().value().modulus(); + let n_one = public_key.inner().n().oneRR(); + let n = &public_key.inner().n().value(); // 6.4.1.4.3 says to skip 6.4.1.2.1 Step 2. @@ -316,7 +319,7 @@ impl KeyPair { // checking p * q == 0 (mod n) is equivalent to checking p * q == n. let q_mod_n = q.modulus.to_elem(n); let p_mod_n = p.modulus.to_elem(n); - let p_mod_n = bigint::elem_mul(n_one.as_ref(), p_mod_n, n); + let p_mod_n = bigint::elem_mul(n_one, p_mod_n, n); let pq_mod_n = bigint::elem_mul(&q_mod_n, p_mod_n, n); if !pq_mod_n.is_zero() { return Err(KeyRejected::inconsistent_components()); @@ -357,9 +360,9 @@ impl KeyPair { // with an even modulus. // Step 7.f. - let qInv = bigint::elem_mul(p.modulus.oneRR().as_ref(), qInv, pm); + let qInv = bigint::elem_mul(p.oneRR.as_ref(), qInv, pm); let q_mod_p = bigint::elem_reduced(&q_mod_n, pm, q.modulus.len_bits()); - let q_mod_p = bigint::elem_mul(p.modulus.oneRR().as_ref(), q_mod_p, pm); + let q_mod_p = bigint::elem_mul(p.oneRR.as_ref(), q_mod_p, pm); bigint::verify_inverses_consttime(&qInv, q_mod_p, pm) .map_err(|error::Unspecified| KeyRejected::inconsistent_components())?; @@ -397,7 +400,8 @@ impl signature::KeyPair for KeyPair { } struct PrivatePrime { - modulus: bigint::OwnedModulusWithOne, + modulus: bigint::OwnedModulus, + oneRR: bigint::One, exponent: bigint::PrivateExponent, } @@ -410,7 +414,7 @@ impl PrivatePrime { n_bits: BitLength, cpu_features: cpu::Features, ) -> Result { - let p = bigint::OwnedModulusWithOne::from_be_bytes(p, cpu_features)?; + let p = bigint::OwnedModulus::from_be_bytes(p, cpu_features)?; // 5.c / 5.g: // @@ -445,8 +449,11 @@ impl PrivatePrime { return Err(error::KeyRejected::private_modulus_len_not_multiple_of_512_bits()); } + let oneRR = bigint::One::newRR(&p.modulus()); + Ok(Self { modulus: p, + oneRR, exponent: dP, }) } @@ -461,8 +468,8 @@ fn elem_exp_consttime( let c_mod_m = bigint::elem_reduced(c, m, other_prime_len_bits); // We could precompute `oneRRR = elem_squared(&p.oneRR`) as mentioned // in the Smooth CRT-RSA paper. - let c_mod_m = bigint::elem_mul(p.modulus.oneRR().as_ref(), c_mod_m, m); - let c_mod_m = bigint::elem_mul(p.modulus.oneRR().as_ref(), c_mod_m, m); + let c_mod_m = bigint::elem_mul(p.oneRR.as_ref(), c_mod_m, m); + let c_mod_m = bigint::elem_mul(p.oneRR.as_ref(), c_mod_m, m); bigint::elem_exp_consttime(c_mod_m, &p.exponent, m) } @@ -537,9 +544,8 @@ impl KeyPair { // RFC 8017 Section 5.1.2: RSADP, using the Chinese Remainder Theorem // with Garner's algorithm. - let n = self.public.inner().n().value(); - let n_one = n.oneRR(); - let n = &n.modulus(); + let n = &self.public.inner().n().value(); + let n_one = self.public.inner().n().oneRR(); // Step 1. The value zero is also rejected. let base = bigint::Elem::from_be_bytes_padded(untrusted::Input::from(base), n)?; @@ -568,7 +574,7 @@ impl KeyPair { // non-modular arithmetic. let h = bigint::elem_widen(h, n); let q_mod_n = self.q.modulus.to_elem(n); - let q_mod_n = bigint::elem_mul(n_one.as_ref(), q_mod_n, 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 = bigint::elem_add(m_2, q_times_h, n); diff --git a/src/rsa/public_key.rs b/src/rsa/public_key.rs index a10b21fd97..9fd875c870 100644 --- a/src/rsa/public_key.rs +++ b/src/rsa/public_key.rs @@ -145,7 +145,7 @@ impl Inner { base: untrusted::Input, out_buffer: &'out mut [u8; PUBLIC_KEY_PUBLIC_MODULUS_MAX_LEN], ) -> Result<&'out [u8], error::Unspecified> { - let n = &self.n.value().modulus(); + let n = &self.n.value(); // The encoded value of the base must be the same length as the modulus, // in bytes. @@ -177,10 +177,9 @@ impl Inner { // The exponent was already checked to be odd. debug_assert_ne!(exponent_without_low_bit, self.e.value()); - let n_ = self.n.value(); - let n = &n_.modulus(); + let n = &self.n.value(); - let base_r = bigint::elem_mul(n_.oneRR().as_ref(), base.clone(), n); + let base_r = bigint::elem_mul(self.n.oneRR(), base.clone(), n); // During RSA public key operations the exponent is almost always either // 65537 (0b10000000000000001) or 3 (0b11), both of which have a Hamming diff --git a/src/rsa/public_modulus.rs b/src/rsa/public_modulus.rs index 30b85327d7..06365f15a7 100644 --- a/src/rsa/public_modulus.rs +++ b/src/rsa/public_modulus.rs @@ -1,10 +1,15 @@ -use crate::{arithmetic::bigint, bits, cpu, error, rsa::N}; +use crate::{ + arithmetic::{bigint, montgomery::RR}, + bits, cpu, error, + rsa::N, +}; use core::ops::RangeInclusive; /// The modulus (n) of an RSA public key. #[derive(Clone)] pub struct PublicModulus { - value: bigint::OwnedModulusWithOne, + value: bigint::OwnedModulus, + oneRR: bigint::One, } /* @@ -32,7 +37,7 @@ impl PublicModulus { const MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024); // Step 3 / Step c for `n` (out of order). - let value = bigint::OwnedModulusWithOne::from_be_bytes(n, cpu_features)?; + let value = bigint::OwnedModulus::from_be_bytes(n, cpu_features)?; let bits = value.len_bits(); // Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of @@ -47,8 +52,9 @@ impl PublicModulus { if bits > max_bits { return Err(error::KeyRejected::too_large()); } + let oneRR = bigint::One::newRR(&value.modulus()); - Ok(Self { value }) + Ok(Self { value, oneRR }) } /// The big-endian encoding of the modulus. @@ -63,7 +69,11 @@ impl PublicModulus { self.value.len_bits() } - pub(super) fn value(&self) -> &bigint::OwnedModulusWithOne { - &self.value + pub(super) fn value(&self) -> bigint::Modulus { + self.value.modulus() + } + + pub(super) fn oneRR(&self) -> &bigint::Elem { + self.oneRR.as_ref() } }