kryptos/rsa

RSA (Rivest-Shamir-Adleman) cryptography.

RSA key generation, signing, and encryption. RSA keys can be used for both digital signatures and encryption.

Key Generation

import kryptos/rsa

let assert Ok(#(private_key, public_key)) = rsa.generate_key_pair(2048)

Signing (RSA-PSS)

import kryptos/rsa
import kryptos/hash

let assert Ok(#(private_key, public_key)) = rsa.generate_key_pair(2048)
let message = <<"hello world":utf8>>
let padding = rsa.Pss(rsa.SaltLengthHashLen)
let signature = rsa.sign(private_key, message, hash.Sha256, padding)
let valid = rsa.verify(public_key, message, signature, hash.Sha256, padding)

Encryption (RSA-OAEP)

import kryptos/rsa
import kryptos/hash

let assert Ok(#(private_key, public_key)) = rsa.generate_key_pair(2048)
let plaintext = <<"secret":utf8>>
let padding = rsa.Oaep(hash: hash.Sha256, label: <<>>)
let assert Ok(ciphertext) = rsa.encrypt(public_key, plaintext, padding)
let assert Ok(decrypted) = rsa.decrypt(private_key, ciphertext, padding)

Types

Padding scheme for RSA encryption.

pub type EncryptPadding {
  EncryptPkcs1v15
  Oaep(hash: hash.HashAlgorithm, label: BitArray)
}

Constructors

  • EncryptPkcs1v15

    PKCS#1 v1.5 encryption padding.

    Warning: Vulnerable to padding oracle attacks. Prefer OAEP for new applications.

    JavaScript target: Decryption may fail on Node.js 20.x due to CVE-2023-46809 which disables PKCS#1 v1.5 decryption to prevent the Marvin timing attack. Use Node.js 22+ or OAEP padding instead.

  • Oaep(hash: hash.HashAlgorithm, label: BitArray)

    RSA-OAEP (Optimal Asymmetric Encryption Padding).

    The hash algorithm is used for both OAEP and MGF1. The label is optional associated data (usually empty).

An RSA private key.

pub type PrivateKey

Format for encoding/decoding RSA private keys.

pub type PrivateKeyFormat {
  Pkcs8
  Pkcs1
}

Constructors

  • Pkcs8

    PKCS#8 format (PrivateKeyInfo) - works with all key types.

  • Pkcs1

    PKCS#1 format (RSAPrivateKey) - RSA-specific.

Salt length options for RSA-PSS signatures.

pub type PssSaltLength {
  SaltLengthHashLen
  SaltLengthMax
  SaltLengthExplicit(Int)
}

Constructors

  • SaltLengthHashLen

    Salt length equals hash output length (recommended).

  • SaltLengthMax

    Maximum salt length for the key and hash combination.

  • SaltLengthExplicit(Int)

    Explicit salt length in bytes.

An RSA public key.

pub type PublicKey

Format for encoding/decoding RSA public keys.

pub type PublicKeyFormat {
  Spki
  RsaPublicKey
}

Constructors

  • Spki

    SPKI format (SubjectPublicKeyInfo) - works with all key types.

  • RsaPublicKey

    PKCS#1 format (RSAPublicKey) - RSA-specific.

Padding scheme for RSA signatures.

pub type SignPadding {
  Pkcs1v15
  Pss(PssSaltLength)
}

Constructors

  • Pkcs1v15

    PKCS#1 v1.5 signature padding.

  • RSA-PSS (Probabilistic Signature Scheme) padding.

Values

pub fn coefficient(key: PrivateKey) -> BitArray

Returns the CRT coefficient (qi = q^-1 mod p) as big-endian bytes.

This is part of the CRT (Chinese Remainder Theorem) parameters used for efficient RSA operations.

pub fn decrypt(
  private_key: PrivateKey,
  ciphertext: BitArray,
  padding: EncryptPadding,
) -> Result(BitArray, Nil)

Decrypts data using RSA with the specified padding scheme.

pub fn encrypt(
  public_key: PublicKey,
  plaintext: BitArray,
  padding: EncryptPadding,
) -> Result(BitArray, Nil)

Encrypts data using RSA with the specified padding scheme.

Note: RSA encryption should only be used for small amounts of data (typically symmetric keys). For bulk encryption, use a symmetric cipher with a randomly generated key, then encrypt that key with RSA.

pub fn exponent1(key: PrivateKey) -> BitArray

Returns the first CRT exponent (dp = d mod (p-1)) as big-endian bytes.

This is part of the CRT (Chinese Remainder Theorem) parameters used for efficient RSA operations.

pub fn exponent2(key: PrivateKey) -> BitArray

Returns the second CRT exponent (dq = d mod (q-1)) as big-endian bytes.

This is part of the CRT (Chinese Remainder Theorem) parameters used for efficient RSA operations.

pub fn from_components(
  modulus n: BitArray,
  public_exponent e: BitArray,
  private_exponent d: BitArray,
) -> Result(#(PrivateKey, PublicKey), Nil)

Constructs an RSA private key from its components.

Creates a private key from the minimal set of components (n, e, d). CRT parameters are computed automatically using Miller’s algorithm.

Note: This function is not constant-time. The CRT parameter derivation involves operations that may leak timing information. This is acceptable for key import since the caller already possesses the secret material, but avoid calling this in timing-sensitive contexts.

Example

import kryptos/rsa

let assert Ok(#(private_key, _public_key)) = rsa.generate_key_pair(2048)
let n = rsa.modulus(private_key)
let e = rsa.public_exponent_bytes(private_key)
let d = rsa.private_exponent_bytes(private_key)
let assert Ok(#(reconstructed, _pub)) = rsa.from_components(n, e, d)
pub fn from_der(
  der: BitArray,
  format: PrivateKeyFormat,
) -> Result(#(PrivateKey, PublicKey), Nil)

Imports an RSA private key from DER-encoded data.

pub fn from_full_components(
  modulus n: BitArray,
  public_exponent e: BitArray,
  private_exponent d: BitArray,
  prime1 p: BitArray,
  prime2 q: BitArray,
  exponent1 dp: BitArray,
  exponent2 dq: BitArray,
  coefficient qi: BitArray,
) -> Result(#(PrivateKey, PublicKey), Nil)

Constructs an RSA private key from all components including CRT parameters.

pub fn from_pem(
  pem: String,
  format: PrivateKeyFormat,
) -> Result(#(PrivateKey, PublicKey), Nil)

Imports an RSA private key from PEM-encoded data.

pub fn generate_key_pair(
  bits: Int,
) -> Result(#(PrivateKey, PublicKey), Nil)

Generates an RSA key pair with the specified key size.

The key size must be >= 1024 bits.

Example

let assert Ok(#(private_key, public_key)) = rsa.generate_key_pair(2048)
pub const min_key_size: Int

The minimum allowed RSA key size in bits.

pub fn modulus(key: PrivateKey) -> BitArray

Returns the modulus (n) as big-endian bytes for an RSA private key.

pub fn modulus_bits(key: PrivateKey) -> Int

Returns the modulus size in bits for an RSA private key.

pub fn prime1(key: PrivateKey) -> BitArray

Returns the first prime factor (p) as big-endian bytes.

The RSA modulus n = p * q. This is part of the CRT (Chinese Remainder Theorem) parameters used for efficient RSA operations.

pub fn prime2(key: PrivateKey) -> BitArray

Returns the second prime factor (q) as big-endian bytes.

The RSA modulus n = p * q. This is part of the CRT (Chinese Remainder Theorem) parameters used for efficient RSA operations.

pub fn private_exponent_bytes(key: PrivateKey) -> BitArray

Returns the private exponent (d) as big-endian bytes for an RSA private key.

pub fn public_exponent(key: PrivateKey) -> Int

Returns the public exponent for an RSA private key.

pub fn public_exponent_bytes(key: PrivateKey) -> BitArray

Returns the public exponent (e) as big-endian bytes for an RSA private key.

pub fn public_key_exponent(key: PublicKey) -> Int

Returns the public exponent for an RSA public key.

pub fn public_key_exponent_bytes(key: PublicKey) -> BitArray

Returns the public exponent (e) as big-endian bytes for an RSA public key.

pub fn public_key_from_components(
  modulus n: BitArray,
  public_exponent e: BitArray,
) -> Result(PublicKey, Nil)

Constructs an RSA public key from its components.

pub fn public_key_from_der(
  der: BitArray,
  format: PublicKeyFormat,
) -> Result(PublicKey, Nil)

Imports an RSA public key from DER-encoded data.

pub fn public_key_from_pem(
  pem: String,
  format: PublicKeyFormat,
) -> Result(PublicKey, Nil)

Imports an RSA public key from PEM-encoded data.

pub fn public_key_from_private_key(key: PrivateKey) -> PublicKey

Derives the public key from an RSA private key.

pub fn public_key_modulus(key: PublicKey) -> BitArray

Returns the modulus (n) as big-endian bytes for an RSA public key.

pub fn public_key_modulus_bits(key: PublicKey) -> Int

Returns the modulus size in bits for an RSA public key.

pub fn public_key_to_der(
  key: PublicKey,
  format: PublicKeyFormat,
) -> Result(BitArray, Nil)

Exports an RSA public key to DER format.

pub fn public_key_to_pem(
  key: PublicKey,
  format: PublicKeyFormat,
) -> Result(String, Nil)

Exports an RSA public key to PEM format.

pub fn sign(
  private_key: PrivateKey,
  message: BitArray,
  hash: hash.HashAlgorithm,
  padding: SignPadding,
) -> BitArray

Signs a message using RSA with the specified hash algorithm and padding.

The message is hashed internally using the provided algorithm before signing.

pub fn to_der(
  key: PrivateKey,
  format: PrivateKeyFormat,
) -> Result(BitArray, Nil)

Exports an RSA private key to DER format.

pub fn to_pem(
  key: PrivateKey,
  format: PrivateKeyFormat,
) -> Result(String, Nil)

Exports an RSA private key to PEM format.

pub fn verify(
  public_key: PublicKey,
  message message: BitArray,
  signature signature: BitArray,
  hash hash: hash.HashAlgorithm,
  padding padding: SignPadding,
) -> Bool

Verifies an RSA signature against a message.

The same hash algorithm and padding used during signing must be used for verification.

Search Document