Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ecies/js-post-quantum/llms.txt
Use this file to discover all available pages before exploring further.
@ecies/post-quantum is built on well-audited, standards-track cryptographic primitives. Understanding what the library guarantees — and what it deliberately leaves outside its scope — helps you integrate it correctly into a larger security architecture. This page covers the ML-KEM standard, the KEM+DEM construction used internally, authentication properties, and practical algorithm selection guidance.
What is ML-KEM?
ML-KEM (Module-Lattice Key Encapsulation Mechanism) is standardised in NIST FIPS 203 and is the primary post-quantum key encapsulation mechanism selected by NIST. It replaces classical Diffie-Hellman and elliptic-curve key exchange in post-quantum settings. ML-KEM is based on the hardness of the Module Learning With Errors (MLWE) problem, which is believed to resist attacks by both classical and quantum computers — including Shor’s algorithm, which breaks RSA and ECC. Three parameter sets are defined, each targeting a different security level:| Variant | Security Level | Classical Equivalent |
|---|---|---|
| ML-KEM-512 | NIST Level 1 | ≈ AES-128 |
| ML-KEM-768 | NIST Level 3 | ≈ AES-192 |
| ML-KEM-1024 | NIST Level 5 | ≈ AES-256 |
Encryption scheme
@ecies/post-quantum uses a standard KEM+DEM (Key Encapsulation Mechanism + Data Encapsulation Mechanism) construction, also known as a hybrid encryption scheme:
- KEM phase — ML-KEM
encapsulateis called with the receiver’s public key. It produces acipherText(the PKE ciphertext) and asharedSecret(256 bits). ThesharedSecretis used directly as the symmetric key. - DEM phase — The plaintext is encrypted with the chosen AEAD cipher (AES-256-GCM or XChaCha20-Poly1305) using the
sharedSecretas the key and a freshly generated random nonce.
| Variant | PKE Size |
|---|---|
| ML-KEM-512 | 768 bytes |
| ML-KEM-768 | 1088 bytes |
| ML-KEM-1024 | 1568 bytes |
Authentication
Both supported symmetric ciphers — AES-256-GCM and XChaCha20-Poly1305 — are AEAD (Authenticated Encryption with Associated Data) ciphers. This means every encrypted payload carries a cryptographic authentication tag that covers both the ciphertext and the nonce. During decryption, the library verifies the tag before returning any plaintext. If the ciphertext has been tampered with, truncated, or corrupted in any way, decryption throws an error and no plaintext is returned. This provides both confidentiality (only the holder of the secret key can read the message) and integrity (any modification to the ciphertext is detected).MITM considerations
ML-KEM encapsulation is not inherently identity-bound — the encapsulation step takes only a public key as input, with no binding to a verified identity. A man-in-the-middle attacker who can substitute a different public key before encryption will receive a ciphertext they can decrypt, without the intended recipient ever learning.The AEAD layer will detect any tampering with the ciphertext in transit, but it cannot detect a public-key substitution attack that occurs before encryption. To prevent this, always distribute and verify public keys through a trusted, authenticated channel (e.g., a PKI, a signed key server response, or a pre-shared key fingerprint). The library does not include a key-distribution mechanism.
Choosing algorithms
Which ML-KEM variant should I use?
Which ML-KEM variant should I use?
ML-KEM-768 (the default) is the right choice for the overwhelming majority of applications. It is the variant explicitly recommended by NIST (FIPS 203, p40) and provides a security level equivalent to AES-192, which is well above any known or foreseeable classical or quantum attack.Use ML-KEM-1024 if you are protecting data that must remain confidential for decades, or if your threat model requires a maximum security margin regardless of the performance and payload-size cost (an extra 480 bytes per message compared to ML-KEM-768).Use ML-KEM-512 only in severely resource-constrained environments where the 320-byte payload saving over ML-KEM-768 matters and where a security level equivalent to AES-128 is accepted by your policy.
Which symmetric cipher should I use?
Which symmetric cipher should I use?
AES-256-GCM (the default) is the faster choice on any CPU with AES-NI hardware acceleration, which includes virtually all modern x86-64, ARM Cortex-A, and Apple Silicon processors. The library automatically uses the native
node:crypto implementation on Node.js and Bun, making it the highest-throughput option in those environments.XChaCha20-Poly1305 ("xchacha20") is preferred when:- The target device lacks hardware AES acceleration (many embedded, IoT, or older mobile processors).
- You require constant-time behaviour by design, independent of the underlying hardware.
- You are running in a browser on an unknown device fleet and want consistent timing regardless of hardware capability.
What does the nonce length affect for AES-256-GCM?
What does the nonce length affect for AES-256-GCM?
The
symmetricNonceLength option accepts 12 or 16 bytes and applies only to AES-256-GCM.A 12-byte nonce is the most widely used GCM nonce length and aligns with the NIST SP 800-38D recommendation for random nonces. It produces slightly smaller ciphertexts (4 bytes per message).A 16-byte nonce (the default in this library) provides a larger random nonce space — 2¹²⁸ possible nonces versus 2⁹⁶ — which makes random nonce collision statistically negligible even at very high message volumes. It is the safer default when messages are numerous and nonces are generated randomly rather than tracked as counters.Both options are cryptographically secure. The default of 16 bytes is the more conservative choice.Dependencies
The library is built on a small set of audited, widely deployed cryptographic libraries:@noble/post-quantum— ML-KEM-512/768/1024 implementation by Paul Miller. Audited and used across the JavaScript cryptography ecosystem.@noble/ciphers/@ecies/ciphers— AES-256-GCM and XChaCha20-Poly1305 implementations.@ecies/cipherswrapsnode:crypto’s native AES-256-GCM on runtimes that support it, falling back to the pure-JS@noble/cipherspath elsewhere.@noble/hashes— ProvidesrandomBytesfor secure nonce generation.