mlkem-native
A portable C90 implementation of ML-KEM (FIPS 203) with formally verified C and assembly, meant to be copied into other cryptographic libraries; AWS-LC, liboqs and, through AWS-LC, rustls use it.
PQCA project- What it is
- Post-quantum cryptography
- Type
- Open source
- Made by
- PQ Code Package (Post-Quantum Cryptography Alliance)
- Foundation
- Post-Quantum Cryptography Alliance. Part of the PQ Code Package project, with mldsa-native and slhdsa-c. Part of the Linux Foundation
- License
- Apache 2.0, ISC or MIT, at your choice
- Facts checked
- 28 October 2026
What it is
mlkem-native is the PQ Code Package’s implementation of ML-KEM, the NIST key-encapsulation standard behind hybrid TLS key exchange. It started as a fork of the ML-KEM reference code and is split into a fixed C frontend and swappable backends for the arithmetic and for SHA-3 (FIPS 202): portable C by default, plus native code for 64-bit Arm (Neon), x86_64 (AVX2), RISC-V (RVV) and POWER (VSX), and an experimental one for Armv8.1-M microcontrollers. It is not a library you link against so much as source you vendor: you copy the mlkem/ tree, or a single-file mlkem_native.c plus its assembly, into your own build, set the parameter set (512, 768 or 1024) and a symbol prefix in a config header, and supply your own random number generator and, if you like, your own SHA-3.
What sets it apart is proof. All C code for the core and the Arm and x86 backends is proved free of memory and integer overflow with the C Bounded Model Checker (CBMC), and all AArch64 and x86_64 assembly is proved functionally correct, memory-safe and constant-time at the object-code level in the HOL Light theorem prover, using AWS’s s2n-bignum models of those CPUs. It is tested against NIST’s ACVP and Google’s Wycheproof test vectors, and timing behaviour is also checked with valgrind across compilers and flags. That is why other libraries adopted it: it became the default ML-KEM in liboqs from version 0.13.0 in April 2025, and AWS imported it into AWS-LC in v1.50.0 the same month, which put it under rustls, whose default crypto provider is AWS-LC. Version 2.0.0, released on 7 August 2026, cleaned up the API; v1.3 is supported with bug fixes until February 2027.
Why teams pick it
- Machine-checked proofs of memory safety, functional correctness and constant-time assembly, with a published analysis of what the proofs do and don’t cover
- Fast on the platforms that matter, with hand-written and SLOTHY-superoptimised Arm assembly and AVX2, RVV and POWER backends
- Built to be embedded: C90, no build system to adopt, configurable symbol prefix, bring-your-own RNG and SHA-3, and a permissive choice of three licences
- Already in production paths through AWS-LC and rustls, and the default ML-KEM in liboqs
Watch out for
- Only ML-KEM: signatures live in the sibling projects mldsa-native and slhdsa-c, and hybrid key exchange, TLS and key storage are the host library’s job
- Protects against timing side channels only; power, electromagnetic, speculative-execution and fault-injection attacks are out of scope
- The C code assumes constant-time 32-bit multiplication, which some small cores without a hardware multiplier don’t provide
- Not a FIPS 140 module by itself: validation comes with the library that embeds it, and v2.0 changed APIs that integrators on v1.x must migrate from before February 2027
Alternatives
What all post-quantum cryptography have in common →Compare side by side →How it fits with other technologies
What mlkem-native uses
What uses mlkem-native
Generate, encapsulate, decapsulate (MLK_CONFIG_NAMESPACE_PREFIX set to mlkem) · c
#include "mlkem_native/mlkem_native.h" /* ML-KEM-768 by default */
uint8_t pk[MLKEM768_PUBLICKEYBYTES], sk[MLKEM768_SECRETKEYBYTES];
uint8_t ct[MLKEM768_CIPHERTEXTBYTES];
uint8_t ss_alice[MLKEM_BYTES], ss_bob[MLKEM_BYTES];
if (mlkem_keypair(pk, sk) != 0) abort(); /* uses your randombytes() */
if (mlkem_enc(ct, ss_bob, pk) != 0) abort(); /* rejects a malformed pk */
if (mlkem_dec(ss_alice, ct, sk) != 0) abort(); /* ss_alice == ss_bob */See it in a real stack
No architecture uses mlkem-native yet. Drop it into the playground and wire it up yourself.Open playground →Where it came from2024–2026
When the Linux Foundation launched the Post-Quantum Cryptography Alliance on 6 February 2024, one of its two founding projects was the PQ Code Package, set up to build high-assurance, production-ready implementations of the coming standards, starting with ML-KEM. The mlkem-native repository was created in March 2024, and earlier PQ Code Package efforts with similar aims, mlkem-c-generic and mlkem-c-embedded, have since been archived.
The team, led by maintainers Hanno Becker and Matthias Kannwischer, combined a reference-code base with verified assembly. A first alpha came out in December 2024 and v1.0.0 on 4 June 2025, by which time liboqs and AWS-LC had already adopted it. Releases in 2026 added RISC-V and POWER backends, and v2.0.0 followed in August 2026, while the same approach was applied to signatures in mldsa-native, which became liboqs’s default ML-DSA in July 2026.
Why it’s built this way
- Prove the code instead of only testing it
- Bugs in cryptographic code hide in rare inputs and in timing. CBMC proves the C free of overflows for every input, and HOL Light proves the assembly computes the right result in constant time.
- Fork the reference implementation
- Starting from the ML-KEM reference code kept the frontend close to the code NIST and reviewers already know, so the optimised backends are the only part that differs much.
- Source to embed, not a library to link
- The users it targets, cryptographic libraries such as AWS-LC and liboqs, have their own build systems, RNGs and SHA-3, so mlkem-native lets them plug those in and namespace its symbols.
Timeline
- 2024
PQ Code Package founded with the PQCA (February 6); mlkem-native repository created (March); first alpha (December)
- 2025
Default ML-KEM in liboqs 0.13.0 and imported into AWS-LC v1.50.0 (April); v1.0.0 released (June 4)
- 2026
v2.0.0 released (August 7); v1.3 supported until February 2027
- Linux Foundation: Post-Quantum Cryptography Alliance launches (February 6, 2024; PQ Code Package, starting with ML-KEM)
- GitHub: pq-code-package organisation (mlkem-native, mldsa-native, slhdsa-c; archived mlkem-c-generic and mlkem-c-embedded)
- mlkem-native MAINTAINERS.md
- mlkem-native releases (v1.0.0-alpha December 2024, v1.0.0 June 4, 2025, v2.0.0 August 7, 2026)
- AWS-LC v1.50.0 release notes (April 25, 2025; import mlkem-native)
- liboqs 0.13.0 release notes (April 16, 2025; mlkem-native as default ML-KEM)
- liboqs 0.16.0 release notes (July 9, 2026; mldsa-native as default ML-DSA)
Sources7 · facts checked 28 October 2026
- mlkem-native README (backends, formal verification, security scope, applications, test vectors)
- mlkem-native SOUNDNESS.md (scope and assumptions of the proofs)
- mlkem-native LICENSE (Apache-2.0 OR ISC OR MIT)
- mlkem-native v2.0.0 release notes (API changes, v1.3 support until February 2027)
- mlkem-native basic example (config header, namespace prefix, randombytes)
- AWS-LC v1.50.0 release notes (import mlkem-native)
- PQCA: Projects (PQ Code Package)
