Don't Roll Your Own Crypto: pure-Rust, hard to misuse cryptography library
See the codedryoc is a general-purpose cryptography library written in pure Rust. It implements many of the same algorithms and wire formats as libsodium, so supported operations can interoperate with libsodium.

The Classic API closely follows libsodium's functions and types, which makes it useful when porting existing code. The Rustaceous API provides typed Rust interfaces that make key, nonce, and output sizes explicit. Both APIs use the same implementations and can be used together.
dryoc does not implement every libsodium feature. See Project status for current coverage.
See the API documentation and integration tests for examples.
wasm32-unknown-unknown targetprotected featurebase64 featurefeatures = ["simd_backend", "nightly"]On the optimized workloads shown below, dryoc is faster than libsodium 1.0.18
on both x86-64 and AArch64. Each result compares the two libraries in the same
process, using the same buffers, one thread, and -Ctarget-cpu=native:
| Workload | Intel Xeon 6975P-C (AVX-512) | Arm Neoverse V3 (NEON/SVE2) |
|---|---|---|
| Poly1305, 1 MiB | 5.85x faster | 3.28x faster |
| Poly1305, 16 KiB | 5.59x faster | 3.14x faster |
| XSalsa20-Poly1305 secretbox, 1 MiB | 3.07x faster | 2.84x faster |
| XSalsa20-Poly1305 secretbox, 1 KiB | 3.16x faster | 2.04x faster |
| BLAKE2b, 694,200 B | 1.19x faster | 1.43x faster |
These results do not require -Ctarget-cpu=native: the optimized Poly1305
and Salsa20 implementations, and the x86-64 BLAKE2b implementation, are
selected automatically at runtime, while the AArch64 BLAKE2b rounds use only
baseline instructions. Omitting the flag changes the results above by no more
than 6%. Argon2id results vary more with the machine and build flags. See
BENCHMARKS.md for the full results, test environment, builds
without CPU-specific flags, and workloads where libsodium is as fast or faster.
dryoc uses the Rust 2024 edition and requires Rust 1.89 or newer, as declared
by rust-version in Cargo.toml.
The optional portable SIMD implementations require nightly Rust and
--features simd_backend,nightly. The simd_backend feature selects those
implementations, while nightly enables Rust's unstable portable_simd API.
Optimized AArch64 and x86-64 implementations are built in and do not require
the simd_backend feature. Implementations that need optional CPU extensions,
such as NEON, SVE2, the SHA-2 and SHA-3 instructions, AVX2, AVX-512, and BMI2,
are selected at runtime when the CPU supports them. The AArch64 asm!
implementations of the BLAKE2b rounds, the scalar ChaCha20 rounds, and
Curve25519 field multiplication use only baseline instructions and are always
used on that architecture. Curve25519 and Ed25519 group operations are also
unaffected by the simd_backend feature.
Enable serde to derive serde::Serialize
and serde::Deserialize
for supported data structures.
Enable wincode to implement wincode::SchemaWrite
and wincode::SchemaRead
for the VecBox aliases in dryocbox and dryocsecretbox, and for the
VecBox and VecEnvelope aliases in dryocaead.
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.
The following features are implemented. Entries that mirror libsodium have been checked against libsodium 1.0.22:
crypto_box_*) libsodium linkcrypto_secretbox_*) libsodium linkcrypto_scalarmult*) libsodium linksodium_memzero) with zeroize libsodium linkrandombytes_buf) libsodium linkcrypto_secretstream_*) libsodium linkcrypto_aead_xchacha20poly1305_ietf_*) libsodium linkcrypto_aead_chacha20poly1305_ietf_*) libsodium linksodium_mlock, sodium_munlock, sodium_mprotect_*) libsodium linksodium_increment) libsodium linkcrypto_generichash_*) libsodium linkcrypto_auth*) libsodium linkcrypto_onetimeauth_*) libsodium linkcrypto_box_seal*) libsodium linkcrypto_kdf_*) libsodium linkcrypto_kx_*) libsodium linkcrypto_sign_*) libsodium linkcrypto_sign_ed25519_*) libsodium linkcrypto_sign_ed25519_sk_to_seed, crypto_sign_ed25519_sk_to_pk) libsodium linkcrypto_hash_sha256_*, crypto_hash_sha512_*) libsodium linkcrypto_hash_sha3256_*, crypto_hash_sha3512_*; dryoc extension) NIST FIPS 202 linkcrypto_shorthash) libsodium linkcrypto_pwhash_*) libsodium linkcrypto_kdf_hkdf_sha256_*, crypto_kdf_hkdf_sha512_*) libsodium linkcrypto_auth_hmacsha256_*, crypto_auth_hmacsha512_*, crypto_auth_hmacsha512256_*) libsodium linkThe following libsodium features are incomplete, internal only, or not implemented. Other crates may provide equivalent functionality:
crypto_box_curve25519xchacha20poly1305_*, crypto_secretbox_xchacha20poly1305_*)crypto_xof_shake*, crypto_xof_turboshake*), added in libsodium 1.0.21crypto_kem_*, crypto_kem_mlkem768_*, crypto_kem_xwing_*), added in libsodium 1.0.22randombytes_buf_deterministic)crypto_shorthash_siphashx24_*)crypto_ipcrypt_*, sodium_ip2bin, sodium_bin2ip), added in libsodium 1.0.21sodium_*, crypto_verify_*)crypto_stream_*; use the salsa20 or chacha20 crates directly instead)crypto_core_keccak1600_*)crypto_pwhash_scryptsalsa208sha256_*; use the scrypt crate directly instead)crypto_core_ed25519_*, crypto_core_ristretto255_*; try the curve25519-dalek crate)crypto_scalarmult_ed25519_*, crypto_scalarmult_ristretto255_*)Not actually trademarked. ↩
Protected memory is available on Unix and Windows with the default
protected feature. It requires custom allocation, system calls, and pointer
arithmetic, which are unsafe in Rust. Some optimized implementations also use
small, carefully bounded unsafe blocks. The in-crate unsafe inventory includes
fixed-size byte views, wincode schema implementations for vector-backed boxes
and AEAD envelopes, BLAKE2b
parameter byte views, protected memory guarded heap buffers and OS protection
calls, 16-byte volatile zeroization of secret buffers, the x86-64 backends
(runtime-detected AVX2, AVX-512 and AVX-512 IFMA entry points for ChaCha20,
XSalsa20, Poly1305, the Argon2 block compression and the BLAKE2b compression,
asm! scalar ChaCha20 and Salsa20 double rounds that run beside the AVX-512
lane sets, an AVX-512
Ed25519 basepoint table lookup, and BMI2-compiled copies of the Curve25519
scalar multiplication, inversion and square-root loops), and the AArch64
backends: runtime-detected NEON entry points for Poly1305, XSalsa20, ChaCha20,
and the Ed25519 basepoint table lookup, register-only SVE2 asm! blocks for
the ChaCha20 and XSalsa20 rounds, scalar asm! blocks for the ChaCha20 and
BLAKE2b rounds and the Curve25519 field products, and runtime-detected
sha2/sha3 instruction asm! loops for the SHA-256 and SHA-512
compression functions.
The rustdoc unsafe code summary
lists every non-test use of unsafe code in this crate. ↩
Rust
99.8%
Don't Roll Your Own Crypto: pure-Rust, hard to misuse cryptography library
See the codedryoc is a general-purpose cryptography library written in pure Rust. It implements many of the same algorithms and wire formats as libsodium, so supported operations can interoperate with libsodium.

