//! RSA.
//!
//! Built on the constant-time [`bignum`](crate::bignum) layer and the
//! [`rng`](crate::rng) CSPRNG. This module currently provides the
//! number-theoretic groundwork — primality testing and prime generation; key
//! types, key generation, and PKCS#1 operations are layered on top.

mod keys;
mod prime;

#[cfg(feature = "alloc")]
mod boxed;
#[cfg(feature = "alloc")]
mod emsa;
#[cfg(all(feature = "der", feature = "alloc"))]
mod encoding;
#[cfg(feature = "key")]
mod key_impl;
#[cfg(feature = "alloc")]
mod pkcs1;
#[cfg(feature = "alloc")]
mod pss;
#[cfg(all(feature = "x509", feature = "alloc"))]
pub(crate) mod registry;

#[cfg(feature = "alloc")]
pub use boxed::{BoxedRsaPrivateKey, BoxedRsaPublicKey};
pub use keys::{RsaPrivateKey, RsaPublicKey};
pub use prime::{is_prime, random_prime};

#[cfg(feature = "alloc")]
pub use pkcs1::Pkcs1Digest;

/// Errors produced by RSA operations.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
    /// The message (or encoded digest) is too long for the modulus.
    MessageTooLong,
    /// A ciphertext or signature length does not match the modulus size.
    InvalidLength,
    /// Decryption failed: the recovered padding was malformed.
    Decryption,
    /// Signature verification failed.
    Verification,
    /// The key's component values are not a well-formed RSA public/private key
    /// (e.g. `e = 0`, `e` even, `e ≥ n`).
    InvalidKey,
}

impl core::fmt::Display for Error {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let msg = match self {
            Error::MessageTooLong => "message too long for RSA modulus",
            Error::InvalidLength => "ciphertext/signature length mismatch",
            Error::Decryption => "RSA decryption error",
            Error::Verification => "RSA signature verification failed",
            Error::InvalidKey => "RSA key components are malformed",
        };
        f.write_str(msg)
    }
}

impl core::error::Error for Error {}
