Skip to main content

dryoc/
lib.rs

1//! # dryoc: Don't Roll Your Own Cryptoâ„¢[^1]
2//!
3//! **dryoc** is a high-performance, pure-Rust cryptography library. It provides
4//! both a type-safe Rustaceous API and a Classic compatibility surface
5//! interoperative with libsodium wire formats.
6//!
7//! ## Highlights
8//!
9//! * **High Performance:** Native SIMD and assembly kernels (AVX-512, AVX2,
10//!   NEON, SVE2) with automatic runtime CPU detection.
11//! * **Post-Quantum Cryptography:** ML-KEM-768 (FIPS 203), X-Wing hybrid
12//!   (ML-KEM
13//!   + X25519), and RFC 9180 HPKE sealed boxes.
14//! * **Type-Safe Rustaceous API:** Strongly-typed fixed-size keys, nonces, and
15//!   containers prevent length and type misuse at compile time.
16//! * **Classic Compatibility:** Drop-in libsodium-compatible functions
17//!   (`crypto_*`) and wire formats.
18//! * **Hardened Memory:** Protected memory allocations (page-aligned, locked,
19//!   guard pages) on Unix and Windows, plus automatic secret zeroization via
20//!   [`zeroize`](https://crates.io/crates/zeroize).
21//! * **Flexible & `#![no_std]`:** Fully functional without `std` or `alloc`
22//!   using fixed-size stack arrays; opt-in `alloc`, `serde`, and `wincode`
23//!   support.
24//!
25//! Requires Rust 1.89 or newer (Rust 2024 edition).
26//!
27//! ## APIs
28//!
29//! `dryoc` provides two complementary API surfaces built on the same underlying
30//! cryptographic kernels:
31//!
32//! * **Rustaceous API (Recommended):** Uses strongly-typed, fixed-size array
33//!   wrappers (e.g., [`Key`](dryocsecretbox::Key),
34//!   [`Nonce`](dryocsecretbox::Nonce),
35//!   [`DryocSecretBox`](dryocsecretbox::DryocSecretBox)). Ensures correct key
36//!   and nonce sizes at compile time and provides convenient helper methods.
37//! * **Classic API:** Low-level byte-slice and array functions matching
38//!   libsodium standard signatures (`crypto_box_*`, `crypto_secretbox_*`,
39//!   etc.).
40//!
41//! ### Rustaceous Quick Start
42//!
43//! ```
44//! # #[cfg(feature = "alloc")]
45//! # {
46//! use dryoc::dryocsecretbox::*;
47//! use dryoc::types::*;
48//!
49//! let key = Key::generate();
50//! let nonce = Nonce::generate();
51//! let message = b"Hello, post-quantum world!";
52//!
53//! let box_ = DryocSecretBox::encrypt_to_vecbox(message, &nonce, &key).expect("encryption failed");
54//! let decrypted = box_
55//!     .decrypt_to_vec(&nonce, &key)
56//!     .expect("authentication failed");
57//! assert_eq!(message, &decrypted[..]);
58//! # }
59//! ```
60//!
61//! ## Feature & API Overview
62//!
63//! | Primitive / Operation | Rustaceous API | Classic API |
64//! |-|-|-|
65//! | Public-key authenticated boxes | [`DryocBox`](dryocbox) | [`crypto_box`](classic::crypto_box) |
66//! | Secret-key authenticated boxes | [`DryocSecretBox`](dryocsecretbox) | [`crypto_secretbox`](classic::crypto_secretbox) |
67//! | Post-quantum key encapsulation | [`kem`], [`kem::mlkem768`] | [`crypto_kem`](classic::crypto_kem) |
68//! | Post-quantum sealed boxes (HPKE) | [`DryocSealedBox`](dryocsealedbox) | N/A |
69//! | AEAD (ChaCha20-Poly1305-IETF / XChaCha20) | [`DryocAead`](dryocaead) | [`crypto_aead_xchacha20poly1305_ietf`](classic::crypto_aead_xchacha20poly1305_ietf) |
70//! | Streaming encryption | [`DryocStream`](dryocstream) | [`crypto_secretstream_xchacha20poly1305`](classic::crypto_secretstream_xchacha20poly1305) |
71//! | Generic hashing (BLAKE2b) | [`GenericHash`](generichash) | [`crypto_generichash`](classic::crypto_generichash) |
72//! | SHA-2 & SHA-3 hashing | [`Sha256`](sha256::Sha256), [`Sha3256`](sha3::Sha3256) | [`crypto_hash`](classic::crypto_hash) |
73//! | XOF (SHAKE128/256, TurboSHAKE) | [`Shake128`](xof::Shake128) | [`crypto_xof`](classic::crypto_xof) |
74//! | Secret-key & HMAC authentication | [`Auth`](auth), [`Hmac`](hmac) | [`crypto_auth`](classic::crypto_auth) |
75//! | Key derivation (KDF & HKDF) | [`Kdf`](kdf), [`Hkdf`](hkdf) | [`crypto_kdf`](classic::crypto_kdf) |
76//! | Key exchange | [`Session`](kx) | [`crypto_kx`](classic::crypto_kx) |
77//! | Public-key signatures (Ed25519) | [`SigningKeyPair`](sign) | [`crypto_sign`](classic::crypto_sign) |
78//! | Password hashing (Argon2id) | [`PwHash`](pwhash) | [`crypto_pwhash`](classic::crypto_pwhash) |
79//! | Protected memory | [`protected`] | N/A |
80//!
81//! ## Cargo Features
82//!
83//! | Feature | Default | Description |
84//! |-|-|-|
85//! | `std` | Yes | Enables `alloc`, runtime CPU detection, and `Error::Io`. |
86//! | `alloc` | With `std` | Heap-allocating APIs (`Vec<u8>` conversions, `VecBox` types, `pwhash`). |
87//! | `protected` | Yes | Page-aligned, locked memory allocations on Unix/Windows. |
88//! | `base64` | Yes | Password-hash string formatting helpers. |
89//! | `serde` | Yes | Serde serialization support for keys, nonces, and containers. |
90//! | `wincode_0_6` | No | Direct binary serialization via `wincode 0.6`. |
91//! | `simd_backend` | No | Portable SIMD implementation (requires `nightly`). |
92//! | `nightly` | No | Nightly compiler features (`portable_simd`, `Allocator` impls). |
93//!
94//! ## Security Notes
95//!
96//! `dryoc` has not undergone a third-party security audit. Defect surface is
97//! minimized through type safety, comprehensive compatibility test suites, and
98//! minimal `unsafe` usage confined to SIMD/assembly kernels and protected
99//! memory. See [`unsafe_code`] for the full unsafe code inventory.
100//!
101//! [^1]: Not actually trademarked.
102#![no_std]
103#![cfg_attr(feature = "nightly", feature(doc_cfg))]
104#![cfg_attr(
105    all(feature = "simd_backend", feature = "nightly"),
106    feature(portable_simd)
107)]
108#![cfg_attr(all(test, feature = "nightly"), feature(test))]
109
110#[cfg(any(feature = "alloc", test))]
111#[macro_use]
112extern crate alloc;
113#[cfg(any(feature = "std", test))]
114extern crate std;
115
116/// Whether an x86-64 CPU feature is available: detected at runtime with the
117/// `std` feature, and taken from the compile-time target features (for
118/// example `-C target-feature=+avx2`) without it. A `true` result therefore
119/// always means the running CPU supports the feature.
120#[cfg(target_arch = "x86_64")]
121macro_rules! has_x86_feature {
122    ($feature:tt) => {{
123        #[cfg(feature = "std")]
124        let detected = std::arch::is_x86_feature_detected!($feature);
125        #[cfg(not(feature = "std"))]
126        let detected = cfg!(target_feature = $feature);
127        detected
128    }};
129}
130
131/// Whether an AArch64 CPU feature is available, detected the same way as
132/// `has_x86_feature!`.
133#[cfg(target_arch = "aarch64")]
134macro_rules! has_aarch64_feature {
135    ($feature:tt) => {{
136        #[cfg(feature = "std")]
137        let detected = std::arch::is_aarch64_feature_detected!($feature);
138        #[cfg(not(feature = "std"))]
139        let detected = cfg!(target_feature = $feature);
140        detected
141    }};
142}
143
144#[macro_use]
145mod error;
146#[cfg(feature = "wincode_0_6")]
147#[macro_use]
148mod wincode_schema;
149
150/// The `alloc` prelude items that the standard prelude would provide, for
151/// unit tests in this `no_std` crate.
152#[cfg(test)]
153mod test_prelude {
154    pub(crate) use alloc::string::{String, ToString};
155    pub(crate) use alloc::vec::Vec;
156}
157#[cfg(any(
158    all(feature = "protected", any(unix, windows)),
159    all(doc, not(doctest), feature = "std")
160))]
161#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "protected")))]
162#[macro_use]
163pub mod protected;
164
165#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
166mod aarch64;
167#[cfg(feature = "alloc")]
168mod argon2;
169mod blake2b;
170#[cfg(feature = "serde")]
171mod bytes_serde;
172mod chacha20;
173mod edwards25519;
174mod fe25519;
175mod keccak;
176mod mlkem;
177#[cfg(all(test, dryoc_native_tests))]
178mod native_test_util;
179#[cfg(all(target_arch = "aarch64", target_endian = "little", not(miri)))]
180mod neon;
181mod poly1305;
182mod salsa20;
183mod scalarmult_curve25519;
184mod sha2_impl;
185mod siphash24;
186mod stream;
187#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
188mod wasm32;
189#[cfg(target_arch = "x86_64")]
190mod x86_64;
191
192pub mod classic {
193    //! # Classic API
194    //!
195    //! The Classic API follows libsodium's interface closely. Use it to port
196    //! libsodium code or when fixed-size byte arrays and byte slices are a
197    //! better fit than the Rustaceous types.
198    mod crypto_aead_chacha20poly1305_impl;
199    pub(crate) mod crypto_auth_hmac_impl;
200    mod crypto_box_impl;
201    mod crypto_secretbox_impl;
202    mod generichash_blake2b;
203
204    pub mod crypto_aead_chacha20poly1305_ietf;
205    pub mod crypto_aead_xchacha20poly1305_ietf;
206    pub mod crypto_auth;
207    pub mod crypto_auth_hmacsha256;
208    pub mod crypto_auth_hmacsha512;
209    pub mod crypto_auth_hmacsha512256;
210    pub mod crypto_box;
211    /// # Core cryptography functions
212    pub mod crypto_core;
213    pub mod crypto_generichash;
214    /// Hash functions
215    pub mod crypto_hash;
216    pub mod crypto_kdf;
217    pub mod crypto_kem;
218    pub mod crypto_kem_mlkem768;
219    pub mod crypto_kem_xwing;
220    pub mod crypto_kx;
221    pub mod crypto_onetimeauth;
222    #[cfg(feature = "alloc")]
223    #[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "alloc")))]
224    pub mod crypto_pwhash;
225    pub mod crypto_secretbox;
226    pub mod crypto_secretstream_xchacha20poly1305;
227    pub mod crypto_shorthash;
228    pub mod crypto_sign;
229    pub mod crypto_sign_ed25519;
230    pub mod crypto_xof;
231}
232
233pub mod auth;
234/// # Constant value definitions
235pub mod constants;
236pub mod dryocaead;
237pub mod dryocbox;
238pub mod dryocsealedbox;
239pub mod dryocsecretbox;
240pub mod dryocstream;
241pub mod generichash;
242pub mod hkdf;
243pub mod hmac;
244pub mod kdf;
245pub mod kem;
246pub mod keypair;
247pub mod kx;
248pub mod onetimeauth;
249pub mod precalc;
250#[cfg(feature = "alloc")]
251#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "alloc")))]
252pub mod pwhash;
253/// # Random number generation utilities
254pub mod rng;
255pub mod sha256;
256pub mod sha3;
257pub mod sha512;
258pub mod sign;
259/// # Base type definitions
260pub mod types;
261pub mod unsafe_code;
262/// # Various utility functions
263pub mod utils;
264pub mod xof;
265
266pub use error::{Error, ErrorContext, LengthConstraint, ValueConstraint};