ML-KEM (FIPS 203)

Module-Lattice-Based Key Encapsulation Mechanism


Overview

ML-KEM is the NIST-standardized post-quantum key encapsulation mechanism defined in FIPS 203. Formerly known as CRYSTALS-Kyber, ML-KEM provides IND-CCA2-secure key encapsulation based on the hardness of the Module Learning With Errors (Module-LWE) problem. It uses the Fujisaki-Okamoto transform to achieve chosen-ciphertext security from an underlying CPA-secure public-key encryption scheme.

ML-KEM enables two parties to establish a shared secret over an insecure channel, resistant to attacks by both classical and quantum computers.


Specifications

Parameter Set NIST Level Public Key (bytes) Secret Key (bytes) Ciphertext (bytes) Shared Secret (bytes)
ML-KEM-512 1 800 1632 768 32
ML-KEM-768 3 1184 2400 1088 32
ML-KEM-1024 5 1568 3168 1568 32

Core operations:

Underlying math: Number Theoretic Transform (NTT) over the polynomial ring Z_q[X]/(X^256 + 1) with q = 3329.


Security


Hardware Acceleration

ML-KEM benefits from SIMD acceleration for its NTT (Number Theoretic Transform) operations, which dominate the computational cost.

Acceleration Target Description
AVX-2 x86-64 16-way parallel NTT butterfly operations
NEON ARM 8-way parallel NTT butterfly operations

NTT multiplication over Z_q[X]/(X^256 + 1) is the core polynomial operation in ML-KEM. The same SIMD NTT infrastructure used for Falcon applies here, adapted for the ML-KEM modulus q = 3329.


Platform Support

ML-KEM is implemented across all 10 platforms in the MetaMUI suite:

Platform Language Implementation Path
Native C metamui-crypto-c/
Systems Rust metamui-crypto-rust/
Backend Go metamui-crypto-go/
Data Science Python metamui-crypto-python/
JVM Java metamui-crypto-java/
JVM/Android Kotlin metamui-crypto-kotlin/
.NET C# metamui-crypto-csharp/
Apple Swift metamui-crypto-swift/
Web TypeScript metamui-crypto-typescript/
Browser/Edge WASM metamui-crypto-wasm/

API Example

// Key generation
let (pk, sk) = ml_kem_768::keygen(&mut rng);

// Encapsulation (sender side)
// Produces a ciphertext and a 32-byte shared secret
let (ciphertext, shared_secret_sender) = ml_kem_768::encapsulate(&pk, &mut rng);

// Decapsulation (receiver side)
// Recovers the same 32-byte shared secret from the ciphertext
let shared_secret_receiver = ml_kem_768::decapsulate(&sk, &ciphertext);

assert_eq!(shared_secret_sender, shared_secret_receiver);

Test Vectors

NIST ACVP (Automated Cryptographic Validation Protocol) test vectors are used for validation:


References

  1. FIPS 203 — Module-Lattice-Based Key-Encapsulation Mechanism Standard. National Institute of Standards and Technology (2024). https://csrc.nist.gov/pubs/fips/203/final
  2. CRYSTALS-Kyber — Avanzi, R., Bos, J., Ducas, L., et al. CRYSTALS-Kyber Algorithm Specifications and Supporting Documentation. https://pq-crystals.org/kyber/
  3. NIST PQC Standardization — Post-Quantum Cryptography project. https://csrc.nist.gov/projects/post-quantum-cryptography