The Classic API closely follows libsodium's functions and types, which makes it useful when porting existing code. The Rustaceous API provides typed Rust interfaces that make key, nonce, and output sizes explicit. Both APIs use the same implementations and can be used together.
dryoc does not implement every libsodium feature. See Project status for current coverage.
See the API documentation and integration tests for examples.
wasm32-unknown-unknown targetprotected featurebase64 featurefeatures = ["simd_backend", "nightly"]On the optimized workloads shown below, dryoc is faster than libsodium 1.0.18
on both x86-64 and AArch64. Each result compares the two libraries in the same
process, using the same buffers, one thread, and -Ctarget-cpu=native:
| Workload | Intel Xeon 6975P-C (AVX-512) | Arm Neoverse V3 (NEON/SVE2) |
|---|---|---|
| Poly1305, 1 MiB | 5.85x faster | 3.28x faster |
| Poly1305, 16 KiB | 5.59x faster | 3.14x faster |
| XSalsa20-Poly1305 secretbox, 1 MiB | 3.07x faster | 2.84x faster |
| XSalsa20-Poly1305 secretbox, 1 KiB | 3.16x faster | 2.04x faster |
| BLAKE2b, 694,200 B | 1.19x faster | 1.43x faster |
These results do not require -Ctarget-cpu=native: the optimized Poly1305
and Salsa20 implementations, and the x86-64 BLAKE2b implementation, are
selected automatically at runtime, while the AArch64 BLAKE2b rounds use only
baseline instructions. Omitting the flag changes the results above by no more
than 6%. Argon2id results vary more with the machine and build flags. See
BENCHMARKS.md for the full results, test environment, builds
without CPU-specific flags, and workloads where libsodium is as fast or faster.
dryoc uses the Rust 2024 edition and requires Rust 1.89 or newer, as declared
by rust-version in Cargo.toml.
The optional portable SIMD implementations require nightly Rust and
--features simd_backend,nightly. The simd_backend feature selects those
implementations, while nightly enables Rust's unstable portable_simd API.
Optimized AArch64 and x86-64 implementations are built in and do not require
the simd_backend feature. Implementations that need optional CPU extensions,
such as NEON, SVE2, the SHA-2 and SHA-3 instructions, AVX2, AVX-512, and BMI2,
are selected at runtime when the CPU supports them. The AArch64 asm!
implementations of the BLAKE2b rounds, the scalar ChaCha20 rounds, and
Curve25519 field multiplication use only baseline instructions and are always
used on that architecture. Curve25519 and Ed25519 group operations are also
unaffected by the simd_backend feature.
Enable serde to derive serde::Serialize
and serde::Deserialize
for supported data structures.
Enable wincode to implement wincode::SchemaWrite
and wincode::SchemaRead
for the VecBox aliases in dryocbox and dryocsecretbox, and for the
VecBox and VecEnvelope aliases in dryocaead.
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.
The following features are implemented. Entries that mirror libsodium have been checked against libsodium 1.0.22:
crypto_box_*) libsodium linkcrypto_secretbox_*) libsodium linkcrypto_scalarmult*) libsodium linksodium_memzero) with zeroize libsodium linkrandombytes_buf) libsodium linkcrypto_secretstream_*) libsodium linkcrypto_aead_xchacha20poly1305_ietf_*) libsodium linkcrypto_aead_chacha20poly1305_ietf_*) libsodium linksodium_mlock, sodium_munlock, sodium_mprotect_*) libsodium linksodium_increment) libsodium linkcrypto_generichash_*) libsodium linkcrypto_auth*) libsodium linkcrypto_onetimeauth_*) libsodium linkcrypto_box_seal*) libsodium linkcrypto_kdf_*) libsodium linkcrypto_kx_*) libsodium linkcrypto_sign_*) libsodium linkcrypto_sign_ed25519_*) libsodium linkcrypto_sign_ed25519_sk_to_seed, crypto_sign_ed25519_sk_to_pk) libsodium linkcrypto_hash_sha256_*, crypto_hash_sha512_*) libsodium linkcrypto_hash_sha3256_*, crypto_hash_sha3512_*; dryoc extension) NIST FIPS 202 linkcrypto_shorthash) libsodium linkcrypto_pwhash_*) libsodium linkcrypto_kdf_hkdf_sha256_*, crypto_kdf_hkdf_sha512_*) libsodium linkcrypto_auth_hmacsha256_*, crypto_auth_hmacsha512_*, crypto_auth_hmacsha512256_*) libsodium linkThe following libsodium features are incomplete, internal only, or not implemented. Other crates may provide equivalent functionality:
crypto_box_curve25519xchacha20poly1305_*, crypto_secretbox_xchacha20poly1305_*)crypto_xof_shake*, crypto_xof_turboshake*), added in libsodium 1.0.21crypto_kem_*, crypto_kem_mlkem768_*, crypto_kem_xwing_*), added in libsodium 1.0.22randombytes_buf_deterministic)crypto_shorthash_siphashx24_*)crypto_ipcrypt_*, sodium_ip2bin, sodium_bin2ip), added in libsodium 1.0.21sodium_*, crypto_verify_*)crypto_stream_*; use the salsa20 or chacha20 crates directly instead)crypto_core_keccak1600_*)crypto_pwhash_scryptsalsa208sha256_*; use the scrypt crate directly instead)crypto_core_ed25519_*, crypto_core_ristretto255_*; try the curve25519-dalek crate)crypto_scalarmult_ed25519_*, crypto_scalarmult_ristretto255_*)Not actually trademarked. ↩
Protected memory is available on Unix and Windows with the default
protected feature. It requires custom allocation, system calls, and pointer
arithmetic, which are unsafe in Rust. Some optimized implementations also use
small, carefully bounded unsafe blocks. The in-crate unsafe inventory includes
fixed-size byte views, wincode schema implementations for vector-backed boxes
and AEAD envelopes, BLAKE2b
parameter byte views, protected memory guarded heap buffers and OS protection
calls, 16-byte volatile zeroization of secret buffers, the x86-64 backends
(runtime-detected AVX2, AVX-512 and AVX-512 IFMA entry points for ChaCha20,
XSalsa20, Poly1305, the Argon2 block compression and the BLAKE2b compression,
asm! scalar ChaCha20 and Salsa20 double rounds that run beside the AVX-512
lane sets, an AVX-512
Ed25519 basepoint table lookup, and BMI2-compiled copies of the Curve25519
scalar multiplication, inversion and square-root loops), and the AArch64
backends: runtime-detected NEON entry points for Poly1305, XSalsa20, ChaCha20,
and the Ed25519 basepoint table lookup, register-only SVE2 asm! blocks for
the ChaCha20 and XSalsa20 rounds, scalar asm! blocks for the ChaCha20 and
BLAKE2b rounds and the Curve25519 field products, and runtime-detected
sha2/sha3 instruction asm! loops for the SHA-256 and SHA-512
compression functions.
The rustdoc unsafe code summary
lists every non-test use of unsafe code in this crate. ↩
Rust
99.8%