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