dryoc: Don't Roll Your Own Crypto™1
dryoc is a pure-Rust cryptography library. It is faster than libsodium on common workloads (up to 4x, see benchmarks), with post-quantum cryptography (ML-KEM-768, X-Wing hybrid, HPKE), protected memory, and #![no_std] support.
- Fast: Pure Rust kernels with runtime CPU feature detection (AVX-512, AVX2, NEON, SVE2) that outperform libsodium's C implementations on common workloads.
- Post-quantum ready: ML-KEM-768 key encapsulation, X-Wing hybrid (ML-KEM + X25519), and RFC 9180 HPKE sealed boxes.
- Type-safe API: Fixed-size Rust types for keys, nonces, and ciphertexts that catch length and type errors at compile time.
- Libsodium compatible:
crypto_*API matching libsodium wire formats and functions for integration or migration (see compatibility notes). - Hardened and flexible: Protected memory on Unix and Windows, memory zeroization,
#![no_std]/allocsupport, and Serde implementations. - Python and Wasm support: Python 3.11+ bindings (
pip install dryoc, including free-threaded CPython support) and WebAssembly (wasm32-unknown-unknown) with optional SIMD.
Add dryoc to your Cargo.toml:
[dependencies]
dryoc = "2"Upgrading from dryoc 1.x? See UPGRADING.md.
use dryoc::dryocsecretbox::*;
use dryoc::types::*;
// Generate a random key and nonce using type-safe fixed-size arrays
let key = Key::generate();
let nonce = Nonce::generate();
let message = b"Hello, post-quantum world!";
// Encrypt and authenticate in one step
let box_ = DryocSecretBox::encrypt_to_vecbox(message, &nonce, &key).expect("encryption failed");
let decrypted = box_.decrypt_to_vec(&nonce, &key).expect("authentication failed");
assert_eq!(message, &decrypted[..]);Measured in single-threaded benchmark runs (-Ctarget-cpu=native, same process and buffers) comparing dryoc against libsodium 1.0.22:
| Workload | Intel Xeon 6975P-C (AVX-512) | Arm Neoverse V3 (NEON/SVE2) |
|---|---|---|
| Poly1305 (1 MiB) | 4.29x faster | 3.61x faster |
| XSalsa20-Poly1305 (1 MiB) | 2.71x faster | 4.00x faster |
| XSalsa20-Poly1305 (1 KiB) | 3.27x faster | 2.60x faster |
| BLAKE2b (694 KiB) | 1.17x faster | 1.42x faster |
No special compiler flags required: CPU extensions (AVX-512, AVX2, NEON, SVE2, SHA-2/SHA-3) are detected at runtime with std. Post-quantum operations (ML-KEM-768, X-Wing) achieve 1.5x–3.8x performance gains over reference C code. Detailed benchmarks and methodology are available in BENCHMARKS.md.
dryoc goes beyond classic NaCl/libsodium algorithms with these additional primitives:
- ML-KEM-768 and X-Wing hybrid: NIST FIPS 203 post-quantum key encapsulation mechanism and the X-Wing post-quantum hybrid scheme (ML-KEM-768 + X25519).
- HPKE sealed boxes: RFC 9180 Hybrid Public Key Encryption using X-Wing, HKDF-SHA256, and ChaCha20-Poly1305.
- SHA-3 and XOF: SHA3-256/512 and SHAKE/TurboSHAKE extendable-output functions based on Keccak.
| Feature | Default | Description |
|---|---|---|
std |
Yes | Enables alloc, runtime CPU feature detection, and Error::Io. |
alloc |
With std |
Heap-allocating APIs (Vec<u8> conversions, VecBox types, pwhash). |
protected |
Yes | Guarded, page-aligned protected memory on Unix and Windows (implies std). |
serde |
Yes | Serialize / Deserialize implementations for keys, nonces, and ciphertexts. |
base64 |
Yes | Password hashing string helpers (implies alloc). |
wincode_0_6 |
No | Direct binary serialization via wincode 0.6 for box types (implies alloc). |
simd_backend |
No | Opt-in portable SIMD implementations (requires nightly). |
nightly |
No | Nightly toolchain support for portable_simd and Allocator impls. |
dryoc is #![no_std] compatible out of the box. Fixed-size arrays and stack-allocated types work without heap allocation or std:
dryoc = { version = "2", default-features = false }Enable features = ["alloc"] on embedded/custom targets with a heap allocator.
- x86_64 & AArch64: SIMD and assembly kernels with automatic runtime CPU dispatch.
- WebAssembly (
wasm32-unknown-unknown): Supported out of the box. Compile withRUSTFLAGS=-Ctarget-feature=+simd128to enable WebAssembly SIMD kernels. - Python bindings: Available on PyPI via
pip install dryoc(see python/README.md).
dryoc minimizes unsafe code, confining it to OS protected memory calls, zeroization, and vectorized SIMD/assembly kernels. Full details are documented in the unsafe code inventory.
Licensed under the MIT License. Inspired by and compatible with libsodium and NaCl.
Footnotes
-
Not actually trademarked. ↩
