rsa/
key.rs

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/// Represents the public part of an RSA key.
25#[derive(Debug, Clone, Hash, PartialEq, Eq)]
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27pub struct RsaPublicKey {
28    /// Modulus: product of prime numbers `p` and `q`
29    n: BigUint,
30    /// Public exponent: power to which a plaintext message is raised in
31    /// order to encrypt it.
32    ///
33    /// Typically 0x10001 (65537)
34    e: BigUint,
35}
36
37/// Represents a whole RSA key, public and private parts.
38#[derive(Debug, Clone)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub struct RsaPrivateKey {
41    /// Public components of the private key.
42    pubkey_components: RsaPublicKey,
43    /// Private exponent
44    pub(crate) d: BigUint,
45    /// Prime factors of N, contains >= 2 elements.
46    pub(crate) primes: Vec<BigUint>,
47    /// precomputed values to speed up private operations
48    #[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        // Domain separator for RSA private keys
71        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    /// D mod (P-1)
89    pub(crate) dp: BigUint,
90    /// D mod (Q-1)
91    pub(crate) dq: BigUint,
92    /// Q^-1 mod P
93    pub(crate) qinv: BigInt,
94
95    /// CRTValues is used for the 3rd and subsequent primes. Due to a
96    /// historical accident, the CRT for the first two primes is handled
97    /// differently in PKCS#1 and interoperability is sufficiently
98    /// important that we mirror this.
99    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    /// Encrypt the given message.
146    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    /// Verify a signed message.
156    ///
157    /// `hashed` must be the result of hashing the input using the hashing function
158    /// passed in through `hash`.
159    ///
160    /// If the message is valid `Ok(())` is returned, otherwise an `Err` indicating failure.
161    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    /// Minimum value of the public exponent `e`.
168    pub const MIN_PUB_EXPONENT: u64 = 2;
169
170    /// Maximum value of the public exponent `e`.
171    pub const MAX_PUB_EXPONENT: u64 = (1 << 33) - 1;
172
173    /// Maximum size of the modulus `n` in bits.
174    pub const MAX_SIZE: usize = 4096;
175
176    /// Create a new public key from its components.
177    ///
178    /// This function accepts public keys with a modulus size up to 4096-bits,
179    /// i.e. [`RsaPublicKey::MAX_SIZE`].
180    pub fn new(n: BigUint, e: BigUint) -> Result<Self> {
181        Self::new_with_max_size(n, e, Self::MAX_SIZE)
182    }
183
184    /// Create a new public key from its components.
185    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, Some(max_size))?;
188        Ok(k)
189    }
190
191    /// Create a new public key, bypassing checks around the modulus and public
192    /// exponent size.
193    ///
194    /// This method is not recommended, and only intended for unusual use cases.
195    /// Most applications should use [`RsaPublicKey::new`] or
196    /// [`RsaPublicKey::new_with_max_size`] instead.
197    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    /// Default exponent for RSA keys.
214    const EXP: u64 = 65537;
215
216    /// Generate a new Rsa key pair of the given bit size using the passed in `rng`.
217    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    /// Generate a new RSA key pair of the given bit size and the public exponent
223    /// using the passed in `rng`.
224    ///
225    /// Unless you have specific needs, you should use `RsaPrivateKey::new` instead.
226    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    /// Constructs an RSA key pair from individual components:
236    ///
237    /// - `n`: RSA modulus
238    /// - `e`: public exponent (i.e. encrypting exponent)
239    /// - `d`: private exponent (i.e. decrypting exponent)
240    /// - `primes`: prime factors of `n`: typically two primes `p` and `q`. More than two primes can
241    ///   be provided for multiprime RSA, however this is generally not recommended. If no `primes`
242    ///   are provided, a prime factor recovery algorithm will be employed to attempt to recover the
243    ///   factors (as described in [NIST SP 800-56B Revision 2] Appendix C.2). This algorithm only
244    ///   works if there are just two prime factors `p` and `q` (as opposed to multiprime), and `e`
245    ///   is between 2^16 and 2^256.
246    ///
247    ///  [NIST SP 800-56B Revision 2]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf
248    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            // Recover `p` and `q` from `d`.
259            // See method in Appendix C.2: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf
260            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        // Always validate the key, to ensure precompute can't fail
273        k.validate()?;
274
275        // precompute when possible, ignore error otherwise.
276        let _ = k.precompute();
277
278        Ok(k)
279    }
280
281    /// Constructs an RSA key pair from its two primes p and q.
282    ///
283    /// This will rebuild the private exponent and the modulus.
284    ///
285    /// Private exponent will be rebuilt using the method defined in
286    /// [NIST 800-56B Section 6.2.1](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf#page=47).
287    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    /// Constructs an RSA key pair from its primes.
299    ///
300    /// This will rebuild the private exponent and the modulus.
301    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        // Makes sure that primes is pairwise unequal.
307        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    /// Get the public key from the private key, cloning `n` and `e`.
322    ///
323    /// Generally this is not needed since `RsaPrivateKey` implements the `PublicKey` trait,
324    /// but it can occasionally be useful to discard the private information entirely.
325    pub fn to_public_key(&self) -> RsaPublicKey {
326        self.pubkey_components.clone()
327    }
328
329    /// Performs some calculations to speed up private key operations.
330    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    /// Clears precomputed values by setting to None
376    pub fn clear_precomputed(&mut self) {
377        self.precomputed = None;
378    }
379
380    /// Compute CRT coefficient: `(1/q) mod p`.
381    pub fn crt_coefficient(&self) -> Option<BigUint> {
382        (&self.primes[1]).mod_inverse(&self.primes[0])?.to_biguint()
383    }
384
385    /// Performs basic sanity checks on the key.
386    /// Returns `Ok(())` if everything is good, otherwise an appropriate error.
387    pub fn validate(&self) -> Result<()> {
388        check_public(self)?;
389
390        // Check that Πprimes == n.
391        let mut m = BigUint::one();
392        for prime in &self.primes {
393            // Any primes ≤ 1 will cause divide-by-zero panics later.
394            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        // Check that de ≡ 1 mod p-1, for each prime.
404        // This implies that e is coprime to each p-1 as e has a multiplicative
405        // inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
406        // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
407        // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
408        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    /// Decrypt the given message.
421    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    /// Decrypt the given message.
426    ///
427    /// Uses `rng` to blind the decryption process.
428    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    /// Sign the given digest.
438    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    /// Sign the given digest using the provided `rng`, which is used in the
443    /// following ways depending on the [`SignatureScheme`]:
444    ///
445    /// - [`Pkcs1v15Sign`][`crate::Pkcs1v15Sign`] padding: uses the RNG
446    ///   to mask the private key operation with random blinding, which helps
447    ///   mitigate sidechannel attacks.
448    /// - [`Pss`][`crate::Pss`] always requires randomness. Use
449    ///   [`Pss::new`][`crate::Pss::new`] for a standard RSASSA-PSS signature, or
450    ///   [`Pss::new_blinded`][`crate::Pss::new_blinded`] for RSA-BSSA blind
451    ///   signatures.
452    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        /* for some reason the standard self.precomputed.as_ref().map() doesn't work */
485        if let Some(p) = &self.precomputed {
486            Some(p.crt_values.as_slice())
487        } else {
488            None
489        }
490    }
491}
492
493/// Check that the public key is well formed and has an exponent within acceptable bounds.
494#[inline]
495pub fn check_public(public_key: &impl PublicKeyParts) -> Result<()> {
496    check_public_with_max_size(public_key, None)
497}
498
499/// Check that the public key is well formed and has an exponent within acceptable bounds.
500#[inline]
501fn check_public_with_max_size(
502    public_key: &impl PublicKeyParts,
503    max_size: Option<usize>,
504) -> Result<()> {
505    if let Some(max_size) = max_size {
506        if public_key.n().bits() > max_size {
507            return Err(Error::ModulusTooLarge);
508        }
509    }
510
511    let e = public_key
512        .e()
513        .to_u64()
514        .ok_or(Error::PublicExponentTooLarge)?;
515
516    if public_key.e() >= public_key.n() || public_key.n().is_even() {
517        return Err(Error::InvalidModulus);
518    }
519
520    if public_key.e().is_even() {
521        return Err(Error::InvalidExponent);
522    }
523
524    if e < RsaPublicKey::MIN_PUB_EXPONENT {
525        return Err(Error::PublicExponentTooSmall);
526    }
527
528    if e > RsaPublicKey::MAX_PUB_EXPONENT {
529        return Err(Error::PublicExponentTooLarge);
530    }
531
532    Ok(())
533}
534
535#[cfg(test)]
536mod tests {
537    use super::*;
538    use crate::algorithms::rsa::{rsa_decrypt_and_check, rsa_encrypt};
539
540    use hex_literal::hex;
541    use num_traits::{FromPrimitive, ToPrimitive, Zero};
542    use pkcs8::DecodePrivateKey;
543    use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
544
545    #[test]
546    fn test_from_into() {
547        let private_key = RsaPrivateKey {
548            pubkey_components: RsaPublicKey {
549                n: BigUint::from_u64(100).unwrap(),
550                e: BigUint::from_u64(200).unwrap(),
551            },
552            d: BigUint::from_u64(123).unwrap(),
553            primes: vec![],
554            precomputed: None,
555        };
556        let public_key: RsaPublicKey = private_key.into();
557
558        assert_eq!(public_key.n().to_u64(), Some(100));
559        assert_eq!(public_key.e().to_u64(), Some(200));
560    }
561
562    fn test_key_basics(private_key: &RsaPrivateKey) {
563        private_key.validate().expect("invalid private key");
564
565        assert!(
566            private_key.d() < private_key.n(),
567            "private exponent too large"
568        );
569
570        let pub_key: RsaPublicKey = private_key.clone().into();
571        let m = BigUint::from_u64(42).expect("invalid 42");
572        let c = rsa_encrypt(&pub_key, &m).expect("encryption successfull");
573        let m2 = rsa_decrypt_and_check::<ChaCha8Rng>(private_key, None, &c)
574            .expect("unable to decrypt without blinding");
575        assert_eq!(m, m2);
576        let mut rng = ChaCha8Rng::from_seed([42; 32]);
577        let m3 = rsa_decrypt_and_check(private_key, Some(&mut rng), &c)
578            .expect("unable to decrypt with blinding");
579        assert_eq!(m, m3);
580    }
581
582    macro_rules! key_generation {
583        ($name:ident, $multi:expr, $size:expr) => {
584            #[test]
585            fn $name() {
586                let mut rng = ChaCha8Rng::from_seed([42; 32]);
587                let exp = BigUint::from_u64(RsaPrivateKey::EXP).expect("invalid static exponent");
588
589                for _ in 0..10 {
590                    let components =
591                        generate_multi_prime_key_with_exp(&mut rng, $multi, $size, &exp).unwrap();
592                    let private_key = RsaPrivateKey::from_components(
593                        components.n,
594                        components.e,
595                        components.d,
596                        components.primes,
597                    )
598                    .unwrap();
599                    assert_eq!(private_key.n().bits(), $size);
600
601                    test_key_basics(&private_key);
602                }
603            }
604        };
605    }
606
607    key_generation!(key_generation_128, 2, 128);
608    key_generation!(key_generation_1024, 2, 1024);
609
610    key_generation!(key_generation_multi_3_256, 3, 256);
611
612    key_generation!(key_generation_multi_4_64, 4, 64);
613
614    key_generation!(key_generation_multi_5_64, 5, 64);
615    key_generation!(key_generation_multi_8_576, 8, 576);
616    key_generation!(key_generation_multi_16_1024, 16, 1024);
617
618    #[test]
619    fn test_negative_decryption_value() {
620        let private_key = RsaPrivateKey::from_components(
621            BigUint::from_bytes_le(&[
622                99, 192, 208, 179, 0, 220, 7, 29, 49, 151, 75, 107, 75, 73, 200, 180,
623            ]),
624            BigUint::from_bytes_le(&[1, 0, 1]),
625            BigUint::from_bytes_le(&[
626                81, 163, 254, 144, 171, 159, 144, 42, 244, 133, 51, 249, 28, 12, 63, 65,
627            ]),
628            vec![
629                BigUint::from_bytes_le(&[105, 101, 60, 173, 19, 153, 3, 192]),
630                BigUint::from_bytes_le(&[235, 65, 160, 134, 32, 136, 6, 241]),
631            ],
632        )
633        .unwrap();
634
635        for _ in 0..1000 {
636            test_key_basics(&private_key);
637        }
638    }
639
640    #[test]
641    #[cfg(feature = "serde")]
642    fn test_serde() {
643        use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
644        use serde_test::{assert_tokens, Token};
645
646        let mut rng = ChaCha8Rng::from_seed([42; 32]);
647        let priv_key = RsaPrivateKey::new(&mut rng, 64).expect("failed to generate key");
648
649        let priv_tokens = [
650            Token::Struct {
651                name: "RsaPrivateKey",
652                len: 3,
653            },
654            Token::Str("pubkey_components"),
655            Token::Struct {
656                name: "RsaPublicKey",
657                len: 2,
658            },
659            Token::Str("n"),
660            Token::Seq { len: Some(2) },
661            Token::U32(3814409919),
662            Token::U32(3429654832),
663            Token::SeqEnd,
664            Token::Str("e"),
665            Token::Seq { len: Some(1) },
666            Token::U32(65537),
667            Token::SeqEnd,
668            Token::StructEnd,
669            Token::Str("d"),
670            Token::Seq { len: Some(2) },
671            Token::U32(1482162201),
672            Token::U32(1675500232),
673            Token::SeqEnd,
674            Token::Str("primes"),
675            Token::Seq { len: Some(2) },
676            Token::Seq { len: Some(1) },
677            Token::U32(4133289821),
678            Token::SeqEnd,
679            Token::Seq { len: Some(1) },
680            Token::U32(3563808971),
681            Token::SeqEnd,
682            Token::SeqEnd,
683            Token::StructEnd,
684        ];
685        assert_tokens(&priv_key, &priv_tokens);
686
687        let priv_tokens = [
688            Token::Struct {
689                name: "RsaPublicKey",
690                len: 2,
691            },
692            Token::Str("n"),
693            Token::Seq { len: Some(2) },
694            Token::U32(3814409919),
695            Token::U32(3429654832),
696            Token::SeqEnd,
697            Token::Str("e"),
698            Token::Seq { len: Some(1) },
699            Token::U32(65537),
700            Token::SeqEnd,
701            Token::StructEnd,
702        ];
703        assert_tokens(&RsaPublicKey::from(priv_key), &priv_tokens);
704    }
705
706    #[test]
707    fn invalid_coeff_private_key_regression() {
708        use base64ct::{Base64, Encoding};
709
710        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();
711        let e = Base64::decode_vec("AQAB").unwrap();
712        let d = Base64::decode_vec("qQazSQ+FRN7nVK1bRsROMRB8AmsDwLVEHivlz1V3Td2Dr+oW3YUMgxedhztML1IdQJPq/ad6qErJ6yRFNySVIjDaxzBTOEoB1eHa1btOnBJWb8rVvvjaorixvJ6Tn3i4EuhsvVy9DoR1k4rGj3qSIiFjUVvLRDAbLyhpGgEfsr0Z577yJmTC5E8JLRMOKX8Tmxsk3jPVpsgd65Hu1s8S/ZmabwuHCf9SkdMeY/1bd/9i7BqqJeeDLE4B5x1xcC3z3scqDUTzqGO+vZPhjgprPDRlBamVwgenhr7KwCn8iaLamFinRVwOAag8BeBqOJj7lURiOsKQa9FIX1kdFUS1QMQxgtPycLjkbvCJjriqT7zWKsmJ7l8YLs6Wmm9/+QJRwNCEVdMTXKfCP1cJjudaiskEQThfUldtgu8gUDNYbQ/Filb2eKfiX4h1TiMxZqUZHVZyb9nShbQoXJ3vj/MGVF0QM8TxhXM8r2Lv9gDYU5t9nQlUMLhs0jVjai48jHABbFNyH3sEcOmJOIwJrCXw1dzG7AotwyaEVUHOmL04TffmwCFfnyrLjbFgnyOeoyIIBYjcY7QFRm/9nupXMTH5hZ2qrHfCJIp0KK4tNBdQqmnHapFl5l6Le1s4qBS5bEIzjitobLvAFm9abPlDGfxmY6mlrMK4+nytwF9Ct7wc1AE=").unwrap();
713        let primes = vec![
714            Base64::decode_vec("9kQWEAzsbzOcdPa+s5wFfw4XDd7bB1q9foZ31b1+TNjGNxbSBCFlDF1q98vwpV6nM8bWDh/wtbNoETSQDgpEnYOQ26LWEw6YY1+q1Q2GGEFceYUf+Myk8/vTc8TN6Zw0bKZBWy10Qo8h7xk4JpzuI7NcxvjJYTkS9aErFxi3vVH0aiZC0tmfaCqr8a2rJxyVwqreRpOjwAWrotMsf2wGsF4ofx5ScoFy5GB5fJkkdOrW1LyTvZAUCX3cstPr19+TNC5zZOk7WzZatnCkN5H5WzalWtZuu0oVL205KPOa3R8V2yv5e6fm0v5fTmqSuvjmaMJLXCN4QJkmIzojO99ckQ==").unwrap(),
715            Base64::decode_vec("x8exdMjVA2CiI+Thx7loHtVcevoeE2sZ7btRVAvmBqo+lkHwxb7FHRnWvuj6eJSlD2f0T50EewIhhiW3R9BmktCk7hXjbSCnC1u9Oxc1IAUm/7azRqyfCMx43XhLxpD+xkBCpWkKDLxGczsRwTuaP3lKS3bSdBrNlGmdblubvVBIq4YZ2vXVlnYtza0cS+dgCK7BGTqUsrCUd/ZbIvwcwZkZtpkhj1KQfto9X/0OMurBzAqbkeq1cyRHXHkOfN/qbUIIRqr9Ii7Eswf9Vk8xp2O1Nt8nzcYS9PFD12M5eyaeFEkEYfpNMNGuTzp/31oqVjbpoCxS6vuWAZyADxhISQ==").unwrap(),
716            Base64::decode_vec("is7d0LY4HoXszlC2NO7gejkq7XqL4p1W6hZJPYTNx+r37t1CC2n3Vvzg6kNdpRixDhIpXVTLjN9O7UO/XuqSumYKJIKoP52eb4Tg+a3hw5Iz2Zsb5lUTNSLgkQSBPAf71LHxbL82JL4g1nBUog8ae60BwnVArThKY4EwlJguGNw09BAU4lwf6csDl/nX2vfVwiAloYpeZkHL+L8m+bueGZM5KE2jEz+7ztZCI+T+E5i69rZEYDjx0lfLKlEhQlCW3HbCPELqXgNJJkRfi6MP9kXa9lSfnZmoT081RMvqonB/FUa4HOcKyCrw9XZEtnbNCIdbitfDVEX+pSSD7596wQ==").unwrap(),
717            Base64::decode_vec("GPs0injugfycacaeIP5jMa/WX55VEnKLDHom4k6WlfDF4L4gIGoJdekcPEUfxOI5faKvHyFwRP1wObkPoRBDM0qZxRfBl4zEtpvjHrd5MibSyJkM8+J0BIKk/nSjbRIGeb3hV5O56PvGB3S0dKhCUnuVObiC+ne7izplsD4OTG70l1Yud33UFntyoMxrxGYLUSqhBMmZfHquJg4NOWOzKNY/K+EcHDLj1Kjvkcgv9Vf7ocsVxvpFdD9uGPceQ6kwRDdEl6mb+6FDgWuXVyqR9+904oanEIkbJ7vfkthagLbEf57dyG6nJlqh5FBZWxGIR72YGypPuAh7qnnqXXjY2Q==").unwrap(),
718            Base64::decode_vec("CUWC+hRWOT421kwRllgVjy6FYv6jQUcgDNHeAiYZnf5HjS9iK2ki7v8G5dL/0f+Yf+NhE/4q8w4m8go51hACrVpP1p8GJDjiT09+RsOzITsHwl+ceEKoe56ZW6iDHBLlrNw5/MtcYhKpjNU9KJ2udm5J/c9iislcjgckrZG2IB8ADgXHMEByZ5DgaMl4AKZ1Gx8/q6KftTvmOT5rNTMLi76VN5KWQcDWK/DqXiOiZHM7Nr4dX4me3XeRgABJyNR8Fqxj3N1+HrYLe/zs7LOaK0++F9Ul3tLelhrhsvLxei3oCZkF9A/foD3on3luYA+1cRcxWpSY3h2J4/22+yo4+Q==").unwrap(),
719        ];
720
721        let res = RsaPrivateKey::from_components(
722            BigUint::from_bytes_be(&n),
723            BigUint::from_bytes_be(&e),
724            BigUint::from_bytes_be(&d),
725            primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(),
726        );
727        assert_eq!(res, Err(Error::InvalidModulus));
728    }
729
730    #[test]
731    fn reject_oversized_private_key() {
732        // -----BEGIN PUBLIC KEY-----
733        // MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAkMBiB8qsNVXAsJR6Xoto
734        // H1r2rtZl/xzUK2tIfy99aPE489u+5tLxCQhQf+a89158vSDpr2/xwgK8w9u0Xpu2
735        // m7XRKjVMS0Y6UIINFoeTc87rVXT92Scr47kNVcGmSFXez4BSDpS+LKpWwXN+0AQu
736        // +cmcfdtsx2862iEbqQvq4PwKGQJOdOR0yldH8O4yeJK/buvIOXRHjb++vtQND/xi
737        // bFGAcd9WJqvaOG7tclhbZ277mbO6ER+y9Lj7AyO8ywybWqNeHaVPHMysPhT7HUWI
738        // 17m59i1OpuVwwEnvzDQQEUf9d5hUmkLYb5qQzuf6Ddnx/04QJCKAgkhyr9CXgnV6
739        // vEZ3PKtpicCHRxk7eqTEmgBlgwqH5vflRFV1iywQMXJnuRhzWOQaXl/vb8v4HIvF
740        // 4TatEZKqfzpbyScLIiYbPEAhHXKdZMd2zY8hkSbicifePApAZmuNpAxxJDZzphh7
741        // r4lD6t8MPT/RUAdtrZfihqaBhduFI6YeVIy6emg05M6YWvlUyer7nYGaPRS1JqD4
742        // 0v7xOtme5I8Qw6APiFPXhTqBK3occr7TgGb3V3lpC8Eq+esNHrji98R1fITkFXJW
743        // KdFcTWjBghPxiobUzMCFUrPIDJcWXeBzrARAryU+hXjEiFfzluXrps0B7RJQ/rLD
744        // LXeTn4vovUeHQVHa7YfoyWMy9pfqeVC+56LBK7SEIAvL0I3lrq5vIv+ZIuOAdbVg
745        // JiRy8DneCOk2LP3RnA8M0HSevYW93DiC+4h/l4ntjjiOfi6yRVOZ8WbVyXZ/83j4
746        // 6+pGWgvi0uMyb+btgOXjBQv7bGqdyHMc5Lqk5bF7ExETx51vKQMYCV4351caS6aX
747        // q16lYZATHgbTADEAZHdroDMJB+HMQaze9O6qU5ZO8wxxAjw89xry0dnoOQD/yA4H
748        // 7CRCo9vVDpV2hqIvHY9RI2T7cek28kmQpKvNvvK+ovmM138dHKViWULHk0fBRt7m
749        // 4wQ+tiL2PmJ/Tr8g1gVhM6S9D1XdE9z0KeDnODCWn1Q8sx2G2ah4ynnYQURDWcwO
750        // McAoP6bdJ7cCt+4F2tEsMPf4S/EwlnjvuNoQjvztxCPahYe9EnyggtQXyHJveIn7
751        // gDJsP6b93VB6x4QbLy5ch4DUhqDWginuKVeo7CTgDkq03j/IEaS1BHwreSDQceny
752        // +bYWONwV+4TMpGytKOHvU5288kmHbyZHdXuaXk8LLqbnqr30fa6Cbp4llCi9sH5a
753        // Kmi5jxQfVTe+elkMs7oVsLsVgkZS6NqPcOuEckAFijNqG223+IJoqvifCzO5Bdcs
754        // JTOLE+YaUYc8LUJwIaPykgcXmtMvQjeT8MCQ3aAlzkHfDpSvvICrXtqbGiaKolU6
755        // mQIDAQAB
756        // -----END PUBLIC KEY-----
757
758        let n = BigUint::from_bytes_be(&hex!(
759            "
760            90c06207caac3555c0b0947a5e8b681f5af6aed665ff1cd42b6b487f2f7d68f1
761            38f3dbbee6d2f10908507fe6bcf75e7cbd20e9af6ff1c202bcc3dbb45e9bb69b
762            b5d12a354c4b463a50820d16879373ceeb5574fdd9272be3b90d55c1a64855de
763            cf80520e94be2caa56c1737ed0042ef9c99c7ddb6cc76f3ada211ba90beae0fc
764            0a19024e74e474ca5747f0ee327892bf6eebc83974478dbfbebed40d0ffc626c
765            518071df5626abda386eed72585b676efb99b3ba111fb2f4b8fb0323bccb0c9b
766            5aa35e1da54f1cccac3e14fb1d4588d7b9b9f62d4ea6e570c049efcc34101147
767            fd7798549a42d86f9a90cee7fa0dd9f1ff4e10242280824872afd09782757abc
768            46773cab6989c08747193b7aa4c49a0065830a87e6f7e54455758b2c10317267
769            b9187358e41a5e5fef6fcbf81c8bc5e136ad1192aa7f3a5bc9270b22261b3c40
770            211d729d64c776cd8f219126e27227de3c0a40666b8da40c71243673a6187baf
771            8943eadf0c3d3fd150076dad97e286a68185db8523a61e548cba7a6834e4ce98
772            5af954c9eafb9d819a3d14b526a0f8d2fef13ad99ee48f10c3a00f8853d7853a
773            812b7a1c72bed38066f75779690bc12af9eb0d1eb8e2f7c4757c84e415725629
774            d15c4d68c18213f18a86d4ccc08552b3c80c97165de073ac0440af253e8578c4
775            8857f396e5eba6cd01ed1250feb2c32d77939f8be8bd47874151daed87e8c963
776            32f697ea7950bee7a2c12bb484200bcbd08de5aeae6f22ff9922e38075b56026
777            2472f039de08e9362cfdd19c0f0cd0749ebd85bddc3882fb887f9789ed8e388e
778            7e2eb2455399f166d5c9767ff378f8ebea465a0be2d2e3326fe6ed80e5e3050b
779            fb6c6a9dc8731ce4baa4e5b17b131113c79d6f290318095e37e7571a4ba697ab
780            5ea56190131e06d300310064776ba0330907e1cc41acdef4eeaa53964ef30c71
781            023c3cf71af2d1d9e83900ffc80e07ec2442a3dbd50e957686a22f1d8f512364
782            fb71e936f24990a4abcdbef2bea2f98cd77f1d1ca5625942c79347c146dee6e3
783            043eb622f63e627f4ebf20d6056133a4bd0f55dd13dcf429e0e73830969f543c
784            b31d86d9a878ca79d841444359cc0e31c0283fa6dd27b702b7ee05dad12c30f7
785            f84bf1309678efb8da108efcedc423da8587bd127ca082d417c8726f7889fb80
786            326c3fa6fddd507ac7841b2f2e5c8780d486a0d68229ee2957a8ec24e00e4ab4
787            de3fc811a4b5047c2b7920d071e9f2f9b61638dc15fb84cca46cad28e1ef539d
788            bcf249876f2647757b9a5e4f0b2ea6e7aabdf47dae826e9e259428bdb07e5a2a
789            68b98f141f5537be7a590cb3ba15b0bb15824652e8da8f70eb847240058a336a
790            1b6db7f88268aaf89f0b33b905d72c25338b13e61a51873c2d427021a3f29207
791            179ad32f423793f0c090dda025ce41df0e94afbc80ab5eda9b1a268aa2553a99"
792        ));
793
794        let e = BigUint::from_u64(65537).unwrap();
795
796        assert_eq!(
797            RsaPublicKey::new(n, e).err().unwrap(),
798            Error::ModulusTooLarge
799        );
800    }
801
802    #[test]
803    fn build_key_from_primes() {
804        const RSA_2048_PRIV_DER: &[u8] = include_bytes!("../tests/examples/pkcs8/rsa2048-priv.der");
805        let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_PRIV_DER).unwrap();
806        assert_eq!(ref_key.validate(), Ok(()));
807
808        let primes = ref_key.primes().to_vec();
809
810        let exp = ref_key.e().clone();
811        let key =
812            RsaPrivateKey::from_primes(primes, exp).expect("failed to import key from primes");
813        assert_eq!(key.validate(), Ok(()));
814
815        assert_eq!(key.n(), ref_key.n());
816
817        assert_eq!(key.dp(), ref_key.dp());
818        assert_eq!(key.dq(), ref_key.dq());
819
820        assert_eq!(key.d(), ref_key.d());
821    }
822
823    #[test]
824    fn build_key_from_p_q() {
825        const RSA_2048_SP800_PRIV_DER: &[u8] =
826            include_bytes!("../tests/examples/pkcs8/rsa2048-sp800-56b-priv.der");
827        let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_SP800_PRIV_DER).unwrap();
828        assert_eq!(ref_key.validate(), Ok(()));
829
830        let primes = ref_key.primes().to_vec();
831        let exp = ref_key.e().clone();
832
833        let key = RsaPrivateKey::from_p_q(primes[0].clone(), primes[1].clone(), exp)
834            .expect("failed to import key from primes");
835        assert_eq!(key.validate(), Ok(()));
836
837        assert_eq!(key.n(), ref_key.n());
838
839        assert_eq!(key.dp(), ref_key.dp());
840        assert_eq!(key.dq(), ref_key.dq());
841
842        assert_eq!(key.d(), ref_key.d());
843    }
844
845    #[test]
846    fn test_key_invalid_primes() {
847        let e = RsaPrivateKey::from_components(
848            BigUint::from_u64(239).unwrap(),
849            BigUint::from_u64(185).unwrap(),
850            BigUint::zero(),
851            vec![
852                BigUint::from_u64(1).unwrap(),
853                BigUint::from_u64(239).unwrap(),
854            ],
855        )
856        .unwrap_err();
857        assert_eq!(e, Error::InvalidPrime);
858    }
859}