Expand description
§dryoc: Don’t Roll Your Own Crypto™1
dryoc is a pure-Rust, general-purpose cryptography library. It implements many libsodium-compatible APIs and wire formats, so supported operations can interoperate with libsodium across languages.
dryoc provides a libsodium-like Classic API and a typed Rustaceous API. The Rustaceous types make key, nonce, and output sizes explicit; the Classic API eases migration from libsodium. Both APIs use the same implementations and can be used together.
This crate uses the Rust 2024 edition. The minimum supported Rust version (MSRV) is Rust 1.89 or newer.
§Features
- Pure Rust, with no hidden C libraries
- Limited use of unsafe code2
- Typed Rustaceous APIs for keys, nonces, and outputs
- Classic and Rustaceous APIs for many libsodium operations
- Protected memory handling (
mprotect()+mlock(), along with Windows equivalents) on stable Rust for Unix and Windows targets, enabled by default with theprotectedfeature - Password-hash string helpers enabled by default with the
base64feature - Serde support (with
features = ["serde"]) - wincode support for direct binary
serialization of Rustaceous box types (with
features = ["wincode"]) - Portable SIMD
implementations on nightly, with
features = ["simd_backend", "nightly"]:- Blake2b (used by generic hashing, password hashing, and key derivation)
- Argon2 block mixing (used by password hashing)
- Salsa20 (used by XSalsa20-Poly1305 secretbox)
- Poly1305 (used by one-time authentication and secret boxes), except on AArch64 where dryoc keeps the soft backend because the portable-SIMD path is slower there
- curve25519-dalek (used by public/private key functions) selects its own serial or x86_64 vector backend
- SHA2 (used for SHA-256 and SHA-512 hashing and seeded box key generation) includes an AVX2 backend
- SHA3 (used for SHA-3 hashing)
- ChaCha20 (used by streaming interface) includes SIMD implementations for NEON, AVX2, and SSE2
Dryoc’s portable SIMD backends require a nightly Rust toolchain and
--features simd_backend,nightly. simd_backend selects the SIMD code;
nightly enables Rust’s unstable portable_simd API.
The Curve25519 backend is selected by curve25519-dalek, not by dryoc’s
simd_backend feature.
Poly1305 is a special exception on AArch64: even with simd_backend and
nightly enabled, dryoc uses the soft Poly1305 backend because profiling
shows the portable-SIMD implementation is slower on that architecture.
See BENCHMARKS.md for side-by-side software and SIMD benchmark results.
§APIs
The Classic API closely follows libsodium’s functions and types. The Rustaceous API wraps the same operations in Rust types.
§Error handling
Fallible cryptographic operations return Error. Its structured variants
let callers distinguish authentication failures, invalid lengths or values,
malformed encodings, invalid keys, protected-memory failures, and invalid
operation state.
Prefer the Rustaceous API for new code. Use the Classic API when porting libsodium code or when its byte-array interface is a better fit.
Rustaceous functions sometimes require an explicit output type. Each module provides type aliases for its common key, nonce, and output types. The Classic API instead uses fixed-size byte arrays and byte slices.
§Using Serde
This crate includes optional Serde support which can be
enabled with the serde feature flag. When enabled, the
Serialize and
Deserialize traits are provided
for data structures.
§Using wincode
This crate includes optional wincode
support which can be enabled with the wincode feature flag. When enabled,
wincode::SchemaWrite and
wincode::SchemaRead are
provided for supported Rustaceous box types, including
DryocBox,
DryocSecretBox, and
AeadBox.
§Unsafe code
Non-test unsafe code is limited to these areas:
| Area | Feature gate | Why unsafe is required |
|---|---|---|
src/types.rs fixed-size byte views | Always available | Converts validated byte slices and vectors into [u8; N] references without copying. Each cast is guarded by a length check or an exact-size wrapper invariant. |
src/dryocbox.rs, src/dryocsecretbox.rs, and src/dryocaead.rs wincode impls | wincode | Implements unsafe wincode schema traits for the Rustaceous box wire formats, including both AEAD nonce sizes. The implementations write and read initialized fields in the same order. |
src/blake2b/blake2b_soft.rs and src/blake2b/blake2b_simd.rs parameter blocks | Always available for the soft backend; simd_backend,nightly for SIMD | Views a repr(C, packed) BLAKE2b parameter block as bytes so the initialization vector is mixed exactly as specified. The parameter type contains only initialized byte fields. |
src/protected.rs protected memory | protected on Unix/Windows | Calls OS APIs such as mlock, mprotect, VirtualLock, and VirtualProtect, implements page-aligned guarded heap buffers, and exposes exact-size byte-array views over protected heap buffers. |
src/classic/salsa20_simd.rs Salsa20 SIMD backend | simd_backend,nightly | Performs little-endian unaligned in-place and buffer-to-buffer word XOR in 256-byte chunks, plus volatile zeroization of cached SIMD lanes containing derived key material. |
Test-only unsafe code is used for libsodium and Argon2 compatibility checks and protected-memory platform probes; it is not part of the runtime crate API.
§Security notes
dryoc has not undergone a third-party security audit. Its compatibility tests, Rust types, and limited use of unsafe code reduce some classes of defects, but do not guarantee that an application is secure. Applications must still follow the documented key and nonce rules, protect secret material, handle errors, and choose primitives appropriate for their protocol.
§Acknowledgements
Thanks to the authors and contributors of NaCl and libsodium.
Not actually trademarked. ↩
The protected memory features described in the protected mod are available on Unix and Windows targets with the default
protectedfeature. Unsupported targets do not expose the protected-memory API. These features require custom memory allocation, system calls, and pointer arithmetic, which are unsafe in Rust. Some optional SIMD code, including dependency-provided SIMD implementations and small internal helpers, may contain unsafe code. See the unsafe code section above for the non-test unsafe inventory in this crate. ↩Available on Unix and Windows targets with the
protectedfeature flag enabled. Theprotectedfeature is enabled by default. ↩
Modules§
- auth
- Secret-key message authentication
- classic
- Classic API
- constants
- Constant value definitions
- dryocaead
- Authenticated encryption with additional data
- dryocbox
- Public-key authenticated encryption
- dryocsecretbox
- Secret-key authenticated encryption
- dryocstream
- Encrypted streams
- generichash
- Generic hashing
- hkdf
- HKDF key derivation
- hmac
- HMAC authentication
- kdf
- Key derivation functions
- keypair
- Public/secret keypair tools
- kx
- Key exchange functions
- onetimeauth
- One-time authentication
- precalc
- Precalculated secret key for use with
precalc_*functions incrate::dryocbox::DryocBox - protected
protected - Memory protection utilities
- pwhash
- Password hashing functions
- rng
- Random number generation utilities
- sha3
- SHA-3 hash algorithms
- sha256
- SHA-256 hash algorithm
- sha512
- SHA-512 hash algorithm
- sign
- Public-key signatures
- types
- Base type definitions
- utils
- Various utility functions
Enums§
- Error
- Errors generated by Dryoc.
- Error
Context - The input, output, or operation associated with an
Error. - Length
Constraint - A constraint on a byte or buffer length.
- Value
Constraint - A constraint on a numeric parameter.