1#![doc = include_str!("../README.md")]
3
4pub mod error;
5pub mod seed;
6pub mod wrap;
7
8pub use argon2::Error;
9use std::ops::Deref;
10pub use zeroize::Zeroizing;
11
12use argon2::Argon2;
13
14pub struct Input {
18 passphrase: Zeroizing<Vec<u8>>,
19 salt: Zeroizing<Vec<u8>>,
20}
21
22impl Input {
23 pub fn new(pwd: impl AsRef<[u8]>, salt: impl AsRef<[u8]>) -> Self {
25 Self {
26 passphrase: Zeroizing::new(pwd.as_ref().to_vec()),
27 salt: Zeroizing::new(salt.as_ref().to_vec()),
28 }
29 }
30
31 pub fn derive_key(&self) -> Result<Zeroizing<[u8; 32]>, Error> {
40 let mut output_key_material = Zeroizing::new([0u8; 32]);
41 Argon2::default().hash_password_into(
42 self.passphrase.deref(),
43 self.salt.deref(),
44 &mut *output_key_material,
45 )?;
46
47 Ok(output_key_material)
48 }
49}
50
51pub fn derive_key(
59 pwd: impl AsRef<[u8]>,
60 salt: impl AsRef<[u8]>,
61) -> Result<Zeroizing<[u8; 32]>, Error> {
62 let mut output_key_material = Zeroizing::new([0u8; 32]); Argon2::default().hash_password_into(pwd.as_ref(), salt.as_ref(), &mut *output_key_material)?;
65
66 Ok(output_key_material)
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use seed::Seed;
73
74 #[test]
75 fn it_works() -> Result<(), Error> {
76 let salt = b"some@email.com"; let password = b"some random words that you made up, for sure!";
78
79 let mut output_key_material_1 = Seed::new(Zeroizing::new([0u8; 32]));
80 let mut output_key_material_2 = Seed::default(); let mut output_key_material_3: Vec<u8> = vec![0; 48]; Argon2::default().hash_password_into(password, salt, &mut output_key_material_1)?;
84 Argon2::default().hash_password_into(password, salt, &mut output_key_material_2)?;
85 Argon2::default().hash_password_into(password, salt, &mut output_key_material_3)?;
86
87 assert_eq!(output_key_material_1, output_key_material_2);
88
89 drop(output_key_material_1);
90 drop(output_key_material_2);
91 drop(output_key_material_3);
92
93 Ok(())
94 }
95
96 #[test]
97 fn api_works() -> Result<(), Error> {
98 let password = "some random words that you made up, for sure!".to_string();
99 let salt = b"some@email.com"; let input = Input::new(&password, salt);
102
103 let seed = input.derive_key()?;
104
105 assert_eq!(
106 seed.as_ref(),
107 [
108 164, 103, 254, 113, 126, 241, 57, 240, 100, 56, 243, 125, 155, 224, 40, 242, 178,
109 136, 222, 133, 220, 141, 127, 10, 88, 199, 181, 11, 241, 91, 149, 249
110 ]
111 );
112
113 println!("Seed {:?}", seed);
115
116 let seed = derive_key(password, salt)?;
118
119 assert_eq!(
120 seed.as_ref(),
121 [
122 164, 103, 254, 113, 126, 241, 57, 240, 100, 56, 243, 125, 155, 224, 40, 242, 178,
123 136, 222, 133, 220, 141, 127, 10, 88, 199, 181, 11, 241, 91, 149, 249
124 ]
125 );
126
127 Ok(())
128 }
129}