1use std::cmp;
2
3use crate::{errors::Result, ErrorKind, SError};
4pub fn raw_scrypt_params(memlimit: usize, opslimit: u64, n_log2_max: u8) -> Result<scrypt::Params> {
5 let opslimit = cmp::max(32768, opslimit);
6 let mut n_log2 = 1u8;
7 let r = 8u32;
8 let p;
9 if opslimit < (memlimit / 32) as u64 {
10 p = 1;
11 let maxn = opslimit / (u64::from(r) * 4);
12 while n_log2 < 63 {
13 if 1u64 << n_log2 > maxn / 2 {
14 break;
15 }
16 n_log2 += 1;
17 }
18 } else {
19 let maxn = memlimit as u64 / (u64::from(r) * 128);
20 while n_log2 < 63 {
21 if 1u64 << n_log2 > maxn / 2 {
22 break;
23 }
24 n_log2 += 1;
25 }
26 let maxrp = cmp::min(0x3fff_ffff_u32, ((opslimit / 4) / (1u64 << n_log2)) as u32);
27 p = maxrp / r;
28 }
29 if n_log2 > n_log2_max {
30 return Err(SError::new(ErrorKind::Kdf, "scrypt parameters too high"));
31 }
32 scrypt::Params::new(n_log2, r, p, scrypt::Params::RECOMMENDED_LEN).map_err(Into::into)
33}