Crates.io | libcrux-ml-kem |
lib.rs | libcrux-ml-kem |
version | 0.0.3 |
created_at | 2024-07-02 14:18:41.169007+00 |
updated_at | 2025-07-01 06:51:50.653551+00 |
description | Libcrux ML-KEM & Kyber implementations |
homepage | https://github.com/cryspen/libcrux |
repository | https://github.com/cryspen/libcrux |
max_upload_size | |
id | 1289617 |
size | 1,666,239 |
This crate implements all three ML-KEM (FIPS 203) variants 512, 768, and 1024. For each algorithm, it inlcudes a portable Rust implementation, as well as SIMD implementations for Intel AVX2 and AArch64 Neon platforms.
The portable and AVX2 code for field arithmetic, NTT polynomial arithmetic, serialization, and the generic code for high-level algorithms is formally verified using hax and F*.
Please refer to this file for detail on the verification of this crate.
By default, all ML-KEM parameter sets are enabled. If required, they are
available individually under feature flags mlkem512
, mlkem768
,
mlkem1024
.
Functions in this crate use CPU feature detection to pick the most efficient version on each platform. To use a specific version with your own feature detection use e.g. one of the following
mlkem768::avx2::generate_key_pair
,mlkem768::neon::generate_key_pair
,mlkem768::portable::generate_key_pair
,analogously for encapsulation and decapsulation.
use rand::{rngs::OsRng, RngCore};
// Ensure you use good randomness.
// It is not recommended to use OsRng directly!
// Instead it is highly encouraged to use RNGs like NISTs DRBG to account for
// bad system entropy.
fn random_array<const L: usize>() -> [u8; L] {
let mut rng = OsRng;
let mut seed = [0; L];
rng.try_fill_bytes(&mut seed).unwrap();
seed
}
use libcrux_ml_kem::*;
// This example uses ML-KEM 768. The other variants can be used the same way.
// Generate a key pair.
let randomness = random_array();
let key_pair = mlkem768::generate_key_pair(randomness);
// Encapsulating a shared secret to a public key.
let randomness = random_array();
let (ciphertext, shared_secret) = mlkem768::encapsulate(key_pair.public_key(), randomness);
// Decapsulating a shared secret with a private key.
let shared_secret_decapsulated = mlkem768::decapsulate(key_pair.private_key(), &ciphertext);
The kyber
flag also gives access
to an, as yet, unverified implementation of Kyber as submitted in Round 3 of
the NIST PQ competition.