bsv_wasm/kdf/
pbkdf2_kdf.rs

1use crate::{hash::Hash, KDF};
2use hmac::Hmac;
3use pbkdf2::{password_hash::SaltString, pbkdf2};
4use rand_core::OsRng;
5use sha1::Sha1;
6use sha2::{Sha256, Sha512};
7#[cfg(target_arch = "wasm32")]
8use wasm_bindgen::prelude::*;
9
10#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-kdf"), wasm_bindgen)]
11#[derive(Debug, Clone, Copy)]
12pub enum PBKDF2Hashes {
13    SHA1,
14    SHA256,
15    SHA512,
16}
17
18impl KDF {
19    /**
20     *
21     */
22    pub fn pbkdf2_impl(password: &[u8], salt: &[u8], hash_algo: PBKDF2Hashes, rounds: u32, output_length: usize) -> KDF {
23        let pbkdf2_fn = match hash_algo {
24            PBKDF2Hashes::SHA1 => pbkdf2::<Hmac<Sha1>>,
25            PBKDF2Hashes::SHA256 => pbkdf2::<Hmac<Sha256>>,
26            PBKDF2Hashes::SHA512 => pbkdf2::<Hmac<Sha512>>,
27        };
28        let mut result = vec![0; output_length];
29        pbkdf2_fn(password, salt, rounds, &mut result);
30
31        KDF {
32            hash: Hash(result),
33            salt: salt.to_vec(),
34        }
35    }
36
37    pub fn pbkdf2_random_salt_impl(password: &[u8], hash_algo: PBKDF2Hashes, rounds: u32, output_length: usize) -> KDF {
38        let salt = SaltString::generate(&mut OsRng);
39        KDF::pbkdf2_impl(password, salt.as_bytes(), hash_algo, rounds, output_length)
40    }
41}
42
43#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-kdf"), wasm_bindgen)]
44impl KDF {
45    /**
46     * Implementation of PBKDF2 - when None is specified for salt, a random salt will be generated
47     */
48    pub fn pbkdf2(password: &[u8], salt: Option<Vec<u8>>, hash_algo: PBKDF2Hashes, rounds: u32, output_length: usize) -> KDF {
49        match salt {
50            Some(s) => KDF::pbkdf2_impl(password, &s, hash_algo, rounds, output_length),
51            None => KDF::pbkdf2_random_salt_impl(password, hash_algo, rounds, output_length),
52        }
53    }
54}