Skip to content

Commit 0015388

Browse files
committed
Use Resize trait
1 parent c6ae958 commit 0015388

File tree

3 files changed

+59
-58
lines changed

3 files changed

+59
-58
lines changed

src/algorithms/rsa.rs

+31-47
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,6 @@ pub fn rsa_encrypt<K: PublicKeyParts>(key: &K, m: &BoxedUint) -> Result<BoxedUin
2222
Ok(res)
2323
}
2424

25-
fn try_set_precision(x: BoxedUint, bits_precision: u32) -> Result<BoxedUint> {
26-
match x.bits_precision().cmp(&bits_precision) {
27-
Ordering::Greater => {
28-
if x.bits() <= bits_precision {
29-
Ok(x.shorten(bits_precision))
30-
} else {
31-
Err(Error::Internal)
32-
}
33-
}
34-
Ordering::Less => Ok(x.widen(bits_precision)),
35-
Ordering::Equal => Ok(x),
36-
}
37-
}
38-
3925
/// ⚠️ Performs raw RSA decryption with no padding or error checking.
4026
///
4127
/// Returns a plaintext `BoxedUint`. Performs RSA blinding if an `Rng` is passed.
@@ -69,9 +55,9 @@ pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
6955
let c = if let Some(rng) = rng {
7056
let (blinded, unblinder) = blind(rng, priv_key, c, n_params)?;
7157
ir = Some(unblinder);
72-
blinded.widen(bits)
58+
blinded.try_resize(bits).ok_or(Error::Internal)?
7359
} else {
74-
c.widen(bits)
60+
c.try_resize(bits).ok_or(Error::Internal)?
7561
};
7662

7763
let is_multiprime = priv_key.primes().len() > 2;
@@ -96,36 +82,31 @@ pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
9682
// (modulo `p` and `q`) rather than calculating the remainder directly.
9783

9884
// m1 = c^dP mod p
99-
let p_wide = NonZero::new(p_params.modulus().widen(c.bits_precision()))
100-
.expect("`p` is non-zero");
101-
let c_mod_dp = (&c % p_wide).shorten(dp.bits_precision());
85+
let p_wide = p_params.modulus().resize_unchecked(c.bits_precision());
86+
let c_mod_dp = (&c % p_wide.as_nz_ref()).resize_unchecked(dp.bits_precision());
10287
let cp = BoxedMontyForm::new(c_mod_dp, p_params.clone());
10388
let mut m1 = cp.pow(dp);
10489
// m2 = c^dQ mod q
105-
let q_wide = NonZero::new(q_params.modulus().widen(c.bits_precision()))
106-
.expect("`q` is non-zero");
107-
let c_mod_dq = (&c % q_wide).shorten(dq.bits_precision());
90+
let q_wide = q_params.modulus().resize_unchecked(c.bits_precision());
91+
let c_mod_dq = (&c % q_wide.as_nz_ref()).resize_unchecked(dq.bits_precision());
10892
let cq = BoxedMontyForm::new(c_mod_dq, q_params.clone());
10993
let m2 = cq.pow(dq).retrieve();
11094

11195
// Note that since `p` and `q` may have different `bits_precision`,
11296
// it may be different for `m1` and `m2` as well.
11397

