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
//! # 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.
//!
//! The minimum supported Rust version (MSRV) for this crate is **Rust 1.51** or
//! newer.
//!
//! ## 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"]`)
//! * [_Portable_ SIMD](https://doc.rust-lang.org/std/simd/index.html)
//! implementation for Blake2b (used by generic hashing, password hashing, and
//! key derivation) on nightly, with `features = ["simd_backend", "nightly"]`
//! * SIMD backend for Curve25519 (used by public/private key functions) on
//! nightly with `features = ["simd_backend", "nightly"]`
//! * [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
//!
//! To enable all the SIMD backends through 3rd party crates, you'll need to
//! also set `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`
//!
//! _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 his is a work in progress_.
//!
//! ## 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.
//!
//! ## 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 of the 3rd party libraries used by this crate, such as
//! those with SIMD, may contain unsafe code. In particular, most 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.
//!
//! [^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.
#![cfg_attr(
any(feature = "nightly", all(feature = "nightly", doc)),
feature(allocator_api, doc_cfg)
)]
#![cfg_attr(
all(feature = "simd_backend", feature = "nightly"),
feature(portable_simd)
)]
#![cfg_attr(feature = "nightly", feature(test))]
#[macro_use]
mod error;
#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
#[macro_use]
pub mod protected;
mod argon2;
mod blake2b;
#[cfg(feature = "serde")]
mod bytes_serde;
mod poly1305;
mod scalarmult_curve25519;
mod siphash24;
pub mod classic {
//! # Classic API
//!
//! The Classic API contains functions designed to match the interface of
//! libsodium as closely as possible. It's provided to make it easier to
//! switch code from using libsodium directly over to dryoc, and also to
//! provide a familiar interface for anyone already comfortable with
//! libsodium.
mod crypto_box_impl;
mod crypto_secretbox_impl;
mod generichash_blake2b;
pub mod crypto_auth;
pub mod crypto_box;
/// # Core cryptography functions
pub mod crypto_core;
pub mod crypto_generichash;
/// Hash functions
pub mod crypto_hash;
pub mod crypto_kdf;
pub mod crypto_kx;
pub mod crypto_onetimeauth;
pub mod crypto_pwhash;
pub mod crypto_secretbox;
pub mod crypto_secretstream_xchacha20poly1305;
pub mod crypto_shorthash;
pub mod crypto_sign;
pub mod crypto_sign_ed25519;
}
pub mod auth;
/// # Constant value definitions
pub mod constants;
pub mod dryocbox;
pub mod dryocsecretbox;
pub mod dryocstream;
pub mod generichash;
pub mod kdf;
pub mod keypair;
pub mod kx;
pub mod onetimeauth;
pub mod pwhash;
/// # Random number generation utilities
pub mod rng;
pub mod sha512;
pub mod sign;
/// # Base type definitions
pub mod types;
/// # Various utility functions
pub mod utils;
pub use error::Error;
#[cfg(test)]
mod tests {
#[test]
fn test_randombytes_buf() {
use crate::rng::*;
let r = randombytes_buf(5);
assert_eq!(r.len(), 5);
let sum = r.into_iter().fold(0u64, |acc, n| acc + n as u64);
assert_ne!(sum, 0);
}
}