extern crate argon2;
extern crate hmac;
extern crate secrecy;
extern crate sha2;
use argon2::{Argon2, Params, Version};
use hkdf::Hkdf as HkdfWrapper;
use hmac::{digest::MacError, Hmac as HmacWrapper, Mac};
use secrecy::{ExposeSecret, Secret};
use sha2::{Digest, Sha256};
pub struct Hash {}
impl Hash {
pub fn sha256(message: &Vec<u8>) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(message);
hasher.finalize().to_vec()
}
}
pub struct PasswordHash {}
impl PasswordHash {
pub fn argon2(
algorithm: argon2::Algorithm,
params: argon2::Params,
password: Secret<String>,
salt: &[u8],
) -> Secret<Vec<u8>> {
let mut key_material: [u8; 32] = [0u8; 32];
Argon2::new(algorithm, Version::default(), params)
.hash_password_into(password.expose_secret().as_bytes(), salt, &mut key_material)
.unwrap();
Secret::new(key_material.to_vec())
}
pub fn argon2d(
password: Secret<String>,
salt: &[u8],
iterations: u8,
threads: u8,
memory: u32,
) -> Secret<Vec<u8>> {
let params: argon2::Params =
argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
.expect("cannot build argon2 params");
PasswordHash::argon2(argon2::Algorithm::Argon2d, params, password, salt)
}
pub fn argon2id(
password: Secret<String>,
salt: &[u8],
iterations: u8,
threads: u8,
memory: u32,
) -> Secret<Vec<u8>> {
let params: argon2::Params =
argon2::Params::new(memory, iterations.into(), threads.into(), Some(32))
.expect("cannot build argon2 params");
PasswordHash::argon2(argon2::Algorithm::Argon2id, params, password, salt)
}
}
pub struct Hkdf {}
impl Hkdf {
pub fn expand(input_key_material: Secret<Vec<u8>>) -> Secret<Vec<u8>> {
let mut okm: [u8; 64] = [0u8; 64];
let info = vec![0xde, 0xad, 0xb0, 0x1d];
let hk = HkdfWrapper::<Sha256>::from_prk(input_key_material.expose_secret())
.expect("PRK should be large enough");
hk.expand(&info, &mut okm).unwrap();
Secret::new(okm.to_vec())
}
}
pub struct Hmac {
mac: HmacWrapper<Sha256>,
}
impl Hmac {
pub fn new(secret: &Secret<Vec<u8>>) -> Hmac {
type HmacSha256 = HmacWrapper<Sha256>;
Hmac {
mac: HmacSha256::new_from_slice(secret.expose_secret()).unwrap(),
}
}
pub fn update(&mut self, message: &[u8]) {
self.mac.update(message);
}
pub fn finalize(&mut self) -> Vec<u8> {
let result = self.mac.clone();
result.finalize().into_bytes().to_vec()
}
pub fn verify(&mut self, expected: &[u8]) -> Result<(), MacError> {
let result = self.mac.clone();
result.verify_slice(expected)
}
}