1use scrypt::scrypt as scrypt_hash;
2
3pub fn scrypt(
28 pass: impl AsRef<[u8]>,
29 salt: impl AsRef<[u8]>,
30 output_len: usize, ) -> Vec<u8> {
33 let params = scrypt::Params::recommended();
34 let mut output = vec![0u8; output_len];
35 scrypt_hash(pass.as_ref(), salt.as_ref(), ¶ms, &mut output)
36 .expect("scrypt failed");
37 output
38}
39
40pub fn scrypt_opt(
41 pass: impl AsRef<[u8]>,
42 salt: impl AsRef<[u8]>,
43 output_len: usize, log_n: u8, r: u32, p: u32, ) -> Vec<u8> {
49 let params = scrypt::Params::new(log_n, r, p, output_len)
50 .expect("Invalid Scrypt parameters");
51 let mut output = vec![0u8; output_len];
52 scrypt_hash(pass.as_ref(), salt.as_ref(), ¶ms, &mut output)
53 .expect("scrypt failed");
54 output
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_scrypt_basic() {
63 let pass = b"password";
64 let salt = b"salt";
65 let output = scrypt(pass, salt, 32);
66 assert_eq!(output.len(), 32);
67 let output2 = scrypt(pass, salt, 32);
69 assert_eq!(output, output2);
70 }
71
72 #[test]
73 fn test_scrypt_different_salt() {
74 let pass = b"password";
75 let salt1 = b"salt1";
76 let salt2 = b"salt2";
77 let out1 = scrypt(pass, salt1, 32);
78 let out2 = scrypt(pass, salt2, 32);
79 assert_ne!(out1, out2);
80 }
81
82 #[test]
83 fn test_scrypt_opt_basic() {
84 let pass = b"password";
85 let salt = b"salt";
86 let output = scrypt_opt(pass, salt, 32, 15, 8, 1);
87 assert_eq!(output.len(), 32);
88 }
89
90 #[test]
91 fn test_scrypt_output_length() {
92 let pass = b"password";
93 let salt = b"salt";
94 for len in [16, 24, 32, 64] {
95 let output = scrypt(pass, salt, len);
96 assert_eq!(output.len(), len);
97 }
98 }
99}