#![doc = include_str!("../README.md")]
pub mod seed;
pub mod wrap;
pub use argon2::Error;
pub use secrecy::zeroize::Zeroizing;
pub use secrecy::{ExposeSecret, Secret, SecretBytesMut};
use argon2::Argon2;
use seed::Seed;
pub struct Input {
passphrase: Secret<Vec<u8>>,
salt: Secret<Vec<u8>>,
}
impl Input {
pub fn new(pwd: impl AsRef<[u8]>, salt: impl AsRef<[u8]>) -> Self {
Self {
passphrase: Secret::new(pwd.as_ref().to_vec()),
salt: Secret::new(salt.as_ref().to_vec()),
}
}
pub fn derive_key(&self) -> Result<Secret<Seed>, Error> {
let mut output_key_material = Zeroizing::new([0u8; 32]);
Argon2::default().hash_password_into(
self.passphrase.expose_secret(),
self.salt.expose_secret(),
&mut *output_key_material,
)?;
Ok(Secret::new(Seed::new(output_key_material)))
}
}
pub fn derive_key(pwd: impl AsRef<[u8]>, salt: impl AsRef<[u8]>) -> Result<Secret<Seed>, Error> {
let mut output_key_material = Zeroizing::new([0u8; 32]); Argon2::default().hash_password_into(pwd.as_ref(), salt.as_ref(), &mut *output_key_material)?;
Ok(Secret::new(Seed::new(output_key_material)))
}
#[cfg(test)]
mod tests {
use super::*;
use secrecy::DebugSecret;
impl DebugSecret for Seed {}
#[test]
fn it_works() -> Result<(), Error> {
let salt = b"some@email.com"; let password = b"some random words that you made up, for sure!";
let mut output_key_material_1 = Seed::new(Zeroizing::new([0u8; 32]));
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)?;
Argon2::default().hash_password_into(password, salt, &mut output_key_material_2)?;
Argon2::default().hash_password_into(password, salt, &mut output_key_material_3)?;
assert_eq!(output_key_material_1, output_key_material_2);
drop(output_key_material_1);
drop(output_key_material_2);
drop(output_key_material_3);
Ok(())
}
#[test]
fn api_works() -> Result<(), Error> {
let password = "some random words that you made up, for sure!".to_string();
let salt = b"some@email.com"; let input = Input::new(&password, salt);
let seed = input.derive_key()?;
assert_eq!(
**seed.expose_secret(),
[
164, 103, 254, 113, 126, 241, 57, 240, 100, 56, 243, 125, 155, 224, 40, 242, 178,
136, 222, 133, 220, 141, 127, 10, 88, 199, 181, 11, 241, 91, 149, 249
]
);
println!("Seed {:?}", seed);
let seed = derive_key(password, salt)?;
assert_eq!(
**seed.expose_secret(),
[
164, 103, 254, 113, 126, 241, 57, 240, 100, 56, 243, 125, 155, 224, 40, 242, 178,
136, 222, 133, 220, 141, 127, 10, 88, 199, 181, 11, 241, 91, 149, 249
]
);
Ok(())
}
}