Skip to content

Commit

Permalink
widen and shorten
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Jul 6, 2024
1 parent 7b2aa3d commit a2d4998
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
47 changes: 32 additions & 15 deletions src/algorithms/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ pub fn rsa_decrypt<R: CryptoRngCore + ?Sized>(
let mut ir = None;

let n_params = priv_key.n_params();
let bits = d.bits_precision();

let c = if let Some(ref mut rng) = rng {
let (blinded, unblinder) = blind(rng, priv_key, &c, &n_params);
ir = Some(unblinder);
Cow::Owned(blinded)
blinded.widen(bits)
} else {
Cow::Borrowed(c)
c.widen(bits)
};

let has_precomputes = priv_key.dp().is_some();
Expand All @@ -77,10 +78,10 @@ pub fn rsa_decrypt<R: CryptoRngCore + ?Sized>(
// precomputed: dQ = (1/e) mod (q-1) = d mod (q-1)

// m1 = c^dP mod p
let cp = BoxedMontyForm::new(c.clone().into_owned(), p_params.clone());
let cp = BoxedMontyForm::new(c.clone(), p_params.clone());
let mut m1 = cp.pow(&dp);
// m2 = c^dQ mod q
let cq = BoxedMontyForm::new(c.into_owned(), q_params.clone());
let cq = BoxedMontyForm::new(c, q_params.clone());
let m2 = cq.pow(&dq).retrieve();

// (m1 - m2) mod p = (m1 mod p) - (m2 mod p) mod p
Expand All @@ -101,6 +102,7 @@ pub fn rsa_decrypt<R: CryptoRngCore + ?Sized>(
match ir {
Some(ref ir) => {
// unblind
let m = m.shorten(n_params.bits_precision());
let res = unblind(&m, ir, n_params);
Ok(res)
}
Expand Down Expand Up @@ -148,13 +150,14 @@ fn blind<R: CryptoRngCore, K: PublicKeyParts>(
// which equals mr mod n. The factor of r can then be removed
// by multiplying by the multiplicative inverse of r.
debug_assert_eq!(&key.n().clone().get(), n_params.modulus());
let bits = key.n_bits_precision();

let mut r: BoxedUint = BoxedUint::one();
let mut r: BoxedUint = BoxedUint::one_with_precision(bits);
let mut ir: Option<BoxedUint> = None;
while ir.is_none() {
r = BoxedUint::random_mod(rng, key.n());
if r.is_zero().into() {
r = BoxedUint::one();
r = BoxedUint::one_with_precision(bits);
}

// r^-1 (mod n)
Expand All @@ -171,12 +174,28 @@ fn blind<R: CryptoRngCore, K: PublicKeyParts>(
c
};

(blinded, ir.unwrap())
let ir = ir.unwrap();
debug_assert_eq!(blinded.bits_precision(), bits);
debug_assert_eq!(ir.bits_precision(), bits);

(blinded, ir)
}

/// Given an m and and unblinding factor, unblind the m.
fn unblind(m: &BoxedUint, unblinder: &BoxedUint, n_params: BoxedMontyParams) -> BoxedUint {
// m * r^-1 (mod n)
debug_assert_eq!(
m.bits_precision(),
unblinder.bits_precision(),
"invalid unblinder"
);

debug_assert_eq!(
m.bits_precision(),
n_params.bits_precision(),
"invalid n_params"
);

mul_mod_params(m, unblinder, n_params)
}

Expand Down Expand Up @@ -271,21 +290,19 @@ pub(crate) fn compute_private_exponent_euler_totient(
if primes.len() < 2 {
return Err(Error::InvalidPrime);
}

let mut totient = BoxedUint::one();
let bits = primes[0].bits_precision();
let mut totient = BoxedUint::one_with_precision(bits);

for prime in primes {
totient = totient * (prime - &BoxedUint::one());
}
let totient = Odd::new(totient).unwrap();
let exp = BoxedUint::from(exp).widen(totient.bits_precision());

// NOTE: `mod_inverse` checks if `exp` evenly divides `totient` and returns `None` if so.
// This ensures that `exp` is not a factor of any `(prime - 1)`.
if let Some(d) = BoxedUint::from(exp).inv_odd_mod(&totient).into() {
Ok(d)
} else {
// `exp` evenly divides `totient`
Err(Error::InvalidPrime)
match exp.inv_mod(&totient).into_option() {
Some(res) => Ok(res),
None => Err(Error::InvalidPrime),
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,16 @@ impl EncodePrivateKey for RsaPrivateKey {
let private_exponent = Zeroizing::new(self.d().to_be_bytes());
let prime1 = Zeroizing::new(self.primes[0].to_be_bytes());
let prime2 = Zeroizing::new(self.primes[1].to_be_bytes());

let bits = self.d().bits_precision();

let exponent1 = Zeroizing::new(
(self.d() % NonZero::new(&self.primes[0] - &BoxedUint::one()).unwrap()).to_be_bytes(),
(self.d() % NonZero::new(&self.primes[0].widen(bits) - &BoxedUint::one()).unwrap())
.to_be_bytes(),
);
let exponent2 = Zeroizing::new(
(self.d() % NonZero::new(&self.primes[1] - &BoxedUint::one()).unwrap()).to_be_bytes(),
(self.d() % NonZero::new(&self.primes[1].widen(bits) - &BoxedUint::one()).unwrap())
.to_be_bytes(),
);
let coefficient = Zeroizing::new(
self.crt_coefficient()
Expand Down
13 changes: 11 additions & 2 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,9 @@ impl RsaPrivateKey {
}

let d = &self.d;
let p = &self.primes[0];
let q = &self.primes[1];
let bits = d.bits_precision();
let p = self.primes[0].widen(bits);
let q = self.primes[1].widen(bits);

// TODO: error handling

Expand All @@ -388,15 +389,23 @@ impl RsaPrivateKey {

let x = NonZero::new(p.wrapping_sub(&BoxedUint::one())).unwrap();
let dp = d.rem_vartime(&x);

let x = NonZero::new(q.wrapping_sub(&BoxedUint::one())).unwrap();
let dq = d.rem_vartime(&x);

let qinv = BoxedMontyForm::new(q.clone(), p_params.clone());
let qinv = qinv.invert();
if qinv.is_none().into() {
return Err(Error::InvalidPrime);
}
let qinv = qinv.unwrap();

debug_assert_eq!(dp.bits_precision(), bits);
debug_assert_eq!(dq.bits_precision(), bits);
debug_assert_eq!(qinv.bits_precision(), bits);
debug_assert_eq!(p_params.bits_precision(), bits);
debug_assert_eq!(q_params.bits_precision(), bits);

self.precomputed = Some(PrecomputedValues {
dp,
dq,
Expand Down

0 comments on commit a2d4998

Please sign in to comment.