FIPS 203 ML-KEM
ML-KEM-512, ML-KEM-768 and ML-KEM-1024, the key-encapsulation mechanism NIST standardised from CRYSTALS-Kyber, behind one KemCore trait.
How the API is shapedOpen-source Rust library
kyberlib implements ML-KEM, the key-encapsulation mechanism NIST standardised from CRYSTALS-Kyber, in pure Rust, and passes all 180 NIST ACVP test vectors.
What it does
Each card opens its section on the features page.
ML-KEM-512, ML-KEM-768 and ML-KEM-1024, the key-encapsulation mechanism NIST standardised from CRYSTALS-Kyber, behind one KemCore trait.
How the API is shapedAll 180 key-generation, encapsulation and decapsulation vectors from NIST's ACVP server pass byte for byte, across the three parameter sets.
How conformance is testedNo division or remainder on secret-derived values. A script in CI fails the build if one is reintroduced.
How timing leaks are kept outThe default build compiles with unsafe code forbidden. Only the optional AVX2 backend opts back in.
How unsafe is containedDecapsulation keys cannot be copied, are wiped from memory when dropped, and print as [REDACTED] in logs and panics.
How secrets are handledThe core builds without the standard library for embedded targets, and kyberlib-wasm wraps it for browsers and JavaScript runtimes.
Where it runsParameter sets
All three implement KemCore and can be used together in one build. Sizes are in bytes.
NIST category 1
Public key 800, secret key 1,632, ciphertext 768. The smallest keys and ciphertexts.
Compare the parameter setsNIST category 3
Public key 1,184, secret key 2,400, ciphertext 1,088. The default parameter set, and the one used by the hybrid TLS key exchange.
Compare the parameter setsNIST category 5
Public key 1,568, secret key 3,168, ciphertext 1,568. The highest security level.
Compare the parameter setsInstall
Add the crate, generate a key pair, encapsulate against the public key and decapsulate with the secret key. kyberlib needs Rust 1.74 or newer.
use kyberlib::{KemCore, MlKem768};
fn main() -> Result<(), kyberlib::KyberLibError> {
let mut rng = rand::thread_rng();
// Receiver: a key pair
let (dk, ek) = MlKem768::generate(&mut rng)?;
// Sender: a ciphertext and its shared secret
let (ct, ss_sender) = ek.encapsulate(&mut rng)?;
// Receiver: the same shared secret
let ss_receiver = dk.decapsulate(&ct);
assert_eq!(ss_sender, ss_receiver);
Ok(())
}kyberlib publishes its threat model, its constant-time claims function by function, and the checks behind them.
kyberlib has not had a third-party audit yet; version 1.0 will not be tagged until one is complete. The audit request for proposals and the materials package are in the repository.
In numbers
Counted from the kyberlib repository at version 0.0.10.
kyberlib is a free, open-source Rust library that implements FIPS 203 ML-KEM, the post-quantum key-encapsulation mechanism NIST published in August 2024 as the standardised form of CRYSTALS-Kyber. Two parties use it to agree on a 32-byte shared secret: the receiver generates a key pair, the sender encapsulates a secret against the public key, and the receiver decapsulates the ciphertext to recover the same secret. It supports ML-KEM-512, ML-KEM-768 and ML-KEM-1024, builds with or without the Rust standard library, and is dual-licensed under Apache-2.0 or MIT.
Both names describe the same family, but the bytes differ. Up to version 0.0.6, kyberlib implemented CRYSTALS-Kyber Round 3. Since 0.0.7 it implements FIPS 203 ML-KEM, which changes the key-generation domain separator, the encapsulation pre-hash and the rejection key derivation. Keys, ciphertexts and shared secrets from 0.0.6 do not work with 0.0.7 or later; the migration guide covers the change.
Read the security page first. kyberlib is pre-1.0 and has not yet had a third-party audit: version 1.0 will not be tagged until one is complete and its findings are fixed. It is not FIPS 140-3 validated, and as a pure-Rust crate it cannot be on its own. The FAQ lists the other cases where a different library fits better today.
kyberlib is written by Sebastien Rousseau and its contributors. The source, the issue tracker and every release are on GitHub; the crates are on crates.io. Read more on the about page.