diff --git a/README.md b/README.md index e5f98f6..b983475 100755 --- a/README.md +++ b/README.md @@ -23,16 +23,16 @@ Options: ### Deriving ```sh -Derive a value using Scrypt KDF +Derive a key using Scrypt KDF -Usage: scrypt-kdf derive --iterations --log-n --r --p

--l +Usage: scrypt-kdf derive [OPTIONS] Options: - -i, --iterations Number of iterations [default: 100] - -l, --log-n Work factor [default: 20] - -r, --r Block size [default: 8] - -p, --p

Parallelization parameter [default: 1] - -l, --l Length of the derived result [default: 16] + -i, --iterations Number of iterations (must be greater than 0 and less than or equal to 4294967295) [default: 100] + -n CPU/memory cost parameter (must be less than 64) [default: 20] + -r Block size parameter, which fine-tunes sequential memory read size and performance (must be greater than 0 and less than or equal to 4294967295) [default: 8] + -p

Parallelization parameter (must be greater than 0 and less than 4294967295) [default: 1] + -l, --length Length of the derived result (must be greater than 9 and less than or equal to 64) [default: 16] -h, --help Print help ``` diff --git a/src/main.rs b/src/main.rs index 3cb47c8..866892c 100755 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use crossterm::{ }; use humantime::format_duration; use pbr::ProgressBar; -use scrypt_kdf::DEFAULT_SCRYPT_KDF_OPTIONS; +use scrypt_kdf::{DEFAULT_SCRYPT_KDF_OPTIONS, MAX_KDF_LEN, MIN_KDF_LEN}; use std::{ env, io::{self, Write}, @@ -36,22 +36,22 @@ struct Cli { #[derive(Subcommand)] enum Commands { - #[command(about = "Derive a value using Scrypt KDF")] + #[command(about = "Derive a key using Scrypt KDF")] Derive { - #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.iterations.to_string(), help = "Number of iterations")] + #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.iterations.to_string(), help = format!("Number of iterations (must be greater than 0 and less than or equal to {})", u32::MAX))] iterations: u32, - #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.log_n.to_string(), help = "Work factor")] + #[arg(short = 'n', default_value = DEFAULT_SCRYPT_KDF_OPTIONS.log_n.to_string(), help = format!("CPU/memory cost parameter (must be less than {})", usize::BITS))] log_n: u8, - #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.r.to_string(), help = "Block size")] + #[arg(short, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.r.to_string(), help = format!("Block size parameter, which fine-tunes sequential memory read size and performance (must be greater than 0 and less than or equal to {})", u32::MAX))] r: u32, - #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.p.to_string(), help = "Parallelization parameter")] + #[arg(short, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.p.to_string(), help = format!("Parallelization parameter (must be greater than 0 and less than {})", u32::MAX))] p: u32, - #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.len.to_string(), help = "Length of the derived result")] - l: usize, + #[arg(short, long, default_value = DEFAULT_SCRYPT_KDF_OPTIONS.len.to_string(), help = format!("Length of the derived result (must be greater than {} and less than or equal to {})", MIN_KDF_LEN - 1, MAX_KDF_LEN))] + length: u8, }, #[command(about = "Print test vectors")] @@ -111,7 +111,7 @@ fn main() { log_n, r, p, - l, + length, }) => { println!( "Parameters: {} (log_n: {}, r: {}, p: {}, len: {})\n", @@ -119,7 +119,7 @@ fn main() { log_n.to_string().cyan(), r.to_string().cyan(), p.to_string().cyan(), - l.to_string().cyan(), + length.to_string().cyan(), ); let salt = get_salt(); @@ -136,7 +136,7 @@ fn main() { log_n: *log_n, r: *r, p: *p, - len: *l, + len: *length, iterations: *iterations, }; let kdf = ScryptKDF::new(&opts); diff --git a/src/scrypt_kdf.rs b/src/scrypt_kdf.rs index 0ace7aa..981f158 100755 --- a/src/scrypt_kdf.rs +++ b/src/scrypt_kdf.rs @@ -6,7 +6,7 @@ pub struct ScryptKDFOptions { pub r: u32, pub p: u32, pub iterations: u32, - pub len: usize, + pub len: u8, } #[derive(PartialEq, Debug)] @@ -49,7 +49,8 @@ pub const TEST_VECTORS: &[&TestScryptKDFOptions] = &[ }, ]; -pub const MAX_KDF_LEN: usize = 64; +pub const MIN_KDF_LEN: u8 = 10; +pub const MAX_KDF_LEN: u8 = 64; pub struct ScryptKDF<'a> { opts: &'a ScryptKDFOptions, @@ -57,6 +58,10 @@ pub struct ScryptKDF<'a> { impl<'a> ScryptKDF<'a> { pub fn new(opts: &'a ScryptKDFOptions) -> Self { + if opts.len < MIN_KDF_LEN { + panic!("length {} is lower than the min length of {MIN_KDF_LEN}", opts.len); + } + if opts.len > MAX_KDF_LEN { panic!("length {} is greater than the max length of {MAX_KDF_LEN}", opts.len); } @@ -65,7 +70,7 @@ impl<'a> ScryptKDF<'a> { } fn derive(&self, salt: &[u8], secret: &[u8]) -> Vec { - let mut dk = vec![0; self.opts.len]; + let mut dk = vec![0; self.opts.len as usize]; scrypt( secret,