Open-source Rust library

Post-quantum key exchange for Rust, built to FIPS 203

kyberlib implements ML-KEM, the key-encapsulation mechanism NIST standardised from CRYSTALS-Kyber, in pure Rust, and passes all 180 NIST ACVP test vectors.

  • Linux
  • macOS
  • Windows
  • WebAssembly
  • no_std + alloc

What it does

A post-quantum key exchange you can audit

Each card opens its section on the features page.

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 shaped

NIST ACVP conformance

All 180 key-generation, encapsulation and decapsulation vectors from NIST's ACVP server pass byte for byte, across the three parameter sets.

How conformance is tested

KyberSlash-clean arithmetic

No division or remainder on secret-derived values. A script in CI fails the build if one is reintroduced.

How timing leaks are kept out

No unsafe code by default

The default build compiles with unsafe code forbidden. Only the optional AVX2 backend opts back in.

How unsafe is contained

Secret keys that clean up after themselves

Decapsulation keys cannot be copied, are wiped from memory when dropped, and print as [REDACTED] in logs and panics.

How secrets are handled

WebAssembly and no_std

The core builds without the standard library for embedded targets, and kyberlib-wasm wraps it for browsers and JavaScript runtimes.

Where it runs

Parameter sets

Three security levels, one trait

All three implement KemCore and can be used together in one build. Sizes are in bytes.

NIST category 1

ML-KEM-512

Public key 800, secret key 1,632, ciphertext 768. The smallest keys and ciphertexts.

Compare the parameter sets

NIST category 3

ML-KEM-768

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 sets

NIST category 5

ML-KEM-1024

Public key 1,568, secret key 3,168, ciphertext 1,568. The highest security level.

Compare the parameter sets

Install

A shared secret in ten lines of Rust

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.

  • cargo add kyberlib
  • cargo add kyberlib-wasm
src/main.rs
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(())
}
Security

Built to be checked, not taken on trust

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.

NIST ACVP vectors
180 / 180
Release signing
Keyless cosign
Build provenance
SLSA
Cryptography bill of materials
CycloneDX

In numbers

What the workspace ships

Counted from the kyberlib repository at version 0.0.10.

Parameter sets
3
ACVP vectors passing
180
Minimum Rust version
1.74
Crates on crates.io
2
  • kyberlib: on crates.io
  • kyberlib-wasm: on crates.io
  • kyberlib-hybrid: in the repository
  • kyberlib-pkcs8: in the repository
  • kyberlib-asm: in the repository

What is kyberlib?

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.

Is it CRYSTALS-Kyber or ML-KEM?

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.

Can I use it in production?

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.

Who makes it?

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.