1use alloc::vec::Vec;
2use core::hash::{Hash, Hasher};
3use num_bigint::traits::ModInverse;
4use num_bigint::Sign::Plus;
5use num_bigint::{BigInt, BigUint};
6use num_integer::Integer;
7use num_traits::{FromPrimitive, One, ToPrimitive};
8use rand_core::CryptoRngCore;
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11use zeroize::{Zeroize, ZeroizeOnDrop};
12
13use crate::algorithms::generate::generate_multi_prime_key_with_exp;
14use crate::algorithms::rsa::{
15 compute_modulus, compute_private_exponent_carmicheal, compute_private_exponent_euler_totient,
16 recover_primes,
17};
18
19use crate::dummy_rng::DummyRng;
20use crate::errors::{Error, Result};
21use crate::traits::{PaddingScheme, PrivateKeyParts, PublicKeyParts, SignatureScheme};
22use crate::CrtValue;
23
24#[derive(Debug, Clone, Hash, PartialEq, Eq)]
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27pub struct RsaPublicKey {
28 n: BigUint,
30 e: BigUint,
35}
36
37#[derive(Debug, Clone)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub struct RsaPrivateKey {
41 pubkey_components: RsaPublicKey,
43 pub(crate) d: BigUint,
45 pub(crate) primes: Vec<BigUint>,
47 #[cfg_attr(feature = "serde", serde(skip))]
49 pub(crate) precomputed: Option<PrecomputedValues>,
50}
51
52impl Eq for RsaPrivateKey {}
53impl PartialEq for RsaPrivateKey {
54 #[inline]
55 fn eq(&self, other: &RsaPrivateKey) -> bool {
56 self.pubkey_components == other.pubkey_components
57 && self.d == other.d
58 && self.primes == other.primes
59 }
60}
61
62impl AsRef<RsaPublicKey> for RsaPrivateKey {
63 fn as_ref(&self) -> &RsaPublicKey {
64 &self.pubkey_components
65 }
66}
67
68impl Hash for RsaPrivateKey {
69 fn hash<H: Hasher>(&self, state: &mut H) {
70 state.write(b"RsaPrivateKey");
72 Hash::hash(&self.pubkey_components, state);
73 }
74}
75
76impl Drop for RsaPrivateKey {
77 fn drop(&mut self) {
78 self.d.zeroize();
79 self.primes.zeroize();
80 self.precomputed.zeroize();
81 }
82}
83
84impl ZeroizeOnDrop for RsaPrivateKey {}
85
86#[derive(Debug, Clone)]
87pub(crate) struct PrecomputedValues {
88 pub(crate) dp: BigUint,
90 pub(crate) dq: BigUint,
92 pub(crate) qinv: BigInt,
94
95 pub(crate) crt_values: Vec<CrtValue>,
100}
101
102impl Zeroize for PrecomputedValues {
103 fn zeroize(&mut self) {
104 self.dp.zeroize();
105 self.dq.zeroize();
106 self.qinv.zeroize();
107 for val in self.crt_values.iter_mut() {
108 val.zeroize();
109 }
110 self.crt_values.clear();
111 }
112}
113
114impl Drop for PrecomputedValues {
115 fn drop(&mut self) {
116 self.zeroize();
117 }
118}
119
120impl From<RsaPrivateKey> for RsaPublicKey {
121 fn from(private_key: RsaPrivateKey) -> Self {
122 (&private_key).into()
123 }
124}
125
126impl From<&RsaPrivateKey> for RsaPublicKey {
127 fn from(private_key: &RsaPrivateKey) -> Self {
128 let n = private_key.n().clone();
129 let e = private_key.e().clone();
130 RsaPublicKey { n, e }
131 }
132}
133
134impl PublicKeyParts for RsaPublicKey {
135 fn n(&self) -> &BigUint {
136 &self.n
137 }
138
139 fn e(&self) -> &BigUint {
140 &self.e
141 }
142}
143
144impl RsaPublicKey {
145 pub fn encrypt<R: CryptoRngCore, P: PaddingScheme>(
147 &self,
148 rng: &mut R,
149 padding: P,
150 msg: &[u8],
151 ) -> Result<Vec<u8>> {
152 padding.encrypt(rng, self, msg)
153 }
154
155 pub fn verify<S: SignatureScheme>(&self, scheme: S, hashed: &[u8], sig: &[u8]) -> Result<()> {
162 scheme.verify(self, hashed, sig)
163 }
164}
165
166impl RsaPublicKey {
167 pub const MIN_PUB_EXPONENT: u64 = 2;
169
170 pub const MAX_PUB_EXPONENT: u64 = (1 << 33) - 1;
172
173 pub const MAX_SIZE: usize = 4096;
175
176 pub fn new(n: BigUint, e: BigUint) -> Result<Self> {
181 Self::new_with_max_size(n, e, Self::MAX_SIZE)
182 }
183
184 pub fn new_with_max_size(n: BigUint, e: BigUint, max_size: usize) -> Result<Self> {
186 let k = Self { n, e };
187 check_public_with_max_size(&k, max_size)?;
188 Ok(k)
189 }
190
191 pub fn new_unchecked(n: BigUint, e: BigUint) -> Self {
198 Self { n, e }
199 }
200}
201
202impl PublicKeyParts for RsaPrivateKey {
203 fn n(&self) -> &BigUint {
204 &self.pubkey_components.n
205 }
206
207 fn e(&self) -> &BigUint {
208 &self.pubkey_components.e
209 }
210}
211
212impl RsaPrivateKey {
213 const EXP: u64 = 65537;
215
216 pub fn new<R: CryptoRngCore + ?Sized>(rng: &mut R, bit_size: usize) -> Result<RsaPrivateKey> {
218 let exp = BigUint::from_u64(Self::EXP).expect("invalid static exponent");
219 Self::new_with_exp(rng, bit_size, &exp)
220 }
221
222 pub fn new_with_exp<R: CryptoRngCore + ?Sized>(
227 rng: &mut R,
228 bit_size: usize,
229 exp: &BigUint,
230 ) -> Result<RsaPrivateKey> {
231 let components = generate_multi_prime_key_with_exp(rng, 2, bit_size, exp)?;
232 RsaPrivateKey::from_components(components.n, components.e, components.d, components.primes)
233 }
234
235 pub fn from_components(
249 n: BigUint,
250 e: BigUint,
251 d: BigUint,
252 mut primes: Vec<BigUint>,
253 ) -> Result<RsaPrivateKey> {
254 if primes.len() < 2 {
255 if !primes.is_empty() {
256 return Err(Error::NprimesTooSmall);
257 }
258 let (p, q) = recover_primes(&n, &e, &d)?;
261 primes.push(p);
262 primes.push(q);
263 }
264
265 let mut k = RsaPrivateKey {
266 pubkey_components: RsaPublicKey { n, e },
267 d,
268 primes,
269 precomputed: None,
270 };
271
272 k.validate()?;
274
275 let _ = k.precompute();
277
278 Ok(k)
279 }
280
281 pub fn from_p_q(p: BigUint, q: BigUint, public_exponent: BigUint) -> Result<RsaPrivateKey> {
288 if p == q {
289 return Err(Error::InvalidPrime);
290 }
291
292 let n = compute_modulus(&[p.clone(), q.clone()]);
293 let d = compute_private_exponent_carmicheal(&p, &q, &public_exponent)?;
294
295 Self::from_components(n, public_exponent, d, vec![p, q])
296 }
297
298 pub fn from_primes(primes: Vec<BigUint>, public_exponent: BigUint) -> Result<RsaPrivateKey> {
302 if primes.len() < 2 {
303 return Err(Error::NprimesTooSmall);
304 }
305
306 for (i, prime1) in primes.iter().enumerate() {
308 for prime2 in primes.iter().take(i) {
309 if prime1 == prime2 {
310 return Err(Error::InvalidPrime);
311 }
312 }
313 }
314
315 let n = compute_modulus(&primes);
316 let d = compute_private_exponent_euler_totient(&primes, &public_exponent)?;
317
318 Self::from_components(n, public_exponent, d, primes)
319 }
320
321 pub fn to_public_key(&self) -> RsaPublicKey {
326 self.pubkey_components.clone()
327 }
328
329 pub fn precompute(&mut self) -> Result<()> {
331 if self.precomputed.is_some() {
332 return Ok(());
333 }
334
335 let dp = &self.d % (&self.primes[0] - BigUint::one());
336 let dq = &self.d % (&self.primes[1] - BigUint::one());
337 let qinv = self.primes[1]
338 .clone()
339 .mod_inverse(&self.primes[0])
340 .ok_or(Error::InvalidPrime)?;
341
342 let mut r: BigUint = &self.primes[0] * &self.primes[1];
343 let crt_values: Vec<CrtValue> = {
344 let mut values = Vec::with_capacity(self.primes.len() - 2);
345 for prime in &self.primes[2..] {
346 let res = CrtValue {
347 exp: BigInt::from_biguint(Plus, &self.d % (prime - BigUint::one())),
348 r: BigInt::from_biguint(Plus, r.clone()),
349 coeff: BigInt::from_biguint(
350 Plus,
351 r.clone()
352 .mod_inverse(prime)
353 .ok_or(Error::InvalidCoefficient)?
354 .to_biguint()
355 .unwrap(),
356 ),
357 };
358 r *= prime;
359
360 values.push(res);
361 }
362 values
363 };
364
365 self.precomputed = Some(PrecomputedValues {
366 dp,
367 dq,
368 qinv,
369 crt_values,
370 });
371
372 Ok(())
373 }
374
375 pub fn clear_precomputed(&mut self) {
377 self.precomputed = None;
378 }
379
380 pub fn crt_coefficient(&self) -> Option<BigUint> {
382 (&self.primes[1]).mod_inverse(&self.primes[0])?.to_biguint()
383 }
384
385 pub fn validate(&self) -> Result<()> {
388 check_public(self)?;
389
390 let mut m = BigUint::one();
392 for prime in &self.primes {
393 if *prime < BigUint::one() {
395 return Err(Error::InvalidPrime);
396 }
397 m *= prime;
398 }
399 if m != self.pubkey_components.n {
400 return Err(Error::InvalidModulus);
401 }
402
403 let mut de = self.e().clone();
409 de *= self.d.clone();
410 for prime in &self.primes {
411 let congruence: BigUint = &de % (prime - BigUint::one());
412 if !congruence.is_one() {
413 return Err(Error::InvalidExponent);
414 }
415 }
416
417 Ok(())
418 }
419
420 pub fn decrypt<P: PaddingScheme>(&self, padding: P, ciphertext: &[u8]) -> Result<Vec<u8>> {
422 padding.decrypt(Option::<&mut DummyRng>::None, self, ciphertext)
423 }
424
425 pub fn decrypt_blinded<R: CryptoRngCore, P: PaddingScheme>(
429 &self,
430 rng: &mut R,
431 padding: P,
432 ciphertext: &[u8],
433 ) -> Result<Vec<u8>> {
434 padding.decrypt(Some(rng), self, ciphertext)
435 }
436
437 pub fn sign<S: SignatureScheme>(&self, padding: S, digest_in: &[u8]) -> Result<Vec<u8>> {
439 padding.sign(Option::<&mut DummyRng>::None, self, digest_in)
440 }
441
442 pub fn sign_with_rng<R: CryptoRngCore, S: SignatureScheme>(
453 &self,
454 rng: &mut R,
455 padding: S,
456 digest_in: &[u8],
457 ) -> Result<Vec<u8>> {
458 padding.sign(Some(rng), self, digest_in)
459 }
460}
461
462impl PrivateKeyParts for RsaPrivateKey {
463 fn d(&self) -> &BigUint {
464 &self.d
465 }
466
467 fn primes(&self) -> &[BigUint] {
468 &self.primes
469 }
470
471 fn dp(&self) -> Option<&BigUint> {
472 self.precomputed.as_ref().map(|p| &p.dp)
473 }
474
475 fn dq(&self) -> Option<&BigUint> {
476 self.precomputed.as_ref().map(|p| &p.dq)
477 }
478
479 fn qinv(&self) -> Option<&BigInt> {
480 self.precomputed.as_ref().map(|p| &p.qinv)
481 }
482
483 fn crt_values(&self) -> Option<&[CrtValue]> {
484 if let Some(p) = &self.precomputed {
486 Some(p.crt_values.as_slice())
487 } else {
488 None
489 }
490 }
491}
492
493#[inline]
495pub fn check_public(public_key: &impl PublicKeyParts) -> Result<()> {
496 check_public_with_max_size(public_key, RsaPublicKey::MAX_SIZE)
497}
498
499#[inline]
501fn check_public_with_max_size(public_key: &impl PublicKeyParts, max_size: usize) -> Result<()> {
502 if public_key.n().bits() > max_size {
503 return Err(Error::ModulusTooLarge);
504 }
505
506 let e = public_key
507 .e()
508 .to_u64()
509 .ok_or(Error::PublicExponentTooLarge)?;
510
511 if public_key.e() >= public_key.n() || public_key.n().is_even() {
512 return Err(Error::InvalidModulus);
513 }
514
515 if public_key.e().is_even() {
516 return Err(Error::InvalidExponent);
517 }
518
519 if e < RsaPublicKey::MIN_PUB_EXPONENT {
520 return Err(Error::PublicExponentTooSmall);
521 }
522
523 if e > RsaPublicKey::MAX_PUB_EXPONENT {
524 return Err(Error::PublicExponentTooLarge);
525 }
526
527 Ok(())
528}
529
530#[cfg(test)]
531mod tests {
532 use super::*;
533 use crate::algorithms::rsa::{rsa_decrypt_and_check, rsa_encrypt};
534
535 use hex_literal::hex;
536 use num_traits::{FromPrimitive, ToPrimitive};
537 use pkcs8::DecodePrivateKey;
538 use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
539
540 #[test]
541 fn test_from_into() {
542 let private_key = RsaPrivateKey {
543 pubkey_components: RsaPublicKey {
544 n: BigUint::from_u64(100).unwrap(),
545 e: BigUint::from_u64(200).unwrap(),
546 },
547 d: BigUint::from_u64(123).unwrap(),
548 primes: vec![],
549 precomputed: None,
550 };
551 let public_key: RsaPublicKey = private_key.into();
552
553 assert_eq!(public_key.n().to_u64(), Some(100));
554 assert_eq!(public_key.e().to_u64(), Some(200));
555 }
556
557 fn test_key_basics(private_key: &RsaPrivateKey) {
558 private_key.validate().expect("invalid private key");
559
560 assert!(
561 private_key.d() < private_key.n(),
562 "private exponent too large"
563 );
564
565 let pub_key: RsaPublicKey = private_key.clone().into();
566 let m = BigUint::from_u64(42).expect("invalid 42");
567 let c = rsa_encrypt(&pub_key, &m).expect("encryption successfull");
568 let m2 = rsa_decrypt_and_check::<ChaCha8Rng>(private_key, None, &c)
569 .expect("unable to decrypt without blinding");
570 assert_eq!(m, m2);
571 let mut rng = ChaCha8Rng::from_seed([42; 32]);
572 let m3 = rsa_decrypt_and_check(private_key, Some(&mut rng), &c)
573 .expect("unable to decrypt with blinding");
574 assert_eq!(m, m3);
575 }
576
577 macro_rules! key_generation {
578 ($name:ident, $multi:expr, $size:expr) => {
579 #[test]
580 fn $name() {
581 let mut rng = ChaCha8Rng::from_seed([42; 32]);
582 let exp = BigUint::from_u64(RsaPrivateKey::EXP).expect("invalid static exponent");
583
584 for _ in 0..10 {
585 let components =
586 generate_multi_prime_key_with_exp(&mut rng, $multi, $size, &exp).unwrap();
587 let private_key = RsaPrivateKey::from_components(
588 components.n,
589 components.e,
590 components.d,
591 components.primes,
592 )
593 .unwrap();
594 assert_eq!(private_key.n().bits(), $size);
595
596 test_key_basics(&private_key);
597 }
598 }
599 };
600 }
601
602 key_generation!(key_generation_128, 2, 128);
603 key_generation!(key_generation_1024, 2, 1024);
604
605 key_generation!(key_generation_multi_3_256, 3, 256);
606
607 key_generation!(key_generation_multi_4_64, 4, 64);
608
609 key_generation!(key_generation_multi_5_64, 5, 64);
610 key_generation!(key_generation_multi_8_576, 8, 576);
611 key_generation!(key_generation_multi_16_1024, 16, 1024);
612
613 #[test]
614 fn test_negative_decryption_value() {
615 let private_key = RsaPrivateKey::from_components(
616 BigUint::from_bytes_le(&[
617 99, 192, 208, 179, 0, 220, 7, 29, 49, 151, 75, 107, 75, 73, 200, 180,
618 ]),
619 BigUint::from_bytes_le(&[1, 0, 1]),
620 BigUint::from_bytes_le(&[
621 81, 163, 254, 144, 171, 159, 144, 42, 244, 133, 51, 249, 28, 12, 63, 65,
622 ]),
623 vec![
624 BigUint::from_bytes_le(&[105, 101, 60, 173, 19, 153, 3, 192]),
625 BigUint::from_bytes_le(&[235, 65, 160, 134, 32, 136, 6, 241]),
626 ],
627 )
628 .unwrap();
629
630 for _ in 0..1000 {
631 test_key_basics(&private_key);
632 }
633 }
634
635 #[test]
636 #[cfg(feature = "serde")]
637 fn test_serde() {
638 use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
639 use serde_test::{assert_tokens, Token};
640
641 let mut rng = ChaCha8Rng::from_seed([42; 32]);
642 let priv_key = RsaPrivateKey::new(&mut rng, 64).expect("failed to generate key");
643
644 let priv_tokens = [
645 Token::Struct {
646 name: "RsaPrivateKey",
647 len: 3,
648 },
649 Token::Str("pubkey_components"),
650 Token::Struct {
651 name: "RsaPublicKey",
652 len: 2,
653 },
654 Token::Str("n"),
655 Token::Seq { len: Some(2) },
656 Token::U32(3814409919),
657 Token::U32(3429654832),
658 Token::SeqEnd,
659 Token::Str("e"),
660 Token::Seq { len: Some(1) },
661 Token::U32(65537),
662 Token::SeqEnd,
663 Token::StructEnd,
664 Token::Str("d"),
665 Token::Seq { len: Some(2) },
666 Token::U32(1482162201),
667 Token::U32(1675500232),
668 Token::SeqEnd,
669 Token::Str("primes"),
670 Token::Seq { len: Some(2) },
671 Token::Seq { len: Some(1) },
672 Token::U32(4133289821),
673 Token::SeqEnd,
674 Token::Seq { len: Some(1) },
675 Token::U32(3563808971),
676 Token::SeqEnd,
677 Token::SeqEnd,
678 Token::StructEnd,
679 ];
680 assert_tokens(&priv_key, &priv_tokens);
681
682 let priv_tokens = [
683 Token::Struct {
684 name: "RsaPublicKey",
685 len: 2,
686 },
687 Token::Str("n"),
688 Token::Seq { len: Some(2) },
689 Token::U32(3814409919),
690 Token::U32(3429654832),
691 Token::SeqEnd,
692 Token::Str("e"),
693 Token::Seq { len: Some(1) },
694 Token::U32(65537),
695 Token::SeqEnd,
696 Token::StructEnd,
697 ];
698 assert_tokens(&RsaPublicKey::from(priv_key), &priv_tokens);
699 }
700
701 #[test]
702 fn invalid_coeff_private_key_regression() {
703 use base64ct::{Base64, Encoding};
704
705 let n = Base64::decode_vec("wC8GyQvTCZOK+iiBR5fGQCmzRCTWX9TQ3aRG5gGFk0wB6EFoLMAyEEqeG3gS8xhAm2rSWYx9kKufvNat3iWlbSRVqkcbpVAYlj2vTrpqDpJl+6u+zxFYoUEBevlJJkAhl8EuCccOA30fVpcfRvXPTtvRd3yFT9E9EwZljtgSI02w7gZwg7VIxaGeajh5Euz6ZVQZ+qNRKgXrRC7gPRqVyI6Dt0Jc+Su5KBGNn0QcPDzOahWha1ieaeMkFisZ9mdpsJoZ4tw5eicLaUomKzALHXQVt+/rcZSrCd6/7uUo11B/CYBM4UfSpwXaL88J9AE6A5++no9hmJzaF2LLp+Qwx4yY3j9TDutxSAjsraxxJOGZ3XyA9nG++Ybt3cxZ5fP7ROjxCfROBmVv5dYn0O9OBIqYeCH6QraNpZMadlLNIhyMv8Y+P3r5l/PaK4VJaEi5pPosnEPawp0W0yZDzmjk2z1LthaRx0aZVrAjlH0Rb/6goLUQ9qu1xsDtQVVpN4A89ZUmtTWORnnJr0+595eHHxssd2gpzqf4bPjNITdAEuOCCtpvyi4ls23zwuzryUYjcUOEnsXNQ+DrZpLKxdtsD/qNV/j1hfeyBoPllC3cV+6bcGOFcVGbjYqb+Kw1b0+jL69RSKQqgmS+qYqr8c48nDRxyq3QXhR8qtzUwBFSLVk=").unwrap();
706 let e = Base64::decode_vec("AQAB").unwrap();
707 let d = Base64::decode_vec("qQazSQ+FRN7nVK1bRsROMRB8AmsDwLVEHivlz1V3Td2Dr+oW3YUMgxedhztML1IdQJPq/ad6qErJ6yRFNySVIjDaxzBTOEoB1eHa1btOnBJWb8rVvvjaorixvJ6Tn3i4EuhsvVy9DoR1k4rGj3qSIiFjUVvLRDAbLyhpGgEfsr0Z577yJmTC5E8JLRMOKX8Tmxsk3jPVpsgd65Hu1s8S/ZmabwuHCf9SkdMeY/1bd/9i7BqqJeeDLE4B5x1xcC3z3scqDUTzqGO+vZPhjgprPDRlBamVwgenhr7KwCn8iaLamFinRVwOAag8BeBqOJj7lURiOsKQa9FIX1kdFUS1QMQxgtPycLjkbvCJjriqT7zWKsmJ7l8YLs6Wmm9/+QJRwNCEVdMTXKfCP1cJjudaiskEQThfUldtgu8gUDNYbQ/Filb2eKfiX4h1TiMxZqUZHVZyb9nShbQoXJ3vj/MGVF0QM8TxhXM8r2Lv9gDYU5t9nQlUMLhs0jVjai48jHABbFNyH3sEcOmJOIwJrCXw1dzG7AotwyaEVUHOmL04TffmwCFfnyrLjbFgnyOeoyIIBYjcY7QFRm/9nupXMTH5hZ2qrHfCJIp0KK4tNBdQqmnHapFl5l6Le1s4qBS5bEIzjitobLvAFm9abPlDGfxmY6mlrMK4+nytwF9Ct7wc1AE=").unwrap();
708 let primes = vec![
709 Base64::decode_vec("9kQWEAzsbzOcdPa+s5wFfw4XDd7bB1q9foZ31b1+TNjGNxbSBCFlDF1q98vwpV6nM8bWDh/wtbNoETSQDgpEnYOQ26LWEw6YY1+q1Q2GGEFceYUf+Myk8/vTc8TN6Zw0bKZBWy10Qo8h7xk4JpzuI7NcxvjJYTkS9aErFxi3vVH0aiZC0tmfaCqr8a2rJxyVwqreRpOjwAWrotMsf2wGsF4ofx5ScoFy5GB5fJkkdOrW1LyTvZAUCX3cstPr19+TNC5zZOk7WzZatnCkN5H5WzalWtZuu0oVL205KPOa3R8V2yv5e6fm0v5fTmqSuvjmaMJLXCN4QJkmIzojO99ckQ==").unwrap(),
710 Base64::decode_vec("x8exdMjVA2CiI+Thx7loHtVcevoeE2sZ7btRVAvmBqo+lkHwxb7FHRnWvuj6eJSlD2f0T50EewIhhiW3R9BmktCk7hXjbSCnC1u9Oxc1IAUm/7azRqyfCMx43XhLxpD+xkBCpWkKDLxGczsRwTuaP3lKS3bSdBrNlGmdblubvVBIq4YZ2vXVlnYtza0cS+dgCK7BGTqUsrCUd/ZbIvwcwZkZtpkhj1KQfto9X/0OMurBzAqbkeq1cyRHXHkOfN/qbUIIRqr9Ii7Eswf9Vk8xp2O1Nt8nzcYS9PFD12M5eyaeFEkEYfpNMNGuTzp/31oqVjbpoCxS6vuWAZyADxhISQ==").unwrap(),
711 Base64::decode_vec("is7d0LY4HoXszlC2NO7gejkq7XqL4p1W6hZJPYTNx+r37t1CC2n3Vvzg6kNdpRixDhIpXVTLjN9O7UO/XuqSumYKJIKoP52eb4Tg+a3hw5Iz2Zsb5lUTNSLgkQSBPAf71LHxbL82JL4g1nBUog8ae60BwnVArThKY4EwlJguGNw09BAU4lwf6csDl/nX2vfVwiAloYpeZkHL+L8m+bueGZM5KE2jEz+7ztZCI+T+E5i69rZEYDjx0lfLKlEhQlCW3HbCPELqXgNJJkRfi6MP9kXa9lSfnZmoT081RMvqonB/FUa4HOcKyCrw9XZEtnbNCIdbitfDVEX+pSSD7596wQ==").unwrap(),
712 Base64::decode_vec("GPs0injugfycacaeIP5jMa/WX55VEnKLDHom4k6WlfDF4L4gIGoJdekcPEUfxOI5faKvHyFwRP1wObkPoRBDM0qZxRfBl4zEtpvjHrd5MibSyJkM8+J0BIKk/nSjbRIGeb3hV5O56PvGB3S0dKhCUnuVObiC+ne7izplsD4OTG70l1Yud33UFntyoMxrxGYLUSqhBMmZfHquJg4NOWOzKNY/K+EcHDLj1Kjvkcgv9Vf7ocsVxvpFdD9uGPceQ6kwRDdEl6mb+6FDgWuXVyqR9+904oanEIkbJ7vfkthagLbEf57dyG6nJlqh5FBZWxGIR72YGypPuAh7qnnqXXjY2Q==").unwrap(),
713 Base64::decode_vec("CUWC+hRWOT421kwRllgVjy6FYv6jQUcgDNHeAiYZnf5HjS9iK2ki7v8G5dL/0f+Yf+NhE/4q8w4m8go51hACrVpP1p8GJDjiT09+RsOzITsHwl+ceEKoe56ZW6iDHBLlrNw5/MtcYhKpjNU9KJ2udm5J/c9iislcjgckrZG2IB8ADgXHMEByZ5DgaMl4AKZ1Gx8/q6KftTvmOT5rNTMLi76VN5KWQcDWK/DqXiOiZHM7Nr4dX4me3XeRgABJyNR8Fqxj3N1+HrYLe/zs7LOaK0++F9Ul3tLelhrhsvLxei3oCZkF9A/foD3on3luYA+1cRcxWpSY3h2J4/22+yo4+Q==").unwrap(),
714 ];
715
716 let res = RsaPrivateKey::from_components(
717 BigUint::from_bytes_be(&n),
718 BigUint::from_bytes_be(&e),
719 BigUint::from_bytes_be(&d),
720 primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(),
721 );
722 assert_eq!(res, Err(Error::InvalidModulus));
723 }
724
725 #[test]
726 fn reject_oversized_private_key() {
727 let n = BigUint::from_bytes_be(&hex!(
754 "
755 90c06207caac3555c0b0947a5e8b681f5af6aed665ff1cd42b6b487f2f7d68f1
756 38f3dbbee6d2f10908507fe6bcf75e7cbd20e9af6ff1c202bcc3dbb45e9bb69b
757 b5d12a354c4b463a50820d16879373ceeb5574fdd9272be3b90d55c1a64855de
758 cf80520e94be2caa56c1737ed0042ef9c99c7ddb6cc76f3ada211ba90beae0fc
759 0a19024e74e474ca5747f0ee327892bf6eebc83974478dbfbebed40d0ffc626c
760 518071df5626abda386eed72585b676efb99b3ba111fb2f4b8fb0323bccb0c9b
761 5aa35e1da54f1cccac3e14fb1d4588d7b9b9f62d4ea6e570c049efcc34101147
762 fd7798549a42d86f9a90cee7fa0dd9f1ff4e10242280824872afd09782757abc
763 46773cab6989c08747193b7aa4c49a0065830a87e6f7e54455758b2c10317267
764 b9187358e41a5e5fef6fcbf81c8bc5e136ad1192aa7f3a5bc9270b22261b3c40
765 211d729d64c776cd8f219126e27227de3c0a40666b8da40c71243673a6187baf
766 8943eadf0c3d3fd150076dad97e286a68185db8523a61e548cba7a6834e4ce98
767 5af954c9eafb9d819a3d14b526a0f8d2fef13ad99ee48f10c3a00f8853d7853a
768 812b7a1c72bed38066f75779690bc12af9eb0d1eb8e2f7c4757c84e415725629
769 d15c4d68c18213f18a86d4ccc08552b3c80c97165de073ac0440af253e8578c4
770 8857f396e5eba6cd01ed1250feb2c32d77939f8be8bd47874151daed87e8c963
771 32f697ea7950bee7a2c12bb484200bcbd08de5aeae6f22ff9922e38075b56026
772 2472f039de08e9362cfdd19c0f0cd0749ebd85bddc3882fb887f9789ed8e388e
773 7e2eb2455399f166d5c9767ff378f8ebea465a0be2d2e3326fe6ed80e5e3050b
774 fb6c6a9dc8731ce4baa4e5b17b131113c79d6f290318095e37e7571a4ba697ab
775 5ea56190131e06d300310064776ba0330907e1cc41acdef4eeaa53964ef30c71
776 023c3cf71af2d1d9e83900ffc80e07ec2442a3dbd50e957686a22f1d8f512364
777 fb71e936f24990a4abcdbef2bea2f98cd77f1d1ca5625942c79347c146dee6e3
778 043eb622f63e627f4ebf20d6056133a4bd0f55dd13dcf429e0e73830969f543c
779 b31d86d9a878ca79d841444359cc0e31c0283fa6dd27b702b7ee05dad12c30f7
780 f84bf1309678efb8da108efcedc423da8587bd127ca082d417c8726f7889fb80
781 326c3fa6fddd507ac7841b2f2e5c8780d486a0d68229ee2957a8ec24e00e4ab4
782 de3fc811a4b5047c2b7920d071e9f2f9b61638dc15fb84cca46cad28e1ef539d
783 bcf249876f2647757b9a5e4f0b2ea6e7aabdf47dae826e9e259428bdb07e5a2a
784 68b98f141f5537be7a590cb3ba15b0bb15824652e8da8f70eb847240058a336a
785 1b6db7f88268aaf89f0b33b905d72c25338b13e61a51873c2d427021a3f29207
786 179ad32f423793f0c090dda025ce41df0e94afbc80ab5eda9b1a268aa2553a99"
787 ));
788
789 let e = BigUint::from_u64(65537).unwrap();
790
791 assert_eq!(
792 RsaPublicKey::new(n, e).err().unwrap(),
793 Error::ModulusTooLarge
794 );
795 }
796
797 #[test]
798 fn build_key_from_primes() {
799 const RSA_2048_PRIV_DER: &[u8] = include_bytes!("../tests/examples/pkcs8/rsa2048-priv.der");
800 let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_PRIV_DER).unwrap();
801 assert_eq!(ref_key.validate(), Ok(()));
802
803 let primes = ref_key.primes().to_vec();
804
805 let exp = ref_key.e().clone();
806 let key =
807 RsaPrivateKey::from_primes(primes, exp).expect("failed to import key from primes");
808 assert_eq!(key.validate(), Ok(()));
809
810 assert_eq!(key.n(), ref_key.n());
811
812 assert_eq!(key.dp(), ref_key.dp());
813 assert_eq!(key.dq(), ref_key.dq());
814
815 assert_eq!(key.d(), ref_key.d());
816 }
817
818 #[test]
819 fn build_key_from_p_q() {
820 const RSA_2048_SP800_PRIV_DER: &[u8] =
821 include_bytes!("../tests/examples/pkcs8/rsa2048-sp800-56b-priv.der");
822 let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_SP800_PRIV_DER).unwrap();
823 assert_eq!(ref_key.validate(), Ok(()));
824
825 let primes = ref_key.primes().to_vec();
826 let exp = ref_key.e().clone();
827
828 let key = RsaPrivateKey::from_p_q(primes[0].clone(), primes[1].clone(), exp)
829 .expect("failed to import key from primes");
830 assert_eq!(key.validate(), Ok(()));
831
832 assert_eq!(key.n(), ref_key.n());
833
834 assert_eq!(key.dp(), ref_key.dp());
835 assert_eq!(key.dq(), ref_key.dq());
836
837 assert_eq!(key.d(), ref_key.d());
838 }
839}