RSA: Precompute R**3 and store it instead of R**2.
This saves two private-modulus-length multiplications per RSA private key operation at the cost of two private-modulus-length squarings per `RsaKeyPair` construction.
This commit is contained in:
parent
9b8d4d7b14
commit
3145a7928a
@ -346,6 +346,12 @@ impl<M> One<M, RR> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> One<M, RRR> {
|
||||
pub(crate) fn newRRR(One(oneRR): One<M, RR>, m: &Modulus<M>) -> Self {
|
||||
Self(elem_squared(oneRR, m))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M, E> AsRef<Elem<M, E>> for One<M, E> {
|
||||
fn as_ref(&self) -> &Elem<M, E> {
|
||||
&self.0
|
||||
|
@ -22,6 +22,12 @@ pub enum Unencoded {}
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum R {}
|
||||
|
||||
// Indicates the element is encoded three times; the value has three
|
||||
// *R* factors that need to be canceled out.
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum RRR {}
|
||||
|
||||
// Indicates the element is encoded twice; the value has two *R*
|
||||
// factors that need to be canceled out.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -34,6 +40,7 @@ pub enum RInverse {}
|
||||
|
||||
pub trait Encoding {}
|
||||
|
||||
impl Encoding for RRR {}
|
||||
impl Encoding for RR {}
|
||||
impl Encoding for R {}
|
||||
impl Encoding for Unencoded {}
|
||||
@ -44,6 +51,10 @@ pub trait ReductionEncoding {
|
||||
type Output: Encoding;
|
||||
}
|
||||
|
||||
impl ReductionEncoding for RRR {
|
||||
type Output = RR;
|
||||
}
|
||||
|
||||
impl ReductionEncoding for RR {
|
||||
type Output = R;
|
||||
}
|
||||
@ -67,6 +78,10 @@ impl<E: Encoding> ProductEncoding for (R, E) {
|
||||
type Output = E;
|
||||
}
|
||||
|
||||
impl ProductEncoding for (RR, RR) {
|
||||
type Output = RRR;
|
||||
}
|
||||
|
||||
impl<E: ReductionEncoding> ProductEncoding for (RInverse, E)
|
||||
where
|
||||
E::Output: ReductionEncoding,
|
||||
@ -87,6 +102,10 @@ impl ProductEncoding for (RR, RInverse) {
|
||||
type Output = <(RInverse, RR) as ProductEncoding>::Output;
|
||||
}
|
||||
|
||||
impl ProductEncoding for (RRR, RInverse) {
|
||||
type Output = <(RInverse, RRR) as ProductEncoding>::Output;
|
||||
}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use {
|
||||
super::n0::N0,
|
||||
|
@ -20,7 +20,7 @@ use super::{
|
||||
use crate::{
|
||||
arithmetic::{
|
||||
bigint,
|
||||
montgomery::{R, RR},
|
||||
montgomery::{R, RR, RRR},
|
||||
},
|
||||
bits::BitLength,
|
||||
cpu, digest,
|
||||
@ -443,7 +443,7 @@ impl<M> PrivatePrime<M> {
|
||||
|
||||
struct PrivateCrtPrime<M> {
|
||||
modulus: bigint::OwnedModulus<M>,
|
||||
oneRR: bigint::One<M, RR>,
|
||||
oneRRR: bigint::One<M, RRR>,
|
||||
exponent: bigint::PrivateExponent,
|
||||
}
|
||||
|
||||
@ -451,8 +451,9 @@ impl<M> PrivateCrtPrime<M> {
|
||||
/// Constructs a `PrivateCrtPrime` from the private prime `p` and `dP` where
|
||||
/// dP == d % (p - 1).
|
||||
fn new(p: PrivatePrime<M>, dP: untrusted::Input) -> Result<Self, KeyRejected> {
|
||||
let m = &p.modulus.modulus();
|
||||
// [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.modulus.modulus())
|
||||
let dP = bigint::PrivateExponent::from_be_bytes_padded(dP, m)
|
||||
.map_err(|error::Unspecified| KeyRejected::inconsistent_components())?;
|
||||
|
||||
// XXX: Steps 7.d and 7.e are omitted. We don't check that
|
||||
@ -464,9 +465,11 @@ impl<M> PrivateCrtPrime<M> {
|
||||
// and `e`. TODO: Either prove that what we do is sufficient, or make
|
||||
// it so.
|
||||
|
||||
let oneRRR = bigint::One::newRRR(p.oneRR, m);
|
||||
|
||||
Ok(Self {
|
||||
modulus: p.modulus,
|
||||
oneRR: p.oneRR,
|
||||
oneRRR,
|
||||
exponent: dP,
|
||||
})
|
||||
}
|
||||
@ -479,10 +482,7 @@ fn elem_exp_consttime<M>(
|
||||
) -> Result<bigint::Elem<M>, error::Unspecified> {
|
||||
let m = &p.modulus.modulus();
|
||||
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.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.oneRRR.as_ref(), c_mod_m, m);
|
||||
bigint::elem_exp_consttime(c_mod_m, &p.exponent, m)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user