dryoc/lib.rs
1//! # dryoc: Don't Roll Your Own Cryptoâ„¢[^1]
2//!
3//! dryoc is a pure-Rust, general-purpose cryptography library. It's also an
4//! implementation of [libsodium](https://libsodium.gitbook.io/doc/), and
5//! designed to be 100% compatible with, and interchangeable with, libsodium's
6//! API.
7//!
8//! Doing cryptography properly is _hard_. While no human is infallible,
9//! computers are pretty good at following instructions. Humans are bad at
10//! following instructions, but they do a decent job of giving instructions,
11//! provided they can effectively communicate intent. Thus, if the instructions
12//! humans give the computer are correct, we can be reasonably assured
13//! that the operations the computer does are correct too.
14//!
15//! This library tries to make it easy to give the computer the correct
16//! instructions, and it does so by providing well-known implementations of
17//! general-purpose cryptography functions, in an API that's relatively easy to
18//! use, type safe, and hard to use incorrectly.
19//!
20//! As the name of this library implies, one should avoid trying to "roll their
21//! own crypto", as it often results in avoidable mistakes. In the context of
22//! cryptography, mistakes can be very costly.
23//!
24//! The minimum supported Rust version (MSRV) for this crate is **Rust 1.51** or
25//! newer.
26//!
27//! ## Features
28//!
29//! * 100% pure Rust, no hidden C libraries
30//! * mostly free of unsafe code[^2]
31//! * Hard to misuse, helping you avoid common costly cryptography mistakes
32//! * Many libsodium features implemented with both Classic and Rustaceous API
33//! * Protected memory handling (`mprotect()` + `mlock()`, along with Windows
34//! equivalents)
35//! * [Serde](https://serde.rs/) support (with `features = ["serde"]`)
36//! * [_Portable_ SIMD](https://doc.rust-lang.org/std/simd/index.html)
37//! implementation for Blake2b (used by generic hashing, password hashing, and
38//! key derivation) on nightly, with `features = ["simd_backend", "nightly"]`
39//! * SIMD backend for Curve25519 (used by public/private key functions) on
40//! nightly with `features = ["simd_backend", "nightly"]`
41//! * [SHA2](https://github.com/RustCrypto/hashes/tree/master/sha2) (used by
42//! sealed boxes) includes SIMD implementation for AVX2
43//! * [ChaCha20](https://github.com/RustCrypto/stream-ciphers/tree/master/chacha20)
44//! (used by streaming interface) includes SIMD implementations for Neon,
45//! AVX2, and SSE2
46//!
47//! To enable all the SIMD backends through 3rd party crates, you'll need to
48//! also set `RUSTFLAGS`:
49//! * For AVX2 set `RUSTFLAGS=-Ctarget-cpu=haswell -Ctarget-feature=+avx2`
50//! * For SSE2 set `RUSTFLAGS=-Ctarget-feature=+sse2`
51//! * For Neon set `RUSTFLAGS=-Ctarget-feature=+neon`
52//!
53//! _Note that eventually this project will converge on portable SIMD
54//! implementations for all the core algos which will work across all platforms
55//! supported by LLVM, rather than relying on hand-coded assembly or intrinsics,
56//! but his is a work in progress_.
57//!
58//! ## APIs
59//!
60//! This library includes both a _Classic_ API, which is very similar to the
61//! original libsodium API, and _Rustaceous_ API with Rust-specific features.
62//! Both APIs can be used together interchangeably, according to your
63//! preferences. The Rustaceous API is a wrapper around the underlying classic
64//! API.
65//!
66//! It's recommended that you use the Rustaceous API unless you have strong
67//! feelings about using the Classic API. The Classic API includes some pitfalls
68//! and traps that are also present in the original libsodium API, and unless
69//! you're extra careful you could make mistakes. With the Rustaceous API, it's
70//! harder to make mistakes thanks to strict type and safety features.
71//!
72//! The Rustaceous API is, arguably, somewhat trickier to use, especially if
73//! you're new to Rust. The Rustaceous API requires knowing and specifying the
74//! desired type in many cases. For your convenience, type aliases are provided
75//! for common types within each module. The Classic API only uses base types
76//! (fixed length byte arrays and byte slices).
77//!
78//! | Feature | Rustaceous API | Classic API | Libsodium Docs |
79//! |-|-|-|-|
80//! | Public-key authenticated boxes | [`DryocBox`](dryocbox) | [`crypto_box`](classic::crypto_box) | [Link](https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption) |
81//! | Secret-key authenticated boxes | [`DryocSecretBox`](dryocsecretbox) | [`crypto_secretbox`](classic::crypto_secretbox) | [Link](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox) |
82//! | Streaming encryption | [`DryocStream`](dryocstream) | [`crypto_secretstream_xchacha20poly1305`](classic::crypto_secretstream_xchacha20poly1305) | [Link](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream) |
83//! | Generic hashing, HMAC | [`GenericHash`](generichash) | [`crypto_generichash`](classic::crypto_generichash) | [Link](https://doc.libsodium.org/hashing/generic_hashing) |
84//! | Secret-key authentication | [`Auth`](auth) | [`crypto_auth`](classic::crypto_auth) | [Link](https://doc.libsodium.org/secret-key_cryptography/secret-key_authentication) |
85//! | One-time authentication | [`OnetimeAuth`](onetimeauth) | [`crypto_onetimeauth`](classic::crypto_onetimeauth) | [Link](https://doc.libsodium.org/advanced/poly1305) |
86//! | Key derivation | [`Kdf`](kdf) | [`crypto_kdf`](classic::crypto_kdf) | [Link](https://doc.libsodium.org/key_derivation) |
87//! | Key exchange | [`Session`](kx) | [`crypto_kx`](classic::crypto_kx) | [Link](https://doc.libsodium.org/key_exchange) |
88//! | Public-key signatures | [`SigningKeyPair`](sign) | [`crypto_sign`](classic::crypto_sign) | [Link](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures) |
89//! | Password hashing | [`PwHash`](pwhash) | [`crypto_pwhash`](classic::crypto_pwhash) | [Link](https://libsodium.gitbook.io/doc/password_hashing/default_phf) |
90//! | Protected memory[^4] | [protected] | N/A | [Link](https://doc.libsodium.org/memory_management) |
91//! | Short-input hashing | N/A | [`crypto_shorthash`](classic::crypto_shorthash) | [Link](https://libsodium.gitbook.io/doc/hashing/short-input_hashing) |
92//!
93//! ## Using Serde
94//!
95//! This crate includes optional [Serde](https://serde.rs/) support which can be
96//! enabled with the `serde` feature flag. When enabled, the
97//! [`Serialize`](serde::ser::Serialize) and
98//! [`Deserialize`](serde::de::Deserialize) traits are provided for data
99//! structures.
100//!
101//! ## Security notes
102//!
103//! This crate has not been audited by any 3rd parties. It uses well-known
104//! implementations of the underlying algorithms which have been previously
105//! verified as using constant-time operations.
106//!
107//! With that out of the way, the deterministic nature of cryptography and
108//! extensive testing used in this crate means it's relatively safe to use,
109//! provided the underlying algorithms remain safe. Arguably, this crate is
110//! _incredibly_ safe (as far as cryptography libraries go) thanks to the
111//! features provided by the API of this crate, and those provided by the Rust
112//! language itself.
113//!
114//! ## Acknowledgements
115//!
116//! Big ups to the authors and contributors of [NaCl](https://nacl.cr.yp.to/) and [libsodium](https://github.com/jedisct1/libsodium) for paving the
117//! way toward better cryptography libraries.
118//!
119//! [^1]: Not actually trademarked.
120//!
121//! [^2]: The protected memory features described in the [protected] mod require
122//! custom memory allocation, system calls, and pointer arithmetic, which are
123//! unsafe in Rust. Some of the 3rd party libraries used by this crate, such as
124//! those with SIMD, may contain unsafe code. In particular, most SIMD
125//! implementations are considered "unsafe" due to their use of assembly or
126//! intrinsics, however without SIMD-based cryptography you may be exposed to
127//! timing attacks.
128//!
129//! [^3]: The Rustaceous API is designed to protect users of this library from
130//! making mistakes, however the Classic API allows one to do as one pleases.
131//!
132//! [^4]: Currently only available on nightly Rust, with the `nightly` feature
133//! flag enabled.
134
135#![cfg_attr(
136 any(feature = "nightly", all(feature = "nightly", doc)),
137 feature(allocator_api, doc_cfg)
138)]
139#![cfg_attr(
140 all(feature = "simd_backend", feature = "nightly"),
141 feature(portable_simd)
142)]
143#![cfg_attr(feature = "nightly", feature(test))]
144#[macro_use]
145mod error;
146#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
147#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
148#[macro_use]
149pub mod protected;
150
151mod argon2;
152mod blake2b;
153#[cfg(feature = "serde")]
154mod bytes_serde;
155mod poly1305;
156mod scalarmult_curve25519;
157mod siphash24;
158
159pub mod classic {
160 //! # Classic API
161 //!
162 //! The Classic API contains functions designed to match the interface of
163 //! libsodium as closely as possible. It's provided to make it easier to
164 //! switch code from using libsodium directly over to dryoc, and also to
165 //! provide a familiar interface for anyone already comfortable with
166 //! libsodium.
167 mod crypto_box_impl;
168 mod crypto_secretbox_impl;
169 mod generichash_blake2b;
170
171 pub mod crypto_auth;
172 pub mod crypto_box;
173 /// # Core cryptography functions
174 pub mod crypto_core;
175 pub mod crypto_generichash;
176 /// Hash functions
177 pub mod crypto_hash;
178 pub mod crypto_kdf;
179 pub mod crypto_kx;
180 pub mod crypto_onetimeauth;
181 pub mod crypto_pwhash;
182 pub mod crypto_secretbox;
183 pub mod crypto_secretstream_xchacha20poly1305;
184 pub mod crypto_shorthash;
185 pub mod crypto_sign;
186 pub mod crypto_sign_ed25519;
187}
188
189pub mod auth;
190/// # Constant value definitions
191pub mod constants;
192pub mod dryocbox;
193pub mod dryocsecretbox;
194pub mod dryocstream;
195pub mod generichash;
196pub mod kdf;
197pub mod keypair;
198pub mod kx;
199pub mod onetimeauth;
200pub mod precalc;
201pub mod pwhash;
202/// # Random number generation utilities
203pub mod rng;
204pub mod sha512;
205pub mod sign;
206/// # Base type definitions
207pub mod types;
208/// # Various utility functions
209pub mod utils;
210
211pub use error::Error;
212
213#[cfg(test)]
214mod tests {
215
216 #[test]
217 fn test_randombytes_buf() {
218 use crate::rng::*;
219 let r = randombytes_buf(5);
220 assert_eq!(r.len(), 5);
221 let sum = r.into_iter().fold(0u64, |acc, n| acc + n as u64);
222 assert_ne!(sum, 0);
223 }
224}