1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
//! # dryoc: Don't Roll Your Own Cryptoâ„¢[^1]
//!
//! dryoc is a pure-Rust, general-purpose cryptography library. It's also an
//! implementation of [libsodium](https://libsodium.gitbook.io/doc/), and
//! designed to be 100% compatible with, and interchangeable with, libsodium's
//! API.
//!
//! Doing cryptography properly is _hard_. While no human is infallible,
//! computers are pretty good at following instructions. Humans are bad at
//! following instructions, but they do a decent job of giving instructions,
//! provided they can effectively communicate intent. Thus, if the instructions
//! humans give the computer are correct, we can be reasonably assured
//! that the operations the computer does are correct too.
//!
//! This library tries to make it easy to give the computer the correct
//! instructions, and it does so by providing well-known implementations of
//! general-purpose cryptography functions, in an API that's relatively easy to
//! use, type safe, and hard to use incorrectly.
//!
//! As the name of this library implies, one should avoid trying to "roll their
//! own crypto", as it often results in avoidable mistakes. In the context of
//! cryptography, mistakes can be very costly.
//!
//! This crate uses the Rust 2024 edition. The minimum supported Rust version
//! (MSRV) is **Rust 1.89** or newer.
//!
//! Rust 2024 reserves `gen` as a keyword. Prefer generation APIs such as
//! `Key::generate()`. Existing `gen` APIs remain available through raw
//! identifier syntax, such as `Key::r#gen()`, for compatibility and will be
//! deprecated in a future release.
//!
//! ## Features
//!
//! * 100% pure Rust, no hidden C libraries
//! * mostly free of unsafe code[^2]
//! * Hard to misuse, helping you avoid common costly cryptography mistakes
//! * Many libsodium features implemented with both Classic and Rustaceous API
//! * Protected memory handling (`mprotect()` + `mlock()`, along with Windows
//! equivalents)
//! * [Serde](https://serde.rs/) support (with `features = ["serde"]`)
//! * [wincode](https://crates.io/crates/wincode) support for direct binary
//! serialization of Rustaceous box types (with `features = ["wincode"]`)
//! * [_Portable_ SIMD](https://doc.rust-lang.org/std/simd/index.html)
//! 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)
//! * [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek)
//! (used by public/private key functions) selects its own serial or x86_64
//! vector backend at build time
//! * [SHA2](https://github.com/RustCrypto/hashes/tree/master/sha2) (used by
//! sealed boxes) includes SIMD implementation for AVX2
//! * [ChaCha20](https://github.com/RustCrypto/stream-ciphers/tree/master/chacha20)
//! (used by streaming interface) includes SIMD implementations for NEON,
//! AVX2, and SSE2
//!
//! 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.
//!
//! _Note that eventually this project will converge on portable SIMD
//! implementations for all the core algos which will work across all platforms
//! supported by LLVM, rather than relying on hand-coded assembly or intrinsics,
//! but this is a work in progress_.
//!
//! See [BENCHMARKS.md](https://github.com/brndnmtthws/dryoc/blob/main/BENCHMARKS.md)
//! for side-by-side software and SIMD benchmark results.
//!
//! ## APIs
//!
//! This library includes both a _Classic_ API, which is very similar to the
//! original libsodium API, and _Rustaceous_ API with Rust-specific features.
//! Both APIs can be used together interchangeably, according to your
//! preferences. The Rustaceous API is a wrapper around the underlying classic
//! API.
//!
//! It's recommended that you use the Rustaceous API unless you have strong
//! feelings about using the Classic API. The Classic API includes some pitfalls
//! and traps that are also present in the original libsodium API, and unless
//! you're extra careful you could make mistakes. With the Rustaceous API, it's
//! harder to make mistakes thanks to strict type and safety features.
//!
//! The Rustaceous API is, arguably, somewhat trickier to use, especially if
//! you're new to Rust. The Rustaceous API requires knowing and specifying the
//! desired type in many cases. For your convenience, type aliases are provided
//! for common types within each module. The Classic API only uses base types
//! (fixed length byte arrays and byte slices).
//!
//! | Feature | Rustaceous API | Classic API | Libsodium Docs |
//! |-|-|-|-|
//! | Public-key authenticated boxes | [`DryocBox`](dryocbox) | [`crypto_box`](classic::crypto_box) | [Link](https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption) |
//! | Secret-key authenticated boxes | [`DryocSecretBox`](dryocsecretbox) | [`crypto_secretbox`](classic::crypto_secretbox) | [Link](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox) |
//! | Streaming encryption | [`DryocStream`](dryocstream) | [`crypto_secretstream_xchacha20poly1305`](classic::crypto_secretstream_xchacha20poly1305) | [Link](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream) |
//! | Generic hashing, HMAC | [`GenericHash`](generichash) | [`crypto_generichash`](classic::crypto_generichash) | [Link](https://doc.libsodium.org/hashing/generic_hashing) |
//! | Secret-key authentication | [`Auth`](auth) | [`crypto_auth`](classic::crypto_auth) | [Link](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication) |
//! | One-time authentication | [`OnetimeAuth`](onetimeauth) | [`crypto_onetimeauth`](classic::crypto_onetimeauth) | [Link](https://doc.libsodium.org/advanced/poly1305) |
//! | Key derivation | [`Kdf`](kdf) | [`crypto_kdf`](classic::crypto_kdf) | [Link](https://doc.libsodium.org/key_derivation) |
//! | Key exchange | [`Session`](kx) | [`crypto_kx`](classic::crypto_kx) | [Link](https://doc.libsodium.org/key_exchange) |
//! | Public-key signatures | [`SigningKeyPair`](sign) | [`crypto_sign`](classic::crypto_sign) | [Link](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures) |
//! | Password hashing | [`PwHash`](pwhash) | [`crypto_pwhash`](classic::crypto_pwhash) | [Link](https://libsodium.gitbook.io/doc/password_hashing/default_phf) |
//! | Protected memory[^4] | [protected] | N/A | [Link](https://doc.libsodium.org/memory_management) |
//! | Short-input hashing | N/A | [`crypto_shorthash`](classic::crypto_shorthash) | [Link](https://libsodium.gitbook.io/doc/hashing/short-input_hashing) |
//!
//! ## Using Serde
//!
//! This crate includes optional [Serde](https://serde.rs/) support which can be
//! enabled with the `serde` feature flag. When enabled, the
//! [`Serialize`](serde::ser::Serialize) and
//! [`Deserialize`](serde::de::Deserialize) traits are provided for data
//! structures.
//!
//! ## Using wincode
//!
//! This crate includes optional [wincode](https://crates.io/crates/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`](dryocbox::DryocBox)
//! and [`DryocSecretBox`](dryocsecretbox::DryocSecretBox).
//!
//! ## 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` and `src/dryocsecretbox.rs` wincode impls | `wincode` | Implements `unsafe` wincode schema traits for the Rustaceous box wire format. 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 | `nightly` | Calls OS APIs such as `mlock`, `mprotect`, `VirtualLock`, and `VirtualProtect`, implements a page-aligned guard-page allocator, 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 word XOR in 256-byte chunks and 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
//!
//! This crate has not been audited by any 3rd parties. It uses well-known
//! implementations of the underlying algorithms which have been previously
//! verified as using constant-time operations.
//!
//! With that out of the way, the deterministic nature of cryptography and
//! extensive testing used in this crate means it's relatively safe to use,
//! provided the underlying algorithms remain safe. Arguably, this crate is
//! _incredibly_ safe (as far as cryptography libraries go) thanks to the
//! features provided by the API of this crate, and those provided by the Rust
//! language itself.
//!
//! ## Acknowledgements
//!
//! Big ups to the authors and contributors of [NaCl](https://nacl.cr.yp.to/) and [libsodium](https://github.com/jedisct1/libsodium) for paving the
//! way toward better cryptography libraries.
//!
//! [^1]: Not actually trademarked.
//!
//! [^2]: The protected memory features described in the [protected] mod 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. In
//! particular, many SIMD implementations are considered "unsafe" due to their
//! use of assembly or intrinsics, however without SIMD-based cryptography you
//! may be exposed to timing attacks. See the unsafe code section above for the
//! non-test unsafe inventory in this crate.
//!
//! [^3]: The Rustaceous API is designed to protect users of this library from
//! making mistakes, however the Classic API allows one to do as one pleases.
//!
//! [^4]: Currently only available on nightly Rust, with the `nightly` feature
//! flag enabled.
/// # Constant value definitions
/// # Random number generation utilities
/// # Base type definitions
/// # Various utility functions
pub use Error;