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
//! Key Derivation Functions (KDF).
//!
//! Two algorithms ship in 0.6.0, addressing different needs:
//!
//! | Algorithm | Purpose | Speed | Feature |
//! |-------------|----------------------------------------------------|---------------|---------------|
//! | HKDF-SHA256 | Derive one-or-many subkeys from a high-entropy IKM | Fast (µs) | `kdf-hkdf` |
//! | HKDF-SHA512 | Same, wider underlying digest | Fast (µs) | `kdf-hkdf` |
//! | Argon2id | Derive a key from a *password* (low-entropy input) | Slow (~100ms) | `kdf-argon2` |
//!
//! # Which one do I want?
//!
//! - **HKDF** ([RFC 5869]) for deriving subkeys from a master key, a
//! shared secret from a key exchange, or anything else already
//! high-entropy. HKDF does *not* protect against weak inputs — feeding
//! it a password is a security mistake.
//!
//! - **Argon2id** ([RFC 9106]) for deriving a key from a password. The
//! memory-hardness and tuneable cost are what protect against
//! brute-force attempts; the slowness is the point.
//!
//! [RFC 5869]: https://datatracker.ietf.org/doc/html/rfc5869
//! [RFC 9106]: https://datatracker.ietf.org/doc/html/rfc9106
//!
//! # Examples
//!
//! Deriving a 32-byte subkey from a master:
//!
//! ```
//! # #[cfg(feature = "kdf-hkdf")] {
//! use crypt_io::kdf;
//! let master = [0x42u8; 32];
//! let subkey = kdf::hkdf_sha256(&master, Some(b"salt"), b"app:session:v1", 32)?;
//! assert_eq!(subkey.len(), 32);
//! # }
//! # Ok::<(), crypt_io::Error>(())
//! ```
//!
//! Hashing and verifying a password:
//!
//! ```no_run
//! # #[cfg(feature = "kdf-argon2")] {
//! use crypt_io::kdf;
//! let phc = kdf::argon2_hash(b"correct horse battery staple")?;
//! assert!(kdf::argon2_verify(&phc, b"correct horse battery staple")?);
//! assert!(!kdf::argon2_verify(&phc, b"wrong guess")?);
//! # }
//! # Ok::<(), crypt_io::Error>(())
//! ```
pub use ;
pub use ;