[ANN] rkyber v0.1.0: minimalist pure Rust implementation of FIPS 203 / Kyber post-quantum Key Encapsulation Mechanism

Three years late to the party, I want to announce our pure Rust implementation of the cryptographic NIST standard FIPS 203 (ML-KEM) and Kyber, its predecessor from which the standard was created and our project took its name:

rkyber (currently licensed under Apache-2.0 or MIT)

As Peter Schwabe (one of the authors of Kyber/ML-KEM) said in his inaugural lecture, asymmetric cryptography today is post-quantum.
Just as RSA and DH were eclipsed by X25519, we are now changing to key encapsulation mechanisms which should stay secure even in the future some quantum computer may try to crack all the harvested internet connections.

Following Cryspen and RustCrypto, we cleaned up our old pure Rust Kyber port (which took a bit longer due to life events) and made it secure against the KyberSlash attack.
We differentiate our code by currently not using hand-proven assembly optimizations, only requiring the Rust toolchain, on a unified code base (no Rust nightly const-generics needed) in which we minimize trait use.
We pared it down to a minimum of two dependencies (working on stable Rust 1.81+), test against kyber-ref and NIST ACVP, made it optionally free of unsafe random number generation, no_std, optionally use zeroize, all under one API parametric over the three ML-KEM strengths (analog for Kyber).
Speed is comparable to other implementations in our benchmarks (including optional cycle count benchmarking like the real cryptography papers on IACR eprint do), but we prefer allocation on call-site (for stronger control over memory cleaning) and functions that can be optimized under the hood. We include a script for benchmarking that can be customized easily and invite you to benchmark it yourself.

Simple examples are provided, even for using Kyber 512, Kyber 768, and ML-KEM 768 from the same file without being able to introduce illegal cryptographic operations from the public API (which is checked at compile-time).

No external security analysis yet, though one author spent some years working on cryptographic constant-time analysis. You are very much invited to talk to us about future directions that are of interest to you! :wink:

Version 0.2.0 and some highlights:

  • Better benchmarking for expected use-cases (target-cpu=native), we found our code to be more than on par with other portable implementations, i.e. the fastest portable Rust ML-KEM we checked on our hardware. YMMW, the hardware you have matters more than the numbers on our hardware.
  • We checked our builds to be reproducible. Helper script included.
  • Better protection of secret key bytes in our API, hiding the private field.
  • New traitless API, if you want simple functions and leave traits up to our implementation.
  • Main API landing point of the module without needing to go for specific submodules.
  • Relaxed dependencies to be compatible with crates available in Debian stable.
  • NIST test vector helper script, no need to hunt for the feature name.
  • Some infrastructure for our X-Wing RFC draft 10 implementation (also published now as rxwing on Codeberg and as version 0.1.0-draft10 on crates.io)

We might try some handcrafted assembly for even better performance, since currently according to our experiments, libcrux still wins out this way. Please tell us if you have strong opinions on portable Rust vs. some included assembly! :slight_smile: