Skip to content

brndnmtthws/dryoc

Repository files navigation

Docs Crates.io Build & test Codecov

💬 Join the Matrix chat

dryoc: Don't Roll Your Own Crypto™1

dryoc is a pure-Rust, general-purpose cryptography library based on libsodium. Many supported operations use libsodium-compatible algorithms and wire formats, allowing dryoc and libsodium applications to interoperate.

Granny says no

The Classic API closely follows libsodium's functions and types. It is not identical to libsodium, but most implemented functions have the same or similar signatures.

The Rustaceous API wraps the same operations in Rust types that make key, nonce, and output sizes explicit. The two APIs 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.

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 the protected feature
  • Password-hash string helpers enabled by default with the base64 feature
  • 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 at build time
  • SHA2 (used for SHA-256 and SHA-512 hashing and seeded box key generation) includes an AVX2 backend
  • SHA3 (used by SHA-3 compatibility hashing)
  • ChaCha20 (used by streaming interface) includes SIMD implementations for NEON, AVX2, and SSE2

Rust version

dryoc uses the Rust 2024 edition and requires Rust 1.89 or newer, as declared by rust-version in Cargo.toml.

The simd_backend and nightly features enable dryoc's portable SIMD backends. CPU-specific dependency backends and local benchmarking may also benefit from target-specific RUSTFLAGS:

  • For AVX2 set RUSTFLAGS=-Ctarget-cpu=haswell -Ctarget-feature=+avx2
  • For SSE2 set RUSTFLAGS=-Ctarget-feature=+sse2
  • For NEON set RUSTFLAGS=-Ctarget-feature=+neon
  • For local Apple Silicon benchmarks, use RUSTFLAGS=-Ctarget-cpu=native. NEON is part of the AArch64 macOS baseline target, so adding -Ctarget-feature=+neon is not expected to change native results.

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.

Optional serialization

Enable serde to derive serde::Serialize and serde::Deserialize for supported data structures.

Enable wincode to derive wincode::SchemaWrite and wincode::SchemaRead for supported Rustaceous box types, including DryocBox and DryocSecretBox, plus AEAD boxes and envelopes from dryocaead.

Security

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.

Project status

The following features are implemented. The libsodium-compatible entries have been reviewed against libsodium 1.0.22:

The following libsodium features are either incomplete, not exposed as public APIs, or not implemented; you may find equivalent functionality in other crates:

  • AEAD constructions beyond the ChaCha20-Poly1305-IETF variants, including AEGIS-128L/256, AES256-GCM, and the legacy 64-bit-nonce ChaCha20-Poly1305 construction
  • XChaCha20-Poly1305 box and secretbox variants (crypto_box_curve25519xchacha20poly1305_*, crypto_secretbox_xchacha20poly1305_*)
  • Extendable-output functions (crypto_xof_shake*, crypto_xof_turboshake*), added in libsodium 1.0.21
  • Key encapsulation (crypto_kem_*, crypto_kem_mlkem768_*, crypto_kem_xwing_*), added in libsodium 1.0.22
  • Deterministic random data for reproducible tests (randombytes_buf_deterministic)
  • Short-input hash variants beyond SipHash-2-4 with 64-bit output (crypto_shorthash_siphashx24_*)
  • IP address encryption (crypto_ipcrypt_*, sodium_ip2bin, sodium_bin2ip), added in libsodium 1.0.21
  • Helpers, padding, and constant-time verify utilities (sodium_*, crypto_verify_*)
  • Standalone stream cipher APIs (crypto_stream_*; use the salsa20 or chacha20 crates directly instead)
  • Advanced features:
    • Keccak-f[1600] core permutation (crypto_core_keccak1600_*)
    • Scrypt (crypto_pwhash_scryptsalsa208sha256_*; use the scrypt crate directly instead)
    • Finite field and group arithmetic (crypto_core_ed25519_*, crypto_core_ristretto255_*; try the curve25519-dalek crate)
    • Ed25519 and Ristretto255 scalar multiplication variants (crypto_scalarmult_ed25519_*, crypto_scalarmult_ristretto255_*)

Other NaCl-related Rust implementations

Footnotes

  1. Not actually trademarked.

  2. The protected memory features described in the [protected] mod are available on Unix and Windows targets with the default protected feature. 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. The in-crate unsafe inventory includes fixed-size byte views, optional wincode schema impls for Rustaceous boxes and both AEAD envelope nonce sizes, BLAKE2b parameter byte views, protected memory guarded heap buffers and OS protection calls, and Salsa20 SIMD unaligned in-place and buffer-to-buffer XOR. See the rustdoc unsafe code summary for the full non-test unsafe inventory in this crate.

About

Don't Roll Your Own Crypto: pure-Rust, hard to misuse cryptography library

Topics

Resources

License

Stars

339 stars

Watchers

3 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages