FIPS 203, 204, and 205 are final
NIST finalized FIPS 203, 204, and 205 in August 2024. It is the biggest change to cryptography since public-key algorithms arrived in the 1970s, and organizations everywhere are now racing to deploy the new algorithms before large quantum computers exist.
OpenCrypt 2.0 took years of research and engineering. It is production-ready post-quantum cryptography, and it is fast.
ML-DSA and ML-KEM performance
ML-DSA signatures
ML-DSA (Module-Lattice Digital Signature Algorithm, standardized as FIPS 204) replaces classical signature schemes such as RSA and ECDSA. Our implementation is fast at every security level:
| Security Level | Key Generation | Signing | Verification |
|---|---|---|---|
| ML-DSA-44 | 22.5μs | 52.3μs | 28.9μs |
| ML-DSA-65 | 38.7μs | 74.4μs | 40.9μs |
| ML-DSA-87 | 61.2μs | 108.2μs | 58.3μs |
That is a 2x improvement over other Rust implementations. It comes from careful algorithm design and architecture-specific optimization.
ML-KEM key exchange
ML-KEM (Module-Lattice Key Encapsulation Mechanism, standardized as FIPS 203) establishes keys in a way that resists quantum attacks. We focused on the encapsulation/decapsulation round trip, which is the critical path:
| Security Level | Encapsulation | Decapsulation | Round-Trip |
|---|---|---|---|
| ML-KEM-512 | 18.7μs | 19.2μs | 37.9μs |
| ML-KEM-768 | 29.1μs | 30.5μs | 59.6μs |
| ML-KEM-1024 | 49.0μs | 51.3μs | 100.3μs |
Design decisions
Pure Rust, no unsafe code
OpenCrypt 2.0 is written entirely in safe Rust, which eliminates whole classes of memory-safety vulnerabilities. We reach competitive performance without unsafe blocks through:
- careful optimization of memory layout
- deliberate use of const generics
- compile-time loop unrolling
Constant-time execution
Every operation in OpenCrypt runs in constant time, which prevents timing side-channel attacks:
use opencrypt::ml_dsa::{MlDsa65, SigningKey, VerifyingKey};
// Key generation is constant-time
let signing_key = SigningKey::<MlDsa65>::generate(&mut rng);
let verifying_key = signing_key.verifying_key();
// Signing and verification are constant-time
let signature = signing_key.sign(message);
verifying_key.verify(message, &signature)?;
Platform-specific optimizations
OpenCrypt automatically detects and uses platform-specific intrinsics:
- AVX2/AVX-512: vectorized NTT operations on x86_64
- NEON: polynomial arithmetic optimized for ARM
- Portable: an efficient pure Rust scalar fallback for all platforms
Migration plan
For organizations planning their post-quantum migration, we recommend doing it in phases:
- Inventory: catalog all cryptographic usage in your systems.
- Hybrid mode: deploy ML-KEM alongside classical ECDH for key exchange.
- Testing: validate performance under production workloads.
- Full migration: replace the classical algorithms entirely.
In OpenCrypt 2.0, hybrid modes are supported out of the box, so you can migrate gradually without service disruption.
Next on our list is a WebAssembly target for browser-native post-quantum crypto. OpenCrypt 2.0 is available now on GitHub, with full documentation, migration guides and benchmarking tools.