libcrux-ml-kem

Crates.iolibcrux-ml-kem
lib.rslibcrux-ml-kem
version0.0.3
created_at2024-07-02 14:18:41.169007+00
updated_at2025-07-01 06:51:50.653551+00
descriptionLibcrux ML-KEM & Kyber implementations
homepagehttps://github.com/cryspen/libcrux
repositoryhttps://github.com/cryspen/libcrux
max_upload_size
id1289617
size1,666,239
Franziskus Kiefer (franziskuskiefer)

documentation

README

ML-KEM

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.

Verification

verified

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.

Usage

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);

Kyber Round 3

The kyber flag also gives access to an, as yet, unverified implementation of Kyber as submitted in Round 3 of the NIST PQ competition.

Commit count: 4151

cargo fmt