Rename PartialModulus to Modulus, Modulus to OwnedModulusWithOne.
Originally we only had `Modulus`. Then we had a need for a temporary `Modulus` without `oneRR` so we created `PartialModulus`. However, there is really nothing "partial" about them. So, improve the naming by renaming `PartialModulus` to `Modulus` and `Modulus` to `OwnedModulusWithOne`. In the future we may refactor things further to separate the ownership aspect from the "has oneRR" aspect. Instead of just doing a straightforward rename, take this opportunity to refactor the code so that it uses the new `Modulus` whenever `oneRR()` isn't used. This eliminates the duplication of the APIs of the two modulus types, and the duplication of `elem_mul` and `elem_mul_`.
This commit is contained in:
parent
69d1dd34e6
commit
e51c88a986
@ -38,7 +38,7 @@
|
||||
|
||||
use self::boxed_limbs::BoxedLimbs;
|
||||
pub(crate) use self::{
|
||||
modulus::{Modulus, PartialModulus, MODULUS_MAX_LIMBS},
|
||||
modulus::{Modulus, OwnedModulusWithOne, MODULUS_MAX_LIMBS},
|
||||
private_exponent::PrivateExponent,
|
||||
};
|
||||
use super::n0::N0;
|
||||
@ -186,20 +186,9 @@ impl<M> Elem<M, Unencoded> {
|
||||
}
|
||||
|
||||
pub fn elem_mul<M, AF, BF>(
|
||||
a: &Elem<M, AF>,
|
||||
b: Elem<M, BF>,
|
||||
m: &Modulus<M>,
|
||||
) -> Elem<M, <(AF, BF) as ProductEncoding>::Output>
|
||||
where
|
||||
(AF, BF): ProductEncoding,
|
||||
{
|
||||
elem_mul_(a, b, &m.as_partial())
|
||||
}
|
||||
|
||||
fn elem_mul_<M, AF, BF>(
|
||||
a: &Elem<M, AF>,
|
||||
mut b: Elem<M, BF>,
|
||||
m: &PartialModulus<M>,
|
||||
m: &Modulus<M>,
|
||||
) -> Elem<M, <(AF, BF) as ProductEncoding>::Output>
|
||||
where
|
||||
(AF, BF): ProductEncoding,
|
||||
@ -211,7 +200,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn elem_mul_by_2<M, AF>(a: &mut Elem<M, AF>, m: &PartialModulus<M>) {
|
||||
fn elem_mul_by_2<M, AF>(a: &mut Elem<M, AF>, m: &Modulus<M>) {
|
||||
prefixed_extern! {
|
||||
fn LIMBS_shl_mod(r: *mut Limb, a: *const Limb, m: *const Limb, num_limbs: c::size_t);
|
||||
}
|
||||
@ -254,7 +243,7 @@ pub fn elem_reduced<Larger, Smaller: NotMuchSmallerModulus<Larger>>(
|
||||
|
||||
fn elem_squared<M, E>(
|
||||
mut a: Elem<M, E>,
|
||||
m: &PartialModulus<M>,
|
||||
m: &Modulus<M>,
|
||||
) -> Elem<M, <(E, E) as ProductEncoding>::Output>
|
||||
where
|
||||
(E, E): ProductEncoding,
|
||||
@ -316,7 +305,7 @@ impl<M> One<M, RR> {
|
||||
// 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: &PartialModulus<M>, m_bits: bits::BitLength) -> Self {
|
||||
fn newRR(m: &Modulus<M>, m_bits: bits::BitLength) -> Self {
|
||||
let m_bits = m_bits.as_usize_bits();
|
||||
let r = (m_bits + (LIMB_BITS - 1)) / LIMB_BITS * LIMB_BITS;
|
||||
|
||||
@ -390,7 +379,7 @@ impl<M: PublicModulus, E> Clone for One<M, E> {
|
||||
pub(crate) fn elem_exp_vartime<M>(
|
||||
base: Elem<M, R>,
|
||||
exponent: NonZeroU64,
|
||||
m: &PartialModulus<M>,
|
||||
m: &Modulus<M>,
|
||||
) -> Elem<M, R> {
|
||||
// Use what [Knuth] calls the "S-and-X binary method", i.e. variable-time
|
||||
// square-and-multiply that scans the exponent from the most significant
|
||||
@ -417,7 +406,7 @@ pub(crate) fn elem_exp_vartime<M>(
|
||||
bit >>= 1;
|
||||
acc = elem_squared(acc, m);
|
||||
if (exponent & bit) != 0 {
|
||||
acc = elem_mul_(&base, acc, m);
|
||||
acc = elem_mul(&base, acc, m);
|
||||
}
|
||||
}
|
||||
acc
|
||||
@ -426,17 +415,20 @@ pub(crate) fn elem_exp_vartime<M>(
|
||||
/// Uses Fermat's Little Theorem to calculate modular inverse in constant time.
|
||||
pub fn elem_inverse_consttime<M: Prime>(
|
||||
a: Elem<M, R>,
|
||||
m: &Modulus<M>,
|
||||
m: &OwnedModulusWithOne<M>,
|
||||
) -> Result<Elem<M, Unencoded>, error::Unspecified> {
|
||||
elem_exp_consttime(a, &PrivateExponent::for_flt(m), m)
|
||||
elem_exp_consttime(a, &PrivateExponent::for_flt(&m.modulus()), m)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
pub fn elem_exp_consttime<M>(
|
||||
base: Elem<M, R>,
|
||||
exponent: &PrivateExponent,
|
||||
m: &Modulus<M>,
|
||||
m: &OwnedModulusWithOne<M>,
|
||||
) -> Result<Elem<M, Unencoded>, error::Unspecified> {
|
||||
let oneRR = m.oneRR();
|
||||
let m = &m.modulus();
|
||||
|
||||
use crate::{bssl, limb::Window};
|
||||
|
||||
const WINDOW_BITS: usize = 5;
|
||||
@ -469,7 +461,7 @@ pub fn elem_exp_consttime<M>(
|
||||
mut tmp: Elem<M, R>,
|
||||
) -> (Elem<M, R>, Elem<M, R>) {
|
||||
for _ in 0..WINDOW_BITS {
|
||||
acc = elem_squared(acc, &m.as_partial());
|
||||
acc = elem_squared(acc, m);
|
||||
}
|
||||
gather(table, &mut tmp, i);
|
||||
let acc = elem_mul(&tmp, acc, m);
|
||||
@ -489,7 +481,7 @@ pub fn elem_exp_consttime<M>(
|
||||
// `table` was initialized to zero and hasn't changed.
|
||||
debug_assert!(acc.iter().all(|&value| value == 0));
|
||||
acc[0] = 1;
|
||||
limbs_mont_mul(acc, &m.oneRR().0.limbs, m.limbs(), m.n0(), m.cpu_features());
|
||||
limbs_mont_mul(acc, &oneRR.0.limbs, m.limbs(), m.n0(), m.cpu_features());
|
||||
}
|
||||
|
||||
entry_mut(&mut table, 1, num_limbs).copy_from_slice(&base.limbs);
|
||||
@ -527,10 +519,13 @@ pub fn elem_exp_consttime<M>(
|
||||
pub fn elem_exp_consttime<M>(
|
||||
base: Elem<M, R>,
|
||||
exponent: &PrivateExponent,
|
||||
m: &Modulus<M>,
|
||||
m: &OwnedModulusWithOne<M>,
|
||||
) -> Result<Elem<M, Unencoded>, error::Unspecified> {
|
||||
use crate::limb::LIMB_BYTES;
|
||||
|
||||
let oneRR = m.oneRR();
|
||||
let m = &m.modulus();
|
||||
|
||||
// Pretty much all the math here requires CPU feature detection to have
|
||||
// been done. `cpu_features` isn't threaded through all the internal
|
||||
// functions, so just make it clear that it has been done at this point.
|
||||
@ -685,7 +680,7 @@ pub fn elem_exp_consttime<M>(
|
||||
// encode it.
|
||||
debug_assert!(acc.iter().all(|&value| value == 0));
|
||||
acc[0] = 1;
|
||||
limbs_mont_mul(acc, &m.oneRR().0.limbs, m_cached, n0, cpu_features);
|
||||
limbs_mont_mul(acc, &oneRR.0.limbs, m_cached, n0, cpu_features);
|
||||
scatter(table, acc, 0, num_limbs);
|
||||
|
||||
// acc = base**1 (i.e. base).
|
||||
@ -853,7 +848,8 @@ mod tests {
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M", cpu_features);
|
||||
let m_ = consume_modulus::<M>(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 = {
|
||||
@ -861,8 +857,8 @@ mod tests {
|
||||
PrivateExponent::from_be_bytes_for_test_only(untrusted::Input::from(&bytes), &m)
|
||||
.expect("valid exponent")
|
||||
};
|
||||
let base = into_encoded(base, &m);
|
||||
let actual_result = elem_exp_consttime(base, &e, &m).unwrap();
|
||||
let base = into_encoded(base, &m_);
|
||||
let actual_result = elem_exp_consttime(base, &e, &m_).unwrap();
|
||||
assert_elem_eq(&actual_result, &expected_result);
|
||||
|
||||
Ok(())
|
||||
@ -882,13 +878,14 @@ mod tests {
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M", cpu_features);
|
||||
let m_ = consume_modulus::<M>(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);
|
||||
@ -906,12 +903,13 @@ mod tests {
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M", cpu_features);
|
||||
let m_ = consume_modulus::<M>(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 actual_result = elem_squared(a, &m.as_partial());
|
||||
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);
|
||||
|
||||
@ -932,13 +930,14 @@ mod tests {
|
||||
unsafe impl SmallerModulus<MM> for M {}
|
||||
unsafe impl NotMuchSmallerModulus<MM> for M {}
|
||||
|
||||
let m = consume_modulus::<M>(test_case, "M", cpu_features);
|
||||
let m_ = consume_modulus::<M>(test_case, "M", cpu_features);
|
||||
let m = m_.modulus();
|
||||
let expected_result = consume_elem(test_case, "R", &m);
|
||||
let a =
|
||||
consume_elem_unchecked::<MM>(test_case, "A", expected_result.limbs.len() * 2);
|
||||
|
||||
let actual_result = elem_reduced(&a, &m);
|
||||
let oneRR = m.oneRR();
|
||||
let oneRR = m_.oneRR();
|
||||
let actual_result = elem_mul(oneRR.as_ref(), actual_result, &m);
|
||||
assert_elem_eq(&actual_result, &expected_result);
|
||||
|
||||
@ -961,11 +960,11 @@ mod tests {
|
||||
unsafe impl SlightlySmallerModulus<N> for QQ {}
|
||||
|
||||
let qq = consume_modulus::<QQ>(test_case, "QQ", cpu_features);
|
||||
let expected_result = consume_elem::<QQ>(test_case, "R", &qq);
|
||||
let expected_result = consume_elem::<QQ>(test_case, "R", &qq.modulus());
|
||||
let n = consume_modulus::<N>(test_case, "N", cpu_features);
|
||||
let a = consume_elem::<N>(test_case, "A", &n);
|
||||
let a = consume_elem::<N>(test_case, "A", &n.modulus());
|
||||
|
||||
let actual_result = elem_reduced_once(&a, &qq);
|
||||
let actual_result = elem_reduced_once(&a, &qq.modulus());
|
||||
assert_elem_eq(&actual_result, &expected_result);
|
||||
|
||||
Ok(())
|
||||
@ -975,7 +974,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_modulus_debug() {
|
||||
let (modulus, _) = Modulus::<M>::from_be_bytes_with_bit_length(
|
||||
let (modulus, _) = OwnedModulusWithOne::<M>::from_be_bytes_with_bit_length(
|
||||
untrusted::Input::from(&[0xff; LIMB_BYTES * MODULUS_MIN_LIMBS]),
|
||||
cpu::features(),
|
||||
)
|
||||
@ -1010,11 +1009,13 @@ mod tests {
|
||||
test_case: &mut test::TestCase,
|
||||
name: &str,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Modulus<M> {
|
||||
) -> OwnedModulusWithOne<M> {
|
||||
let value = test_case.consume_bytes(name);
|
||||
let (value, _) =
|
||||
Modulus::from_be_bytes_with_bit_length(untrusted::Input::from(&value), cpu_features)
|
||||
.unwrap();
|
||||
let (value, _) = OwnedModulusWithOne::from_be_bytes_with_bit_length(
|
||||
untrusted::Input::from(&value),
|
||||
cpu_features,
|
||||
)
|
||||
.unwrap();
|
||||
value
|
||||
}
|
||||
|
||||
@ -1031,7 +1032,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_encoded<M>(a: Elem<M, Unencoded>, m: &Modulus<M>) -> Elem<M, R> {
|
||||
elem_mul(m.oneRR().as_ref(), a, m)
|
||||
fn into_encoded<M>(a: Elem<M, Unencoded>, m: &OwnedModulusWithOne<M>) -> Elem<M, R> {
|
||||
elem_mul(m.oneRR().as_ref(), a, &m.modulus())
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
use super::{
|
||||
super::{
|
||||
montgomery::{Unencoded, R, RR},
|
||||
montgomery::{Unencoded, RR},
|
||||
n0::N0,
|
||||
},
|
||||
BoxedLimbs, Elem, Nonnegative, One, PublicModulus, SlightlySmallerModulus, SmallerModulus,
|
||||
@ -39,7 +39,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 Modulus<M> {
|
||||
pub struct OwnedModulusWithOne<M> {
|
||||
limbs: BoxedLimbs<M>, // Also `value >= 3`.
|
||||
|
||||
// n0 * N == -1 (mod r).
|
||||
@ -84,7 +84,7 @@ pub struct Modulus<M> {
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl<M: PublicModulus> Clone for Modulus<M> {
|
||||
impl<M: PublicModulus> Clone for OwnedModulusWithOne<M> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
limbs: self.limbs.clone(),
|
||||
@ -95,7 +95,7 @@ impl<M: PublicModulus> Clone for Modulus<M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: PublicModulus> core::fmt::Debug for Modulus<M> {
|
||||
impl<M: PublicModulus> core::fmt::Debug for OwnedModulusWithOne<M> {
|
||||
fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
|
||||
fmt.debug_struct("Modulus")
|
||||
// TODO: Print modulus value.
|
||||
@ -103,7 +103,7 @@ impl<M: PublicModulus> core::fmt::Debug for Modulus<M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Modulus<M> {
|
||||
impl<M> OwnedModulusWithOne<M> {
|
||||
pub(crate) fn from_be_bytes_with_bit_length(
|
||||
input: untrusted::Input,
|
||||
cpu_features: cpu::Features,
|
||||
@ -173,7 +173,7 @@ impl<M> Modulus<M> {
|
||||
|
||||
let bits = limb::limbs_minimal_bits(&n);
|
||||
let oneRR = {
|
||||
let partial = PartialModulus {
|
||||
let partial = Modulus {
|
||||
limbs: &n,
|
||||
n0: n0.clone(),
|
||||
m: PhantomData,
|
||||
@ -194,35 +194,6 @@ impl<M> Modulus<M> {
|
||||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn cpu_features(&self) -> cpu::Features {
|
||||
self.cpu_features
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn limbs(&self) -> &[Limb] {
|
||||
&self.limbs
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn n0(&self) -> &N0 {
|
||||
&self.n0
|
||||
}
|
||||
|
||||
pub(super) fn zero<E>(&self) -> Elem<M, E> {
|
||||
Elem {
|
||||
limbs: BoxedLimbs::zero(self.limbs().len()),
|
||||
encoding: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get rid of this
|
||||
pub(super) fn one(&self) -> Elem<M, Unencoded> {
|
||||
let mut r = self.zero();
|
||||
r.limbs[0] = 1;
|
||||
r
|
||||
}
|
||||
|
||||
pub fn oneRR(&self) -> &One<M, RR> {
|
||||
&self.oneRR
|
||||
}
|
||||
@ -232,15 +203,14 @@ impl<M> Modulus<M> {
|
||||
M: SmallerModulus<L>,
|
||||
{
|
||||
// TODO: Encode this assertion into the `where` above.
|
||||
assert_eq!(self.limbs().len(), l.limbs().len());
|
||||
assert_eq!(self.limbs.len(), l.limbs.len());
|
||||
Elem {
|
||||
limbs: BoxedLimbs::new_unchecked(self.limbs.clone().into_limbs()),
|
||||
encoding: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_partial(&self) -> PartialModulus<M> {
|
||||
PartialModulus {
|
||||
pub fn modulus(&self) -> Modulus<M> {
|
||||
Modulus {
|
||||
limbs: &self.limbs,
|
||||
n0: self.n0.clone(),
|
||||
m: PhantomData,
|
||||
@ -249,28 +219,35 @@ impl<M> Modulus<M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: PublicModulus> Modulus<M> {
|
||||
impl<M: PublicModulus> OwnedModulusWithOne<M> {
|
||||
pub fn be_bytes(&self) -> LeadingZerosStripped<impl ExactSizeIterator<Item = u8> + Clone + '_> {
|
||||
LeadingZerosStripped::new(limb::unstripped_be_bytes(&self.limbs))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PartialModulus<'a, M> {
|
||||
pub struct Modulus<'a, M> {
|
||||
limbs: &'a [Limb],
|
||||
n0: N0,
|
||||
m: PhantomData<M>,
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl<M> PartialModulus<'_, M> {
|
||||
impl<M> Modulus<'_, M> {
|
||||
// TODO: XXX Avoid duplication with `Modulus`.
|
||||
pub(super) fn zero(&self) -> Elem<M, R> {
|
||||
pub(super) fn zero<E>(&self) -> Elem<M, E> {
|
||||
Elem {
|
||||
limbs: BoxedLimbs::zero(self.limbs.len()),
|
||||
encoding: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get rid of this
|
||||
pub(super) fn one(&self) -> Elem<M, Unencoded> {
|
||||
let mut r = self.zero();
|
||||
r.limbs[0] = 1;
|
||||
r
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn limbs(&self) -> &[Limb] {
|
||||
self.limbs
|
||||
@ -282,7 +259,7 @@ impl<M> PartialModulus<'_, M> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cpu_features(&self) -> cpu::Features {
|
||||
pub(crate) fn cpu_features(&self) -> cpu::Features {
|
||||
self.cpu_features
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ pub struct KeyPair {
|
||||
// completely unnecessary since `elem_reduced` seems to be able to reduce
|
||||
// an `Elem<N>` directly to an `Elem<Q>`. TODO: Verify that is true and
|
||||
// eliminate this.
|
||||
qq: bigint::Modulus<QQ>,
|
||||
qq: bigint::OwnedModulusWithOne<QQ>,
|
||||
|
||||
// TODO: Eliminate `q_mod_n` entirely since it is a bad space:time trade-off.
|
||||
// Also, this is the only non-temporary `Elem` so if we eliminate this, we
|
||||
@ -313,7 +313,8 @@ impl KeyPair {
|
||||
cpu_features,
|
||||
)?;
|
||||
|
||||
let n = public_key.inner().n().value();
|
||||
let n_one = public_key.inner().n().value().oneRR();
|
||||
let n = &public_key.inner().n().value().modulus();
|
||||
|
||||
// 6.4.1.4.3 says to skip 6.4.1.2.1 Step 2.
|
||||
|
||||
@ -369,7 +370,7 @@ impl KeyPair {
|
||||
// 0 < q < p < n. We check that q and p are close to sqrt(n) and then
|
||||
// assume that these preconditions are enough to let us assume that
|
||||
// checking p * q == 0 (mod n) is equivalent to checking p * q == n.
|
||||
let q_mod_n = bigint::elem_mul(n.oneRR().as_ref(), q_mod_n_decoded.clone(), n);
|
||||
let q_mod_n = bigint::elem_mul(n_one.as_ref(), q_mod_n_decoded.clone(), n);
|
||||
let p_mod_n = p
|
||||
.to_elem(n)
|
||||
.map_err(|error::Unspecified| KeyRejected::inconsistent_components())?;
|
||||
@ -404,20 +405,21 @@ impl KeyPair {
|
||||
|
||||
// Step 7.a.
|
||||
let p = PrivatePrime::new(p, dP, cpu_features)?;
|
||||
let pm = &p.modulus.modulus();
|
||||
|
||||
// Step 7.b.
|
||||
let q = PrivatePrime::new(q, dQ, cpu_features)?;
|
||||
|
||||
let q_mod_p = q.modulus.to_elem(&p.modulus);
|
||||
let q_mod_p = q.modulus.to_elem(pm);
|
||||
|
||||
// Step 7.c.
|
||||
let qInv = if let Some(qInv) = qInv {
|
||||
bigint::Elem::from_be_bytes_padded(qInv, &p.modulus)
|
||||
bigint::Elem::from_be_bytes_padded(qInv, pm)
|
||||
.map_err(|error::Unspecified| KeyRejected::invalid_component())?
|
||||
} else {
|
||||
// We swapped `p` and `q` above, so we need to calculate `qInv`.
|
||||
// Step 7.f below will verify `qInv` is correct.
|
||||
let q_mod_p = bigint::elem_mul(p.modulus.oneRR().as_ref(), q_mod_p.clone(), &p.modulus);
|
||||
let q_mod_p = bigint::elem_mul(p.modulus.oneRR().as_ref(), q_mod_p.clone(), pm);
|
||||
bigint::elem_inverse_consttime(q_mod_p, &p.modulus)
|
||||
.map_err(|error::Unspecified| KeyRejected::unexpected_error())?
|
||||
};
|
||||
@ -427,11 +429,11 @@ impl KeyPair {
|
||||
// with an even modulus.
|
||||
|
||||
// Step 7.f.
|
||||
let qInv = bigint::elem_mul(p.modulus.oneRR().as_ref(), qInv, &p.modulus);
|
||||
bigint::verify_inverses_consttime(&qInv, q_mod_p, &p.modulus)
|
||||
let qInv = bigint::elem_mul(p.modulus.oneRR().as_ref(), qInv, pm);
|
||||
bigint::verify_inverses_consttime(&qInv, q_mod_p, pm)
|
||||
.map_err(|error::Unspecified| KeyRejected::inconsistent_components())?;
|
||||
|
||||
let qq = bigint::Modulus::from_elem(
|
||||
let qq = bigint::OwnedModulusWithOne::from_elem(
|
||||
bigint::elem_mul(&q_mod_n, q_mod_n_decoded, n),
|
||||
cpu_features,
|
||||
)?;
|
||||
@ -472,7 +474,7 @@ impl signature::KeyPair for KeyPair {
|
||||
}
|
||||
|
||||
struct PrivatePrime<M: Prime> {
|
||||
modulus: bigint::Modulus<M>,
|
||||
modulus: bigint::OwnedModulusWithOne<M>,
|
||||
exponent: bigint::PrivateExponent,
|
||||
}
|
||||
|
||||
@ -484,13 +486,14 @@ impl<M: Prime> PrivatePrime<M> {
|
||||
dP: untrusted::Input,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<Self, KeyRejected> {
|
||||
let (p, p_bits) = bigint::Modulus::from_nonnegative_with_bit_length(p, cpu_features)?;
|
||||
let (p, p_bits) =
|
||||
bigint::OwnedModulusWithOne::from_nonnegative_with_bit_length(p, cpu_features)?;
|
||||
if p_bits.as_usize_bits() % 512 != 0 {
|
||||
return Err(error::KeyRejected::private_modulus_len_not_multiple_of_512_bits());
|
||||
}
|
||||
|
||||
// [NIST SP-800-56B rev. 1] 6.4.1.4.3 - Steps 7.a & 7.b.
|
||||
let dP = bigint::PrivateExponent::from_be_bytes_padded(dP, &p)
|
||||
let dP = bigint::PrivateExponent::from_be_bytes_padded(dP, &p.modulus())
|
||||
.map_err(|error::Unspecified| KeyRejected::inconsistent_components())?;
|
||||
|
||||
// XXX: Steps 7.d and 7.e are omitted. We don't check that
|
||||
@ -517,11 +520,12 @@ where
|
||||
M: bigint::NotMuchSmallerModulus<MM>,
|
||||
M: Prime,
|
||||
{
|
||||
let c_mod_m = bigint::elem_reduced(c, &p.modulus);
|
||||
let m = &p.modulus.modulus();
|
||||
let c_mod_m = bigint::elem_reduced(c, m);
|
||||
// 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, &p.modulus);
|
||||
let c_mod_m = bigint::elem_mul(p.modulus.oneRR().as_ref(), c_mod_m, &p.modulus);
|
||||
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);
|
||||
bigint::elem_exp_consttime(c_mod_m, &p.exponent, &p.modulus)
|
||||
}
|
||||
|
||||
@ -618,7 +622,7 @@ 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 = &self.public.inner().n().value().modulus();
|
||||
|
||||
// Step 1. The value zero is also rejected.
|
||||
let base = bigint::Elem::from_be_bytes_padded(untrusted::Input::from(base), n)?;
|
||||
@ -628,13 +632,13 @@ impl KeyPair {
|
||||
|
||||
// Step 2.b.i.
|
||||
let m_1 = elem_exp_consttime(&c, &self.p)?;
|
||||
let c_mod_qq = bigint::elem_reduced_once(&c, &self.qq);
|
||||
let c_mod_qq = bigint::elem_reduced_once(&c, &self.qq.modulus());
|
||||
let m_2 = elem_exp_consttime(&c_mod_qq, &self.q)?;
|
||||
|
||||
// Step 2.b.ii isn't needed since there are only two primes.
|
||||
|
||||
// Step 2.b.iii.
|
||||
let p = &self.p.modulus;
|
||||
let p = &self.p.modulus.modulus();
|
||||
let m_2 = bigint::elem_widen(m_2, p);
|
||||
let m_1_minus_m_2 = bigint::elem_sub(m_1, &m_2, p);
|
||||
let h = bigint::elem_mul(&self.qInv, m_1_minus_m_2, p);
|
||||
|
@ -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();
|
||||
let n = &self.n.value().modulus();
|
||||
|
||||
// The encoded value of the base must be the same length as the modulus,
|
||||
// in bytes.
|
||||
@ -177,15 +177,16 @@ 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_ = self.n.value();
|
||||
let n = &n_.modulus();
|
||||
|
||||
let base_r = bigint::elem_mul(n.oneRR().as_ref(), base.clone(), n);
|
||||
let base_r = bigint::elem_mul(n_.oneRR().as_ref(), 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
|
||||
// weight of 2. The maximum bit length and maximum Hamming weight of the
|
||||
// exponent is bounded by the value of `PublicExponent::MAX`.
|
||||
let acc = bigint::elem_exp_vartime(base_r, exponent_without_low_bit, &n.as_partial());
|
||||
let acc = bigint::elem_exp_vartime(base_r, exponent_without_low_bit, n);
|
||||
|
||||
// Now do the multiplication for the low bit and convert out of the Montgomery domain.
|
||||
bigint::elem_mul(&base, acc, n)
|
||||
|
@ -4,7 +4,7 @@ use core::ops::RangeInclusive;
|
||||
/// The modulus (n) of an RSA public key.
|
||||
#[derive(Clone)]
|
||||
pub struct PublicModulus {
|
||||
value: bigint::Modulus<N>,
|
||||
value: bigint::OwnedModulusWithOne<N>,
|
||||
bits: bits::BitLength,
|
||||
}
|
||||
|
||||
@ -33,7 +33,8 @@ impl PublicModulus {
|
||||
const MIN_BITS: bits::BitLength = bits::BitLength::from_usize_bits(1024);
|
||||
|
||||
// Step 3 / Step c for `n` (out of order).
|
||||
let (value, bits) = bigint::Modulus::from_be_bytes_with_bit_length(n, cpu_features)?;
|
||||
let (value, bits) =
|
||||
bigint::OwnedModulusWithOne::from_be_bytes_with_bit_length(n, cpu_features)?;
|
||||
|
||||
// Step 1 / Step a. XXX: SP800-56Br1 and SP800-89 require the length of
|
||||
// the public modulus to be exactly 2048 or 3072 bits, but we are more
|
||||
@ -63,7 +64,7 @@ impl PublicModulus {
|
||||
self.bits
|
||||
}
|
||||
|
||||
pub(super) fn value(&self) -> &bigint::Modulus<N> {
|
||||
pub(super) fn value(&self) -> &bigint::OwnedModulusWithOne<N> {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user