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
-
EncryptPkcs1v15PKCS#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
-
Pkcs8PKCS#8 format (PrivateKeyInfo) - works with all key types.
-
Pkcs1PKCS#1 format (RSAPrivateKey) - RSA-specific.
Salt length options for RSA-PSS signatures.
pub type PssSaltLength {
SaltLengthHashLen
SaltLengthMax
SaltLengthExplicit(Int)
}
Constructors
-
SaltLengthHashLenSalt length equals hash output length (recommended).
-
SaltLengthMaxMaximum salt length for the key and hash combination.
-
SaltLengthExplicit(Int)Explicit salt length in bytes.
Format for encoding/decoding RSA public keys.
pub type PublicKeyFormat {
Spki
RsaPublicKey
}
Constructors
-
SpkiSPKI format (SubjectPublicKeyInfo) - works with all key types.
-
RsaPublicKeyPKCS#1 format (RSAPublicKey) - RSA-specific.
Padding scheme for RSA signatures.
pub type SignPadding {
Pkcs1v15
Pss(PssSaltLength)
}
Constructors
-
Pkcs1v15PKCS#1 v1.5 signature padding.
-
Pss(PssSaltLength)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 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.