11498
// (m1 - m2) mod p = (m1 mod p) - (m2 mod p) mod p
115-
let m2r = match p_params.bits_precision().cmp(&q_params.bits_precision()) {
99+
let m2_mod_p = match p_params.bits_precision().cmp(&q_params.bits_precision()) {
116100
Ordering::Less => {
117-
let p_wide =
118-
NonZero::new(p.widen(q_params.bits_precision())).expect("`p` is non-zero");
119-
BoxedMontyForm::new(
120-
(&m2 % p_wide).shorten(p_params.bits_precision()),
121-
p_params.clone(),
122-
)
123-
}
124-
Ordering::Greater => {
125-
BoxedMontyForm::new(m2.widen(p_params.bits_precision()), p_params.clone())
101+
let p_wide = NonZero::new(p.clone())
102+
.expect("`p` is non-zero")
103+
.resize_unchecked(q_params.bits_precision());
104+
(&m2 % p_wide).resize_unchecked(p_params.bits_precision())
126105
}
127-
Ordering::Equal => BoxedMontyForm::new(m2.clone(), p_params.clone()),
106+
Ordering::Greater => (&m2).resize_unchecked(p_params.bits_precision()),
107+
Ordering::Equal => m2.clone(),
128108
};
109+
let m2r = BoxedMontyForm::new(m2_mod_p, p_params.clone());
129110
m1 -= &m2r;
130111

131112
// precomputed: qInv = (1/q) mod p
@@ -134,8 +115,10 @@ pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
134115
let h = (qinv * m1).retrieve();
135116

136117
// m = m2 + h.q
137-
let m2 = try_set_precision(m2, n.bits_precision())?;
138-
let hq = try_set_precision(h * q, n.bits_precision())?;
118+
let m2 = m2.try_resize(n.bits_precision()).ok_or(Error::Internal)?;
119+
let hq = (h * q)
120+
.try_resize(n.bits_precision())
121+
.ok_or(Error::Internal)?;
139122
m2.wrapping_add(&hq)
140123
}
141124
_ => {
@@ -253,7 +236,7 @@ fn pow_mod_params(base: &BoxedUint, exp: &BoxedUint, n_params: &BoxedMontyParams
253236

254237
fn reduce_vartime(n: &BoxedUint, p: &BoxedMontyParams) -> BoxedMontyForm {
255238
let modulus = p.modulus().as_nz_ref().clone();
256-
let n_reduced = n.rem_vartime(&modulus).widen(p.bits_precision());
239+
let n_reduced = n.rem_vartime(&modulus).resize_unchecked(p.bits_precision());
257240
BoxedMontyForm::new(n_reduced, p.clone())
258241
}
259242

@@ -283,19 +266,20 @@ pub fn recover_primes(
283266

284267
// 1. Let a = (de – 1) × GCD(n – 1, de – 1).
285268
let bits = d.bits_precision() * 2;
286-
let one = BoxedUint::one().widen(bits);
287-
let e = e.widen(bits);
288-
let d = d.widen(bits);
289-
let n = n.as_ref().widen(bits);
269+
let one = BoxedUint::one_with_precision(bits);
270+
let e = e.resize_unchecked(d.bits_precision());
271+
let d = d.resize_unchecked(d.bits_precision());
272+
let n = n.resize_unchecked(bits);
290273

291-
let a1 = &d * &e - &one;
292-
let a2 = (&n - &one).gcd(&a1);
274+
let a1 = d * e - &one;
275+
let a2 = (n.as_ref() - &one).gcd(&a1);
293276
let a = a1 * a2;
294-
let n = n.widen(a.bits_precision());
277+
let n = n.resize_unchecked(a.bits_precision());
295278

296279
// 2. Let m = floor(a /n) and r = a – m n, so that a = m n + r and 0 ≤ r < n.
297-
let m = &a / NonZero::new(n.clone()).expect("checked");
298-
let r = a - &m * &n;
280+
let m = &a / &n;
281+
let r = a - &m * n.as_ref();
282+
let n = n.get();
299283

300284
// 3. Let b = ( (n – r)/(m + 1) ) + 1; if b is not an integer or b^2 ≤ 4n, then output an error indicator,
301285
// and exit without further processing.
@@ -360,7 +344,7 @@ pub(crate) fn compute_private_exponent_euler_totient(
360344
for prime in primes {
361345
totient *= prime - &BoxedUint::one();
362346
}
363-
let exp = exp.widen(totient.bits_precision());
347+
let exp = exp.resize_unchecked(totient.bits_precision());
364348

365349
// NOTE: `mod_inverse` checks if `exp` evenly divides `totient` and returns `None` if so.
366350
// This ensures that `exp` is not a factor of any `(prime - 1)`.
@@ -391,7 +375,7 @@ pub(crate) fn compute_private_exponent_carmicheal(
391375
// LCM inlined
392376
let gcd = p1.gcd(&q1);
393377
let lcm = p1 / NonZero::new(gcd).expect("gcd is non zero") * &q1;
394-
let exp = exp.widen(lcm.bits_precision());
378+
let exp = exp.resize_unchecked(lcm.bits_precision());
395379
if let Some(d) = exp.inv_mod(&lcm).into() {
396380
Ok(d)
397381
} else {

src/encoding.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
RsaPrivateKey, RsaPublicKey,
99
};
1010
use core::convert::{TryFrom, TryInto};
11-
use crypto_bigint::{BoxedUint, NonZero, Odd};
11+
use crypto_bigint::{BoxedUint, NonZero, Odd, Resize};
1212
use pkcs8::{
1313
der::{asn1::OctetStringRef, Encode},
1414
Document, EncodePrivateKey, EncodePublicKey, ObjectIdentifier, SecretDocument,
@@ -115,13 +115,20 @@ impl EncodePrivateKey for RsaPrivateKey {
115115

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

118+
debug_assert!(bits >= self.primes[0].bits_vartime());
119+
debug_assert!(bits >= self.primes[1].bits_vartime());
120+
118121
let exponent1 = Zeroizing::new(
119-
(self.d() % NonZero::new(&self.primes[0].widen(bits) - &BoxedUint::one()).unwrap())
120-
.to_be_bytes(),
122+
(self.d()
123+
% NonZero::new((&self.primes[0]).resize_unchecked(bits) - &BoxedUint::one())
124+
.unwrap())
125+
.to_be_bytes(),
121126
);
122127
let exponent2 = Zeroizing::new(
123-
(self.d() % NonZero::new(&self.primes[1].widen(bits) - &BoxedUint::one()).unwrap())
124-
.to_be_bytes(),
128+
(self.d()
129+
% NonZero::new((&self.primes[1]).resize_unchecked(bits) - &BoxedUint::one())
130+
.unwrap())
131+
.to_be_bytes(),
125132
);
126133
let coefficient = Zeroizing::new(
127134
self.crt_coefficient()

src/key.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use core::fmt;
44
use core::hash::{Hash, Hasher};
55

66
use crypto_bigint::modular::{BoxedMontyForm, BoxedMontyParams};
7-
use crypto_bigint::{BoxedUint, Integer, NonZero, Odd};
7+
use crypto_bigint::{BoxedUint, Integer, NonZero, Odd, Resize};
88
use rand_core::CryptoRng;
99
use zeroize::{Zeroize, ZeroizeOnDrop};
1010
#[cfg(feature = "serde")]
@@ -311,7 +311,8 @@ impl RsaPrivateKey {
311311
) -> Result<RsaPrivateKey> {
312312
// The modulus may come in padded with zeros, shorten it
313313
// to ensure optimal performance of arithmetic operations.
314-
let n = Odd::new(n.shorten(n.bits_vartime())).expect("`n` is odd");
314+
let n_bits = n.bits_vartime();
315+
let n = n.resize_unchecked(n_bits);
315316

316317
let n_params = BoxedMontyParams::new(n.clone());
317318
let n_c = NonZero::new(n.get())
@@ -338,7 +339,13 @@ impl RsaPrivateKey {
338339
}
339340

340341
// The primes may come in padded with zeros too, so we need to shorten them as well.
341-
let primes = primes.iter().map(|p| p.shorten(p.bits())).collect();
342+
let primes = primes
343+
.into_iter()
344+
.map(|p| {
345+
let p_bits = p.bits();
346+
p.resize_unchecked(p_bits)
347+
})
348+
.collect();
342349

343350
let mut k = RsaPrivateKey {
344351
pubkey_components: RsaPublicKey {
@@ -449,10 +456,13 @@ impl RsaPrivateKey {
449456
// so we have to equalize them to calculate the remainder.
450457
let q_mod_p = match p.bits_precision().cmp(&q.bits_precision()) {
451458
Ordering::Less => (&q
452-
% &NonZero::new(p.widen(q.bits_precision())).expect("`p` is non-zero"))
453-
.shorten(p.bits_precision()),
459+
% NonZero::new(p.clone())
460+
.expect("`p` is non-zero")
461+
.resize_unchecked(q.bits_precision()))
462+
.resize_unchecked(p.bits_precision()),
454463
Ordering::Greater => {
455-
q.widen(p.bits_precision()) % &NonZero::new(p.clone()).expect("`p` is non-zero")
464+
(&q).resize_unchecked(p.bits_precision())
465+
% &NonZero::new(p.clone()).expect("`p` is non-zero")
456466
}
457467
Ordering::Equal => &q % NonZero::new(p.clone()).expect("`p` is non-zero"),
458468
};

0 commit comments

Comments
 (0)