1 //! Argon2 summarizes the state of the art in the design of memory-hard functions.
2 //!
3 //! It aims at the highest memory filling rate and effective use of multiple
4 //! computing units, while still providing defense against tradeoff attacks.
5 //!
6 //! It prevents ASICs from having a significant advantage over software
7 //! implementations.
8 //!
9 //! Argon2i uses data-independent memory access, which is preferred for
10 //! password hashing and password-based key derivation. Argon2i is
11 //! invulnerable to side-channel timing attacks but weaker against
12 //! Time-memory Tradeoff (TMTO) attacks.  If you are unsure which
13 //! Argon2 variant to use, use Argon2id, not this module.
14 //!
15 //! Note: libsodium provides a limited version of the Argon2 function. The salt
16 //! parameter is fixed at 128 bits and the parallelism parameter is fixed to 1.
17 
18 use ffi::{
19     crypto_pwhash_ALG_ARGON2I13, crypto_pwhash_argon2i, crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE,
20     crypto_pwhash_argon2i_MEMLIMIT_MODERATE, crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE,
21     crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE, crypto_pwhash_argon2i_OPSLIMIT_MODERATE,
22     crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE, crypto_pwhash_argon2i_SALTBYTES,
23     crypto_pwhash_argon2i_STRBYTES, crypto_pwhash_argon2i_STRPREFIX, crypto_pwhash_argon2i_str,
24     crypto_pwhash_argon2i_str_verify,
25 };
26 
27 argon2_module!(
28     crypto_pwhash_argon2i,
29     crypto_pwhash_argon2i_str,
30     crypto_pwhash_argon2i_str_verify,
31     crypto_pwhash_argon2i_SALTBYTES as usize,
32     crypto_pwhash_argon2i_STRBYTES as usize,
33     crypto_pwhash_argon2i_STRPREFIX,
34     crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE as usize,
35     crypto_pwhash_argon2i_OPSLIMIT_MODERATE as usize,
36     crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE as usize,
37     crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE as usize,
38     crypto_pwhash_argon2i_MEMLIMIT_MODERATE as usize,
39     crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE as usize,
40     crypto_pwhash_ALG_ARGON2I13
41 );
42 
43 #[cfg(test)]
44 mod test {
45     use super::*;
46 
47     /// Helper function to allow for testing derive_key with different configurations
run_derive_key_test( password: &[u8], salt: [u8; SALTBYTES], expected: &[u8], out_len: usize, ops: usize, mem: usize, ) -> Result<(), ()>48     fn run_derive_key_test(
49         password: &[u8],
50         salt: [u8; SALTBYTES],
51         expected: &[u8],
52         out_len: usize,
53         ops: usize,
54         mem: usize,
55     ) -> Result<(), ()> {
56         let mut out_bin = vec![0u8; out_len];
57         let result = derive_key(
58             out_bin.as_mut_slice(),
59             password,
60             &Salt(salt),
61             OpsLimit(ops),
62             MemLimit(mem),
63         );
64 
65         match result {
66             Ok(out_bin) => {
67                 assert_eq!(expected, out_bin, "output does not match expected result");
68                 Ok(())
69             }
70             Err(_) => Err(()),
71         }
72     }
73 
74     /// Converts a str into a hashed password struct
to_hashed_password(s: &str) -> HashedPassword75     fn to_hashed_password(s: &str) -> HashedPassword {
76         let mut pw = [0; 128];
77         s.as_bytes()
78             .iter()
79             .enumerate()
80             .for_each(|(i, val)| pw[i] = *val);
81         HashedPassword(pw)
82     }
83 
84     #[test]
test_pwhash_verify()85     fn test_pwhash_verify() {
86         use randombytes::randombytes;
87         for i in 0..32usize {
88             let pw = randombytes(i);
89             let pwh = pwhash(&pw, OpsLimit(16), MemLimit(8192)).unwrap();
90             assert!(pwhash_verify(&pwh, &pw));
91         }
92     }
93 
94     #[test]
test_pwhash_verify_tamper()95     fn test_pwhash_verify_tamper() {
96         use randombytes::randombytes;
97         for i in 0..16usize {
98             let mut pw = randombytes(i);
99             let pwh = pwhash(&pw, OpsLimit(16), MemLimit(8192)).unwrap();
100             for j in 0..pw.len() {
101                 pw[j] ^= 0x20;
102                 assert!(!pwhash_verify(&pwh, &pw));
103                 pw[j] ^= 0x20;
104             }
105         }
106     }
107 
108     #[cfg(feature = "serde")]
109     #[test]
test_serialisation()110     fn test_serialisation() {
111         use randombytes::randombytes;
112         use test_utils::round_trip;
113         for i in 0..32usize {
114             let pw = randombytes(i);
115             let pwh = pwhash(&pw, OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE).unwrap();
116             let salt = gen_salt();
117             round_trip(pwh);
118             round_trip(salt);
119         }
120     }
121 
122     #[test]
test_derive_01()123     fn test_derive_01() {
124         let password = [
125             0xa3, 0x47, 0xae, 0x92, 0xbc, 0xe9, 0xf8, 0x0f, 0x6f, 0x59, 0x5a, 0x44, 0x80, 0xfc,
126             0x9c, 0x2f, 0xe7, 0xe7, 0xd7, 0x14, 0x8d, 0x37, 0x1e, 0x94, 0x87, 0xd7, 0x5f, 0x5c,
127             0x23, 0x00, 0x8f, 0xfa, 0xe0, 0x65, 0x57, 0x7a, 0x92, 0x8f, 0xeb, 0xd9, 0xb1, 0x97,
128             0x3a, 0x5a, 0x95, 0x07, 0x3a, 0xcd, 0xbe, 0xb6, 0xa0, 0x30, 0xcf, 0xc0, 0xd7, 0x9c,
129             0xaa, 0x2d, 0xc5, 0xcd, 0x01, 0x1c, 0xef, 0x02, 0xc0, 0x8d, 0xa2, 0x32, 0xd7, 0x6d,
130             0x52, 0xdf, 0xbc, 0xa3, 0x8c, 0xa8, 0xdc, 0xbd, 0x66, 0x5b, 0x17, 0xd1, 0x66, 0x5f,
131             0x7c, 0xf5, 0xfe, 0x59, 0x77, 0x2e, 0xc9, 0x09, 0x73, 0x3b, 0x24, 0xde, 0x97, 0xd6,
132             0xf5, 0x8d, 0x22, 0x0b, 0x20, 0xc6, 0x0d, 0x7c, 0x07, 0xec, 0x1f, 0xd9, 0x3c, 0x52,
133             0xc3, 0x10, 0x20, 0x30, 0x0c, 0x6c, 0x1f, 0xac, 0xd7, 0x79, 0x37, 0xa5, 0x97, 0xc7,
134             0xa6,
135         ];
136         let salt = [
137             0x55, 0x41, 0xfb, 0xc9, 0x95, 0xd5, 0xc1, 0x97, 0xba, 0x29, 0x03, 0x46, 0xd2, 0xc5,
138             0x59, 0xde,
139         ];
140         let expected = [
141             0x23, 0xb8, 0x03, 0xc8, 0x4e, 0xaa, 0x25, 0xf4, 0xb4, 0x46, 0x34, 0xcc, 0x1e, 0x5e,
142             0x37, 0x79, 0x2c, 0x53, 0xfc, 0xd9, 0xb1, 0xeb, 0x20, 0xf8, 0x65, 0x32, 0x9c, 0x68,
143             0xe0, 0x9c, 0xbf, 0xa9, 0xf1, 0x96, 0x87, 0x57, 0x90, 0x1b, 0x38, 0x3f, 0xce, 0x22,
144             0x1a, 0xfe, 0x27, 0x71, 0x3f, 0x97, 0x91, 0x4a, 0x04, 0x13, 0x95, 0xbb, 0xe1, 0xfb,
145             0x70, 0xe0, 0x79, 0xe5, 0xbe, 0xd2, 0xc7, 0x14, 0x5b, 0x1f, 0x61, 0x54, 0x04, 0x6f,
146             0x59, 0x58, 0xe9, 0xb1, 0xb2, 0x90, 0x55, 0x45, 0x4e, 0x26, 0x4d, 0x1f, 0x22, 0x31,
147             0xc3, 0x16, 0xf2, 0x6b, 0xe2, 0xe3, 0x73, 0x8e, 0x83, 0xa8, 0x03, 0x15, 0xe9, 0xa0,
148             0x95, 0x1c, 0xe4, 0xb1, 0x37, 0xb5, 0x2e, 0x7d, 0x5e, 0xe7, 0xb3, 0x7f, 0x7d, 0x93,
149             0x6d, 0xce, 0xe5, 0x13, 0x62, 0xbc, 0xf7, 0x92, 0x59, 0x5e, 0x3c, 0x89, 0x6a, 0xd5,
150             0x04, 0x27, 0x34, 0xfc, 0x90, 0xc9, 0x2c, 0xae, 0x57, 0x2c, 0xe6, 0x3f, 0xf6, 0x59,
151             0xa2, 0xf7, 0x97, 0x4a, 0x3b, 0xd7, 0x30, 0xd0, 0x4d, 0x52, 0x5d, 0x25, 0x3c, 0xcc,
152             0x38,
153         ];
154         let result = run_derive_key_test(&password, salt, &expected, 155, 5, 7_256_678);
155         assert!(result.is_ok());
156     }
157 
158     #[test]
test_derive_02()159     fn test_derive_02() {
160         let password = [
161             0xe1, 0x25, 0xce, 0xe6, 0x1c, 0x8c, 0xb7, 0x77, 0x8d, 0x9e, 0x5a, 0xd0, 0xa6, 0xf5,
162             0xd9, 0x78, 0xce, 0x9f, 0x84, 0xde, 0x21, 0x3a, 0x85, 0x56, 0xd9, 0xff, 0xe2, 0x02,
163             0x02, 0x0a, 0xb4, 0xa6, 0xed, 0x90, 0x74, 0xa4, 0xeb, 0x34, 0x16, 0xf9, 0xb1, 0x68,
164             0xf1, 0x37, 0x51, 0x0f, 0x3a, 0x30, 0xb7, 0x0b, 0x96, 0xcb, 0xfa, 0x21, 0x9f, 0xf9,
165             0x9f, 0x6c, 0x6e, 0xaf, 0xfb, 0x15, 0xc0, 0x6b, 0x60, 0xe0, 0x0c, 0xc2, 0x89, 0x02,
166             0x77, 0xf0, 0xfd, 0x3c, 0x62, 0x21, 0x15, 0x77, 0x2f, 0x70, 0x48, 0xad, 0xae, 0xbe,
167             0xd8, 0x6e,
168         ];
169         let salt = [
170             0xf1, 0x19, 0x2d, 0xd5, 0xdc, 0x23, 0x68, 0xb9, 0xcd, 0x42, 0x13, 0x38, 0xb2, 0x24,
171             0x33, 0x45,
172         ];
173         let expected = [
174             0x0b, 0xb3, 0x76, 0x9b, 0x06, 0x4b, 0x9c, 0x43, 0xa9, 0x46, 0x04, 0x76, 0xab, 0x38,
175             0xc4, 0xa9, 0xa2, 0x47, 0x0d, 0x55, 0xd4, 0xc9, 0x92, 0xc6, 0xe7, 0x23, 0xaf, 0x89,
176             0x5e, 0x4c, 0x07, 0xc0, 0x9a, 0xf4, 0x1f, 0x22, 0xf9, 0x0e, 0xab, 0x58, 0x3a, 0x0c,
177             0x36, 0x2d, 0x17, 0x7f, 0x46, 0x77, 0xf2, 0x12, 0x48, 0x2f, 0xd1, 0x45, 0xbf, 0xb9,
178             0xac, 0x62, 0x11, 0x63, 0x5e, 0x48, 0x46, 0x11, 0x22, 0xbb, 0x49, 0x09, 0x7b, 0x5f,
179             0xb0, 0x73, 0x9d, 0x2c, 0xd2, 0x2a, 0x39, 0xbf, 0x03, 0xd2, 0x68, 0xe7, 0x49, 0x5d,
180             0x4f, 0xd8, 0xd7, 0x10, 0xaa, 0x15, 0x62, 0x02, 0xf0, 0xa0, 0x6e, 0x93, 0x2f, 0xf5,
181             0x13, 0xe6, 0xe7, 0xc7, 0x6a, 0x4e, 0x98, 0xb6, 0xdf, 0x5c, 0xf9, 0x22, 0xf1, 0x24,
182             0x79, 0x1b, 0x10, 0x76, 0xad, 0x90, 0x4e, 0x68, 0x97, 0x27, 0x1f, 0x5d, 0x7d, 0x24,
183             0xc5, 0x92, 0x9e, 0x2a, 0x3b, 0x83, 0x6d, 0x0f, 0x2f, 0x26, 0x97, 0xc2, 0xd7, 0x58,
184             0xee, 0x79, 0xbf, 0x12, 0x64, 0xf3, 0xfa, 0xe6, 0x5f, 0x37, 0x44, 0xe0, 0xf6, 0xd7,
185             0xd0, 0x7e, 0xf6, 0xe8, 0xb3, 0x5b, 0x70, 0xc0, 0xf8, 0x8e, 0x90, 0x36, 0x32, 0x5b,
186             0xfb, 0x24, 0xac, 0x7f, 0x55, 0x03, 0x51, 0x48, 0x6d, 0xa8, 0x7a, 0xef, 0x10, 0xd6,
187             0xb0, 0xcb, 0x77, 0xd1, 0xcf, 0x6e, 0x31, 0xcf, 0x98, 0x39, 0x9c, 0x6f, 0x24, 0x1c,
188             0x60, 0x5c, 0x65, 0x30, 0xdf, 0xfb, 0x47, 0x64, 0x78, 0x4f, 0x6c, 0x0b, 0x0b, 0xf6,
189             0x01, 0xd4, 0xe4, 0x43, 0x1e, 0x8b, 0x18, 0xda, 0xbd, 0xc3, 0x07, 0x9c, 0x6e, 0x26,
190             0x43, 0x02, 0xad, 0xe7, 0x9f, 0x61, 0xcb, 0xd5, 0x49, 0x7c, 0x95, 0x48, 0x63, 0x40,
191             0xbb, 0x89, 0x1a, 0x73, 0x72, 0x23, 0x10, 0x0b, 0xe0, 0x42, 0x96, 0x50,
192         ];
193         let result = run_derive_key_test(&password, salt, &expected, 250, 4, 7_849_083);
194         assert!(result.is_ok());
195     }
196 
197     #[test]
test_derive_03()198     fn test_derive_03() {
199         let password = [
200             0x92, 0x26, 0x3c, 0xbf, 0x6a, 0xc3, 0x76, 0x49, 0x9f, 0x68, 0xa4, 0x28, 0x9d, 0x3b,
201             0xb5, 0x9e, 0x5a, 0x22, 0x33, 0x5e, 0xba, 0x63, 0xa3, 0x2e, 0x64, 0x10, 0x24, 0x91,
202             0x55, 0xb9, 0x56, 0xb6, 0xa3, 0xb4, 0x8d, 0x4a, 0x44, 0x90, 0x6b, 0x18, 0xb8, 0x97,
203             0x12, 0x73, 0x00, 0xb3, 0x75, 0xb8, 0xf8, 0x34, 0xf1, 0xce, 0xff, 0xc7, 0x08, 0x80,
204             0xa8, 0x85, 0xf4, 0x7c, 0x33, 0x87, 0x67, 0x17, 0xe3, 0x92, 0xbe, 0x57, 0xf7, 0xda,
205             0x3a, 0xe5, 0x8d, 0xa4, 0xfd, 0x1f, 0x43, 0xda, 0xa7, 0xe4, 0x4b, 0xb8, 0x2d, 0x37,
206             0x17, 0xaf, 0x43, 0x19, 0x34, 0x9c, 0x24, 0xcd, 0x31, 0xe4, 0x6d, 0x29, 0x58, 0x56,
207             0xb0, 0x44, 0x1b, 0x6b, 0x28, 0x99, 0x92, 0xa1, 0x1c, 0xed, 0x1c, 0xc3, 0xbf, 0x30,
208             0x11, 0x60, 0x45, 0x90, 0x24, 0x4a, 0x3e, 0xb7, 0x37, 0xff, 0x22, 0x11, 0x29, 0x21,
209             0x5e, 0x4e, 0x43, 0x47, 0xf4, 0x91, 0x5d, 0x41, 0x29, 0x2b, 0x51, 0x73, 0xd1, 0x96,
210             0xeb, 0x9a, 0xdd, 0x69, 0x3b, 0xe5, 0x31, 0x9f, 0xda, 0xdc, 0x24, 0x29, 0x06, 0x17,
211             0x8b, 0xb6, 0xc0, 0x28, 0x6c, 0x9b, 0x6c, 0xa6, 0x01, 0x27, 0x46, 0x71, 0x1f, 0x58,
212             0xc8, 0xc3, 0x92, 0x01, 0x6b, 0x2f, 0xdf, 0xc0, 0x9c, 0x64, 0xf0, 0xf6, 0xb6, 0xab,
213             0x7b,
214         ];
215         let salt = [
216             0x3b, 0x84, 0x0e, 0x20, 0xe9, 0x55, 0x5e, 0x9f, 0xb0, 0x31, 0xc4, 0xba, 0x1f, 0x17,
217             0x47, 0xce,
218         ];
219         let expected = [
220             0xe9, 0xaa, 0x07, 0x3b, 0x0b, 0x87, 0x2f, 0x15, 0xc0, 0x83, 0xd1, 0xd7, 0xce, 0x52,
221             0xc0, 0x9f, 0x49, 0x3b, 0x82, 0x7c, 0xa7, 0x8f, 0x13, 0xa0, 0x6c, 0x17, 0x21, 0xb4,
222             0x5b, 0x1e, 0x17, 0xb2, 0x4c, 0x04, 0xe1, 0x9f, 0xe8, 0x69, 0x33, 0x31, 0x35, 0x36,
223             0x01, 0x97, 0xa7, 0xeb, 0x55, 0x99, 0x4f, 0xee, 0x3e, 0x8d, 0x96, 0x80, 0xae, 0xdf,
224             0xdf, 0x76, 0x74, 0xf3, 0xad, 0x7b, 0x84, 0xd5, 0x9d, 0x7e, 0xab, 0x03, 0x57, 0x9f,
225             0xfc, 0x10, 0xc7, 0x09, 0x30, 0x93, 0xbc, 0x48, 0xec, 0x84, 0x25, 0x2a, 0xa1, 0xb3,
226             0x0f, 0x40, 0xf5, 0xe8, 0x38, 0xf1, 0x44, 0x3e, 0x15, 0xe2, 0x77, 0x2a, 0x39, 0xf4,
227             0xe7, 0x74, 0xeb, 0x05, 0x20, 0x97, 0xe8, 0x88, 0x1e, 0x94, 0xf1, 0x54, 0x57, 0xb7,
228             0x79, 0xfa, 0x2a, 0xf2, 0xbb, 0xc9, 0xa9, 0x93, 0x68, 0x76, 0x57, 0xc7, 0x70, 0x4a,
229             0xc8, 0xa3, 0x7c, 0x25, 0xc1, 0xdf, 0x42, 0x89, 0xeb, 0x4c, 0x70, 0xda, 0x45, 0xf2,
230             0xfd, 0x46, 0xbc, 0x0f, 0x78, 0x25, 0x97, 0x67, 0xd3, 0xdd, 0x47, 0x8a, 0x7c, 0x36,
231             0x9c, 0xf8, 0x66, 0x75, 0x8b, 0xc3, 0x6d, 0x9b, 0xd8, 0xe2, 0xe3, 0xc9, 0xfb, 0x0c,
232             0xf7, 0xfd, 0x60, 0x73, 0xeb, 0xf6, 0x30, 0xc1, 0xf6, 0x7f, 0xa7, 0xd3, 0x03, 0xc0,
233             0x7d, 0xa4, 0x0b, 0x36, 0x74, 0x9d, 0x15, 0x7e, 0xa3, 0x79, 0x65, 0xfe, 0xf8, 0x10,
234             0xf2, 0xea, 0x05, 0xae, 0x6f, 0xc7, 0xd9, 0x6a, 0x8f, 0x34, 0x70, 0xd7, 0x3e, 0x15,
235             0xb2, 0x2b, 0x42, 0xe8, 0xd6, 0x98, 0x6d, 0xbf, 0xe5, 0x30, 0x32, 0x56, 0xb2, 0xb3,
236             0x56, 0x03, 0x72, 0xc4, 0x45, 0x2f, 0xfb, 0x2a, 0x04, 0xfb, 0x7c, 0x66, 0x91, 0x48,
237             0x9f, 0x70, 0xcb, 0x46, 0x83, 0x1b, 0xe0, 0x67, 0x91, 0x17, 0xf7,
238         ];
239         let result = run_derive_key_test(&password, salt, &expected, 249, 3, 7_994_791);
240         assert!(result.is_ok());
241     }
242 
243     #[test]
test_derive_04()244     fn test_derive_04() {
245         let password = [
246             0x02, 0x7b, 0x6d, 0x8e, 0x8c, 0x8c, 0x47, 0x4e, 0x9b, 0x69, 0xc7, 0xd9, 0xed, 0x4f,
247             0x99, 0x71, 0xe8, 0xe1, 0xce, 0x2f, 0x6b, 0xa9, 0x50, 0x48, 0x41, 0x4c, 0x39, 0x70,
248             0xf0, 0xf0, 0x9b, 0x70, 0xe3, 0xb6, 0xc5, 0xae, 0x05, 0x87, 0x2b, 0x3d, 0x86, 0x78,
249             0x70, 0x5b, 0x7d, 0x38, 0x18, 0x29, 0xc3, 0x51, 0xa5, 0xa9, 0xc8, 0x8c, 0x23, 0x35,
250             0x69, 0xb3, 0x5d, 0x6b, 0x0b, 0x80, 0x9d, 0xf4, 0x4b, 0x64, 0x51, 0xa9, 0xc2, 0x73,
251             0xf1, 0x15, 0x0e, 0x2e, 0xf8, 0xa0, 0xb5, 0x43, 0x7e, 0xb7, 0x01, 0xe3, 0x73, 0x47,
252             0x4c, 0xd4, 0x4b, 0x97, 0xef, 0x02, 0x48, 0xeb, 0xce, 0x2c, 0xa0, 0x40, 0x0e, 0x1b,
253             0x53, 0xf3, 0xd8, 0x62, 0x21, 0xec, 0xa3, 0xf1, 0x8e, 0xb4, 0x5b, 0x70, 0x2b, 0x91,
254             0x72, 0x44, 0x0f, 0x77, 0x4a, 0x82, 0xcb, 0xf1, 0xf6, 0xf5, 0x25, 0xdf, 0x30, 0xa6,
255             0xe2, 0x93, 0xc8, 0x73, 0xcc, 0xe6, 0x9b, 0xb0, 0x78, 0xed, 0x1f, 0x0d, 0x31, 0xe7,
256             0xf9, 0xb8, 0x06, 0x24, 0x09, 0xf3, 0x7f, 0x19, 0xf8, 0x55, 0x0a, 0xae,
257         ];
258         let salt = [
259             0xeb, 0x2a, 0x30, 0x56, 0xa0, 0x9a, 0xd2, 0xd7, 0xd7, 0xf9, 0x75, 0xbc, 0xd7, 0x07,
260             0x59, 0x8f,
261         ];
262         let expected = [0x00];
263         let result = run_derive_key_test(&password, salt, &expected, 5, 4, 1_397_645);
264         assert!(result.is_err(), "Test should fail, output size too small");
265     }
266 
267     #[test]
test_derive_05()268     fn test_derive_05() {
269         let password = [
270             0x4a, 0x85, 0x7e, 0x2e, 0xe8, 0xaa, 0x9b, 0x60, 0x56, 0xf2, 0x42, 0x4e, 0x84, 0xd2,
271             0x4a, 0x72, 0x47, 0x33, 0x78, 0x90, 0x6e, 0xe0, 0x4a, 0x46, 0xcb, 0x05, 0x31, 0x15,
272             0x02, 0xd5, 0x25, 0x0b, 0x82, 0xad, 0x86, 0xb8, 0x3c, 0x8f, 0x20, 0xa2, 0x3d, 0xbb,
273             0x74, 0xf6, 0xda, 0x60, 0xb0, 0xb6, 0xec, 0xff, 0xd6, 0x71, 0x34, 0xd4, 0x59, 0x46,
274             0xac, 0x8e, 0xbf, 0xb3, 0x06, 0x42, 0x94, 0xbc, 0x09, 0x7d, 0x43, 0xce, 0xd6, 0x86,
275             0x42, 0xbf, 0xb8, 0xbb, 0xbd, 0xd0, 0xf5, 0x0b, 0x30, 0x11, 0x8f, 0x5e,
276         ];
277         let salt = [
278             0x39, 0xd8, 0x2e, 0xef, 0x32, 0x01, 0x0b, 0x8b, 0x79, 0xcc, 0x5b, 0xa8, 0x8e, 0xd5,
279             0x39, 0xfb,
280         ];
281         let expected = [
282             0xc1, 0x21, 0x20, 0x9f, 0x0b, 0xa7, 0x0a, 0xed, 0x93, 0xd4, 0x92, 0x00, 0xe5, 0xdc,
283             0x82, 0xcc, 0xe0, 0x13, 0xce, 0xf2, 0x5e, 0xa3, 0x1e, 0x16, 0x0b, 0xf8, 0xdb, 0x3c,
284             0xf4, 0x48, 0xa5, 0x9d, 0x1a, 0x56, 0xf6, 0xc1, 0x92, 0x59, 0xe1, 0x8e, 0xa0, 0x20,
285             0x55, 0x3c, 0xb7, 0x57, 0x81, 0x76, 0x1d, 0x11, 0x2b, 0x2d, 0x94, 0x9a, 0x29, 0x75,
286             0x84, 0xc6, 0x5e, 0x60, 0xdf, 0x95, 0xad, 0x89, 0xc4, 0x10, 0x98, 0x25, 0xa3, 0x17,
287             0x1d, 0xc6, 0xf2, 0x0b, 0x1f, 0xd6, 0xb0, 0xcd, 0xfd, 0x19, 0x48, 0x61, 0xbc, 0x2b,
288             0x41, 0x42, 0x95, 0xbe, 0xe5, 0xc6, 0xc5, 0x26, 0x19, 0xe5, 0x44, 0xab, 0xce, 0x7d,
289             0x52, 0x06, 0x59, 0xc3, 0xd5, 0x1d, 0xe2, 0xc6, 0x0e, 0x89, 0x94, 0x8d, 0x83, 0x06,
290             0x95, 0xab, 0x38, 0xdc, 0xb7, 0x5d, 0xd7, 0xab, 0x06, 0xa4, 0x77, 0x0d, 0xd4, 0xbc,
291             0x7c, 0x8f, 0x33, 0x55, 0x19, 0xe0, 0x4b, 0x03, 0x84, 0x16, 0xb1, 0xa7, 0xdb, 0xd2,
292             0x5c, 0x02, 0x67, 0x86, 0xa8, 0x10, 0x5c, 0x5f, 0xfe, 0x7a, 0x09, 0x31, 0x36, 0x4f,
293             0x03, 0x76, 0xae, 0x57, 0x72, 0xbe, 0x39, 0xb5, 0x1d, 0x91, 0xd3, 0x28, 0x14, 0x64,
294             0xe0, 0xf3, 0xa1, 0x28, 0xe7, 0x15, 0x5a, 0x68, 0xe8, 0x7c, 0xf7, 0x96, 0x26, 0xff,
295             0xca, 0x0b, 0x2a, 0x30, 0x22, 0xfc, 0x84, 0x20,
296         ];
297         let result = run_derive_key_test(&password, salt, &expected, 190, 3, 1_432_947);
298         assert!(result.is_ok());
299     }
300 
301     #[test]
test_derive_06()302     fn test_derive_06() {
303         let password = [
304             0xc7, 0xb0, 0x9a, 0xec, 0x68, 0x0e, 0x7b, 0x42, 0xfe, 0xdd, 0x7f, 0xc7, 0x92, 0xe7,
305             0x8b, 0x2f, 0x6c, 0x1b, 0xea, 0x8f, 0x4a, 0x88, 0x43, 0x20, 0xb6, 0x48, 0xf8, 0x1e,
306             0x8c, 0xf5, 0x15, 0xe8, 0xba, 0x9d, 0xcf, 0xb1, 0x1d, 0x43, 0xc4, 0xaa, 0xe1, 0x14,
307             0xc1, 0x73, 0x4a, 0xa6, 0x9c, 0xa8, 0x2d, 0x44, 0x99, 0x83, 0x65, 0xdb, 0x9c, 0x93,
308             0x74, 0x4f, 0xa2, 0x8b, 0x63, 0xfd, 0x16, 0x00, 0x0e, 0x82, 0x61, 0xcb, 0xbe, 0x08,
309             0x3e, 0x7e, 0x2d, 0xa1, 0xe5, 0xf6, 0x96, 0xbd, 0xe0, 0x83, 0x4f, 0xe5, 0x31, 0x46,
310             0xd7, 0xe0, 0xe3, 0x5e, 0x7d, 0xe9, 0x92, 0x0d, 0x04, 0x1f, 0x5a, 0x56, 0x21, 0xaa,
311             0xbe, 0x02, 0xda, 0x3e, 0x2b, 0x09, 0xb4, 0x05, 0xb7, 0x79, 0x37, 0xef, 0xef, 0x31,
312             0x97, 0xbd, 0x57, 0x72, 0xe4, 0x1f, 0xdb, 0x73, 0xfb, 0x52, 0x94, 0x47, 0x8e, 0x45,
313             0x20, 0x80, 0x63, 0xb5, 0xf5, 0x8e, 0x08, 0x9d, 0xbe, 0xb6, 0xd6, 0x34, 0x2a, 0x90,
314             0x9c, 0x13, 0x07, 0xb3, 0xff, 0xf5, 0xfe, 0x2c, 0xf4, 0xda, 0x56, 0xbd, 0xae, 0x50,
315             0x84, 0x8f,
316         ];
317         let salt = [
318             0x03, 0x9c, 0x05, 0x6d, 0x93, 0x3b, 0x47, 0x50, 0x32, 0x77, 0x7e, 0xdb, 0xaf, 0xfa,
319             0xc5, 0x0f,
320         ];
321         let expected = [
322             0x91, 0xc3, 0x37, 0xce, 0x89, 0x18, 0xa5, 0x80, 0x5a, 0x59, 0xb0, 0x0b, 0xd1, 0x81,
323             0x9d, 0x3e, 0xb4, 0x35, 0x68, 0x07, 0xcb, 0xd2, 0xa8, 0x0b, 0x27, 0x1c, 0x4b, 0x48,
324             0x2d, 0xce, 0x03, 0xf5, 0xb0, 0x2a, 0xe4, 0xeb, 0x83, 0x1f, 0xf6, 0x68, 0xcb, 0xb3,
325             0x27, 0xb9, 0x3c, 0x30, 0x0b, 0x41, 0xda, 0x48, 0x52, 0xe5, 0x54, 0x7b, 0xea, 0x83,
326             0x42, 0xd5, 0x18, 0xdd, 0x93, 0x11, 0xaa, 0xeb, 0x5f, 0x90, 0xec, 0xcf, 0x66, 0xd5,
327             0x48, 0xf9, 0x27, 0x56, 0x31, 0xf0, 0xb1, 0xfd, 0x4b, 0x29, 0x9c, 0xec, 0x5d, 0x2e,
328             0x86, 0xa5, 0x9e, 0x55, 0xdc, 0x7b, 0x3a, 0xfa, 0xb6, 0x20, 0x44, 0x47, 0xb2, 0x1d,
329             0x1e, 0xf1, 0xda, 0x82, 0x4a, 0xba, 0xf3, 0x1a, 0x25, 0xa0, 0xd6, 0x13, 0x5c, 0x4f,
330             0xe8, 0x1d, 0x34, 0xa0, 0x68, 0x16, 0xc8, 0xa6, 0xea, 0xb1, 0x91, 0x41, 0xf5, 0x68,
331             0x71, 0x08, 0x50, 0x0f, 0x37, 0x19, 0xa8, 0x62, 0xaf, 0x8c, 0x5f, 0xee, 0x36, 0xe1,
332             0x30, 0xc6, 0x99, 0x21, 0xe1, 0x1c, 0xe8, 0x3d, 0xfc, 0x72, 0xc5, 0xec, 0x3b, 0x86,
333             0x2c, 0x1b, 0xcc, 0xc5, 0xfd, 0x63, 0xad, 0x57, 0xf4, 0x32, 0xfb, 0xcc, 0xa6, 0xf9,
334             0xe1, 0x8d, 0x5a, 0x59, 0x01, 0x59, 0x50, 0xcd, 0xf0, 0x53,
335         ];
336         let result = run_derive_key_test(&password, salt, &expected, 178, 3, 4_886_999);
337         assert!(result.is_ok());
338     }
339 
340     #[test]
test_derive_07()341     fn test_derive_07() {
342         let password = [
343             0xb5, 0x40, 0xbe, 0xb0, 0x16, 0xa5, 0x36, 0x65, 0x24, 0xd4, 0x60, 0x51, 0x56, 0x49,
344             0x3f, 0x98, 0x74, 0x51, 0x4a, 0x5a, 0xa5, 0x88, 0x18, 0xcd, 0x0c, 0x6d, 0xff, 0xfa,
345             0xa9, 0xe9, 0x02, 0x05, 0xf1, 0x7b,
346         ];
347         let salt = [
348             0x44, 0x07, 0x1f, 0x6d, 0x18, 0x15, 0x61, 0x67, 0x0b, 0xda, 0x72, 0x8d, 0x43, 0xfb,
349             0x79, 0xb4,
350         ];
351         let expected = [0x00];
352         let result = run_derive_key_test(&password, salt, &expected, 231, 1, 1_631_659);
353         assert!(
354             result.is_err(),
355             "Test should fail, argon2i with opslimit < 3"
356         );
357     }
358 
359     #[test]
test_derive_08()360     fn test_derive_08() {
361         let password = [
362             0xa1, 0x49, 0x75, 0xc2, 0x6c, 0x08, 0x87, 0x55, 0xa8, 0xb7, 0x15, 0xff, 0x25, 0x28,
363             0xd6, 0x47, 0xcd, 0x34, 0x39, 0x87, 0xfc, 0xf4, 0xaa, 0x25, 0xe7, 0x19, 0x4a, 0x84,
364             0x17, 0xfb, 0x2b, 0x4b, 0x3f, 0x72, 0x68, 0xda, 0x9f, 0x31, 0x82, 0xb4, 0xcf, 0xb2,
365             0x2d, 0x13, 0x8b, 0x27, 0x49, 0xd6, 0x73, 0xa4, 0x7e, 0xcc, 0x75, 0x25, 0xdd, 0x15,
366             0xa0, 0xa3, 0xc6, 0x60, 0x46, 0x97, 0x17, 0x84, 0xbb, 0x63, 0xd7, 0xea, 0xe2, 0x4c,
367             0xc8, 0x4f, 0x26, 0x31, 0x71, 0x20, 0x75, 0xa1, 0x0e, 0x10, 0xa9, 0x6b, 0x0e, 0x0e,
368             0xe6, 0x7c, 0x43, 0xe0, 0x1c, 0x42, 0x3c, 0xb9, 0xc4, 0x4e, 0x53, 0x71, 0x01, 0x7e,
369             0x9c, 0x49, 0x69, 0x56, 0xb6, 0x32, 0x15, 0x8d, 0xa3, 0xfe, 0x12, 0xad, 0xde, 0xcb,
370             0x88, 0x91, 0x2e, 0x67, 0x59, 0xbc, 0x37, 0xf9, 0xaf, 0x2f, 0x45, 0xaf, 0x72, 0xc5,
371             0xca, 0xe3, 0xb1, 0x79, 0xff, 0xb6, 0x76, 0xa6, 0x97, 0xde, 0x6e, 0xbe, 0x45, 0xcd,
372             0x4c, 0x16, 0xd4, 0xa9, 0xd6, 0x42, 0xd2, 0x9d, 0xdc, 0x01, 0x86, 0xa0, 0xa4, 0x8c,
373             0xb6, 0xcd, 0x62, 0xbf, 0xc3, 0xdd, 0x22, 0x9d, 0x31, 0x3b, 0x30, 0x15, 0x60, 0x97,
374             0x1e, 0x74, 0x0e, 0x2c, 0xf1, 0xf9, 0x9a, 0x9a, 0x09, 0x0a, 0x5b, 0x28, 0x3f, 0x35,
375             0x47, 0x50, 0x57, 0xe9, 0x6d, 0x70, 0x64, 0xe2, 0xe0, 0xfc, 0x81, 0x98, 0x45, 0x91,
376             0x06, 0x8d, 0x55, 0xa3, 0xb4, 0x16, 0x9f, 0x22, 0xcc, 0xcb, 0x07, 0x45, 0xa2, 0x68,
377             0x94, 0x07, 0xea, 0x19, 0x01, 0xa0, 0xa7, 0x66, 0xeb, 0x99,
378         ];
379         let salt = [
380             0x3d, 0x96, 0x8b, 0x27, 0x52, 0xb8, 0x83, 0x84, 0x31, 0x16, 0x50, 0x59, 0x31, 0x9f,
381             0x3f, 0xf8,
382         ];
383         let expected = [
384             0xe9, 0x42, 0x95, 0x1d, 0xfb, 0xc2, 0xd5, 0x08, 0x29, 0x4b, 0x10, 0xf9, 0xe9, 0x7b,
385             0x47, 0xd0, 0xcd, 0x04, 0xe6, 0x68, 0xa0, 0x43, 0xcb, 0x95, 0x67, 0x9c, 0xc1, 0x13,
386             0x9d, 0xf7, 0xc2, 0x7c, 0xd5, 0x43, 0x67, 0x68, 0x87, 0x25, 0xbe, 0x9d, 0x06, 0x9f,
387             0x57, 0x04, 0xc1, 0x22, 0x23, 0xe7, 0xe4, 0xca, 0x18, 0x1f, 0xbd, 0x0b, 0xed, 0x18,
388             0xbb, 0x46, 0x34, 0x79, 0x5e, 0x54, 0x5a, 0x6c, 0x04, 0xa7, 0x30, 0x69, 0x33, 0xa4,
389             0x1a, 0x79, 0x4b, 0xae, 0xdb, 0xb6, 0x28, 0xd4, 0x1b, 0xc2, 0x85, 0xe0, 0xb9, 0x08,
390             0x40, 0x55, 0xae, 0x13, 0x6f, 0x6b, 0x63, 0x62, 0x4c, 0x87, 0x4f, 0x5a, 0x1e, 0x1d,
391             0x8b, 0xe7, 0xb0, 0xb7, 0x22, 0x7a, 0x17, 0x1d, 0x2d, 0x7e, 0xd5, 0x78, 0xd8, 0x8b,
392             0xfd, 0xcf, 0x18, 0x32, 0x31, 0x98, 0x96, 0x2d, 0x0d, 0xca, 0xd4, 0x12, 0x6f, 0xd3,
393             0xf2, 0x1a, 0xde, 0xb1, 0xe1, 0x1d, 0x66, 0x25, 0x2e, 0xa0, 0xc5, 0x8c, 0x91, 0x69,
394             0x6e, 0x91, 0x03, 0x1b, 0xfd, 0xcc, 0x2a, 0x9d, 0xc0, 0xe0, 0x28, 0xd1, 0x7b, 0x97,
395             0x05, 0xba, 0x2d, 0x7b, 0xcd, 0xcd, 0x1e, 0x3b, 0xa7, 0x5b, 0x4b, 0x1f, 0xea,
396         ];
397         let result = run_derive_key_test(&password, salt, &expected, 167, 3, 1_784_128);
398         assert!(result.is_ok());
399     }
400 
401     #[test]
test_derive_09()402     fn test_derive_09() {
403         let password = [
404             0xa3, 0x47, 0xae, 0x92, 0xbc, 0xe9, 0xf8, 0x0f, 0x6f, 0x59, 0x5a, 0x44, 0x80, 0xfc,
405             0x9c, 0x2f, 0xe7, 0xe7, 0xd7, 0x14, 0x8d, 0x37, 0x1e, 0x94, 0x87, 0xd7, 0x5f, 0x5c,
406             0x23, 0x00, 0x8f, 0xfa, 0xe0, 0x65, 0x57, 0x7a, 0x92, 0x8f, 0xeb, 0xd9, 0xb1, 0x97,
407             0x3a, 0x5a, 0x95, 0x07, 0x3a, 0xcd, 0xbe, 0xb6, 0xa0, 0x30, 0xcf, 0xc0, 0xd7, 0x9c,
408             0xaa, 0x2d, 0xc5, 0xcd, 0x01, 0x1c, 0xef, 0x02, 0xc0, 0x8d, 0xa2, 0x32, 0xd7, 0x6d,
409             0x52, 0xdf, 0xbc, 0xa3, 0x8c, 0xa8, 0xdc, 0xbd, 0x66, 0x5b, 0x17, 0xd1, 0x66, 0x5f,
410             0x7c, 0xf5, 0xfe, 0x59, 0x77, 0x2e, 0xc9, 0x09, 0x73, 0x3b, 0x24, 0xde, 0x97, 0xd6,
411             0xf5, 0x8d, 0x22, 0x0b, 0x20, 0xc6, 0x0d, 0x7c, 0x07, 0xec, 0x1f, 0xd9, 0x3c, 0x52,
412             0xc3, 0x10, 0x20, 0x30, 0x0c, 0x6c, 0x1f, 0xac, 0xd7, 0x79, 0x37, 0xa5, 0x97, 0xc7,
413             0xa6,
414         ];
415         let salt = [
416             0x55, 0x41, 0xfb, 0xc9, 0x95, 0xd5, 0xc1, 0x97, 0xba, 0x29, 0x03, 0x46, 0xd2, 0xc5,
417             0x59, 0xde,
418         ];
419         let expected = [
420             0xfd, 0x32, 0x98, 0x73, 0x38, 0x74, 0x29, 0xcb, 0x79, 0xfa, 0xae, 0xc4, 0xf6, 0x5c,
421             0x35, 0x64, 0x9f, 0x65, 0xde, 0x0a, 0xab, 0xc1, 0xf0, 0x92, 0xca, 0x9d, 0xee, 0x20,
422             0x02, 0x9d, 0x8a, 0xe6, 0xc3, 0xa9, 0x7e, 0x99, 0x40, 0x76, 0x3e, 0x17, 0x03, 0xa7,
423             0xfe, 0xf5, 0xa2, 0x0e, 0xb7, 0xf2, 0x10, 0x12, 0x3f, 0xc8, 0xc6, 0xd3, 0xf1, 0x74,
424             0x5d, 0x19, 0xd5, 0xe3, 0xc1, 0xeb, 0x39, 0x2a, 0xb4, 0xa6, 0x07, 0x0c, 0x8a, 0x6b,
425             0x9e, 0xcb, 0xea, 0xba, 0xe0, 0x71, 0x13, 0x26, 0xe8, 0x15, 0x30, 0x09, 0x95, 0x41,
426             0xa8, 0x82, 0xd4, 0xbd, 0x77, 0x33, 0xc4, 0xa7, 0x47, 0x7a, 0xe7, 0x2b, 0x69, 0x28,
427             0xc4, 0x6c, 0xd0, 0x72, 0x64, 0x17, 0x2a, 0x9d, 0x2c, 0xfb, 0x7d, 0x64, 0x95, 0x94,
428             0xf8, 0x77, 0xf8, 0xb4, 0x47, 0xd9, 0xc0, 0x1b, 0x17, 0x99, 0x6b, 0x85, 0xdb, 0x5a,
429             0x71, 0xf7, 0x33, 0xf8, 0xcc, 0x5f, 0xd0, 0x43, 0x65, 0x40, 0xa5, 0xb7, 0xa1, 0xd7,
430             0x9d, 0xe0, 0x9e, 0x20, 0xc3, 0xab, 0xe6, 0x51, 0x55, 0x01, 0xb3, 0x15, 0x6c, 0xd5,
431             0x1e,
432         ];
433         let result = run_derive_key_test(&password, salt, &expected, 155, 4, 397_645);
434         assert!(result.is_ok());
435     }
436 
437     #[test]
test_derive_10()438     fn test_derive_10() {
439         let password = [
440             0xa3, 0x47, 0xae, 0x92, 0xbc, 0xe9, 0xf8, 0x0f, 0x6f, 0x59, 0x5a, 0x44, 0x80, 0xfc,
441             0x9c, 0x2f, 0xe7, 0xe7, 0xd7, 0x14, 0x8d, 0x37, 0x1e, 0x94, 0x87, 0xd7, 0x5f, 0x5c,
442             0x23, 0x00, 0x8f, 0xfa, 0xe0, 0x65, 0x57, 0x7a, 0x92, 0x8f, 0xeb, 0xd9, 0xb1, 0x97,
443             0x3a, 0x5a, 0x95, 0x07, 0x3a, 0xcd, 0xbe, 0xb6, 0xa0, 0x30, 0xcf, 0xc0, 0xd7, 0x9c,
444             0xaa, 0x2d, 0xc5, 0xcd, 0x01, 0x1c, 0xef, 0x02, 0xc0, 0x8d, 0xa2, 0x32, 0xd7, 0x6d,
445             0x52, 0xdf, 0xbc, 0xa3, 0x8c, 0xa8, 0xdc, 0xbd, 0x66, 0x5b, 0x17, 0xd1, 0x66, 0x5f,
446             0x7c, 0xf5, 0xfe, 0x59, 0x77, 0x2e, 0xc9, 0x09, 0x73, 0x3b, 0x24, 0xde, 0x97, 0xd6,
447             0xf5, 0x8d, 0x22, 0x0b, 0x20, 0xc6, 0x0d, 0x7c, 0x07, 0xec, 0x1f, 0xd9, 0x3c, 0x52,
448             0xc3, 0x10, 0x20, 0x30, 0x0c, 0x6c, 0x1f, 0xac, 0xd7, 0x79, 0x37, 0xa5, 0x97, 0xc7,
449             0xa6,
450         ];
451         let salt = [
452             0x55, 0x41, 0xfb, 0xc9, 0x95, 0xd5, 0xc1, 0x97, 0xba, 0x29, 0x03, 0x46, 0xd2, 0xc5,
453             0x59, 0xde,
454         ];
455         let expected = [
456             0xbb, 0xbc, 0x4c, 0x79, 0x63, 0x59, 0x36, 0x01, 0xd4, 0xd6, 0x85, 0xed, 0x9d, 0x89,
457             0x68, 0x23, 0x74, 0xf8, 0xe6, 0xb3, 0xce, 0x92, 0xce, 0x8c, 0xcc, 0x70, 0x27, 0x28,
458             0xec, 0x8b, 0xf8, 0x39, 0xfd, 0x7c, 0xb8, 0xe3, 0x7d, 0xdb, 0x09, 0xbe, 0x8c, 0x18,
459             0xc7, 0xe0, 0xed, 0x09, 0x99, 0x49, 0x66, 0x52, 0x27, 0xa0, 0x0f, 0xb3, 0x3e, 0x1f,
460             0x63, 0xca, 0x83, 0x0d, 0xbe, 0xb1, 0x3b, 0x29, 0xd9, 0x87, 0xb4, 0x45, 0xb3, 0xe0,
461             0x81, 0xcd, 0x84, 0x28, 0xbd, 0xb2, 0xf9, 0xe0, 0x03, 0xe1, 0x2b, 0xea, 0x98, 0x23,
462             0x0f, 0xd3, 0x08, 0x42, 0xfa, 0x19, 0x3a, 0xf9, 0x16, 0x91, 0x71, 0xb5, 0x50, 0x32,
463             0x20, 0x72, 0xc8, 0x83, 0x30, 0xea, 0x46, 0x4c, 0xbe, 0x02, 0xb6, 0xee, 0x04, 0x43,
464             0x74, 0xd3, 0xf3, 0xd1, 0x74, 0xc2, 0x36, 0x17, 0xb7, 0x07, 0x15, 0x9a, 0x11, 0x92,
465             0x6c, 0x56, 0x60, 0x11, 0x23, 0xdc, 0xc3, 0x05, 0x08, 0xec, 0x84, 0xfd, 0xb0, 0x79,
466             0x7b, 0x7a, 0xb2, 0x3a, 0x77, 0xee, 0xef, 0xb2, 0xa0, 0xbe, 0x2e, 0xf4, 0x5e, 0x90,
467             0x3c,
468         ];
469         let result = run_derive_key_test(&password, salt, &expected, 155, 3, 397_645);
470         assert!(result.is_ok());
471     }
472 
473     #[test]
test_verify_1()474     fn test_verify_1() {
475         let password = "";
476         let out = "$argon2i$v=19$m=4096,t=1,p=1$X1NhbHQAAAAAAAAAAAAAAA$bWh++\
477                    MKN1OiFHKgIWTLvIi1iHicmHH7+Fv3K88ifFfI";
478         let hashed = to_hashed_password(out);
479 
480         assert!(
481             pwhash_verify(&hashed, password.as_bytes()),
482             "failed to verify password with hash"
483         );
484     }
485 
486     #[test]
test_verify_2()487     fn test_verify_2() {
488         let password = "";
489         let out = "$argon2i$v=19$m=2048,t=4,p=1$SWkxaUhpY21ISDcrRnYzSw$Mbg/\
490                    Eck1kpZir5T9io7C64cpffdTBaORgyriLQFgQj8";
491         let hashed = to_hashed_password(out);
492 
493         assert!(
494             pwhash_verify(&hashed, password.as_bytes()),
495             "failed to verify password with hash"
496         );
497     }
498 
499     #[test]
test_verify_3()500     fn test_verify_3() {
501         let password = "^T5H$JYt39n%K*j:W]!1s?vg!:jGi]Ax?..l7[p0v:1jHTpla9;]bUN;?bWyCbtqg ";
502         let out = "$argon2i$v=19$m=4096,t=3,p=2$X1NhbHQAAAAAAAAAAAAAAA$z/\
503                    QMiU4lQxGsYNc/+K/bizwsA1P11UG2dj/7+aILJ4I";
504         let hashed = to_hashed_password(out);
505 
506         assert!(
507             pwhash_verify(&hashed, password.as_bytes()),
508             "failed to verify password with hash"
509         );
510     }
511 
512     #[test]
test_verify_4()513     fn test_verify_4() {
514         let password = "K3S=KyH#)36_?]LxeR8QNKw6X=gFbxai$C%29V*";
515         let out = "$argon2i$v=19$m=4096,t=3,p=1$X1NhbHQAAAAAAAAAAAAAAA$fu2Wsecyt+\
516                    yPnBvSvYN16oP5ozRmkp0ixJ1YL19V3Uo";
517         let hashed = to_hashed_password(out);
518 
519         assert!(
520             pwhash_verify(&hashed, password.as_bytes()),
521             "failed to verify password with hash"
522         );
523     }
524 
525     #[test]
test_hash_1()526     fn test_hash_1() {
527         let password = "Correct Horse Battery Staple";
528         let opslimit = OpsLimit(3);
529         let memlimit = MemLimit(5_000_000);
530 
531         let result = pwhash(password.as_bytes(), opslimit, memlimit);
532         assert!(result.is_ok(), "failed to hash password (1)");
533         let out_01 = result.unwrap();
534 
535         let result = pwhash(password.as_bytes(), opslimit, memlimit);
536         assert!(result.is_ok(), "failed to hash password (2)");
537         let out_02 = result.unwrap();
538 
539         assert_ne!(out_01, out_02, "not generating different salts");
540     }
541 
542     #[test]
test_hash_2()543     fn test_hash_2() {
544         let password = "Correct Horse Battery Staple";
545         let opslimit = OpsLimit(1);
546         let memlimit = MemLimit(5_000_000);
547 
548         let result = pwhash(password.as_bytes(), opslimit, memlimit);
549         assert!(
550             result.is_err(),
551             "should have failed (opslimit too small, < 3)"
552         );
553     }
554 
555     #[test]
test_hash_3()556     fn test_hash_3() {
557         let password = "Correct Horse Battery Staple";
558         let opslimit = OpsLimit(3);
559         let memlimit = MemLimit(5_000_000);
560 
561         let result = pwhash(password.as_bytes(), opslimit, memlimit);
562         assert!(result.is_ok(), "failed to hash password (1)");
563         let out = result.unwrap();
564 
565         assert!(
566             pwhash_verify(&out, password.as_bytes()),
567             "failed to verify password with hash"
568         );
569     }
570 }
571