Skip to main content

prople_crypto/passphrase/
mod.rs

1//! `passphrase` is a module used to hash a given secret passphrase or a `password`
2//!
3//! This hashed password will be used as secret key to encrypt and decrypt some critical
4//! information such as for encrypted `Private Key`
5pub mod kdf_params;
6pub mod salt;
7pub mod types;
8
9use rst_common::with_cryptography::argon2::{Algorithm, Argon2, Params, Version};
10
11use kdf_params::KdfParams;
12use types::errors::PassphraseError;
13use types::{KeyBytesRange, SaltBytes};
14
15use crate::types::Value;
16
17/// `Passphrase` used to hash given input password used to
18/// encrypt the private keys and depends to [`KdfParams`]
19pub struct Passphrase {
20    params: KdfParams,
21}
22
23impl Passphrase {
24    pub fn new(params: KdfParams) -> Self {
25        Self { params }
26    }
27
28    // `hash` will hash given password using `Argon2` based on generated salt too
29    pub fn hash(
30        &self,
31        password: String,
32        salt: SaltBytes,
33    ) -> Result<KeyBytesRange, PassphraseError> {
34        let argon_params = Params::new(
35            self.params.m_cost,
36            self.params.t_cost,
37            self.params.p_cost,
38            Some(self.params.output_len),
39        )
40        .map_err(|err| PassphraseError::BuildParamsError(err.to_string()))?;
41
42        let mut output_key_material = [0u8; 32];
43        let argon = Argon2::new(Algorithm::default(), Version::default(), argon_params);
44
45        let salt_bytes_val = salt
46            .get()
47            .map_err(|err| PassphraseError::ParseSaltError(err.to_string()))?;
48
49        argon
50            .hash_password_into(
51                password.as_bytes(),
52                salt_bytes_val.as_slice(),
53                &mut output_key_material,
54            )
55            .map(|_| output_key_material)
56            .map_err(|err| PassphraseError::HashPasswordError(err.to_string()))
57    }
58}
59
60/// `prelude` used to grouping all defined types and objects
61/// used to simplify the import operations.
62///
63/// This module will be usefull when we need to import all of defined object and types without need
64/// to import one by one
65pub mod prelude {
66    use super::*;
67
68    pub use crate::passphrase::Passphrase;
69    pub use kdf_params::KdfParams;
70    pub use salt::Salt;
71    pub use types::*;
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use rst_common::with_cryptography::hex;
78    use salt::Salt;
79
80    #[test]
81    fn test_hash() {
82        let params = KdfParams::default();
83
84        let salt = Salt::generate();
85        let salt_bytes_val = salt.get().unwrap();
86        let salt_to_string = String::from_utf8(salt_bytes_val.clone());
87        assert!(!salt_to_string.is_err());
88
89        let kdf = Passphrase::new(params.clone());
90        let try_hash = kdf.hash("rawatext".to_string(), salt.clone());
91        assert!(!try_hash.is_err());
92
93        let try_input = kdf.hash("rawatext".to_string(), salt.clone());
94        assert!(!try_input.is_err());
95
96        let hashed_hex = hex::encode(try_hash.unwrap());
97        let hashed_input = hex::encode(try_input.unwrap());
98        assert_eq!(hashed_hex, hashed_input);
99
100        let salt2 = Salt::generate();
101        let try_invalid = kdf.hash("rawatext".to_string(), salt2);
102        assert!(!try_invalid.is_err());
103
104        let hashed_invalid_hex = hex::encode(try_invalid.unwrap());
105        assert_ne!(hashed_hex, hashed_invalid_hex)
106    }
107
108    #[test]
109    fn test_generate_salt_from_vec() {
110        let salt = Salt::generate();
111        let salt_new = Salt::from_vec(salt);
112        assert!(!salt_new.is_err());
113    }
114}