1pub mod aes;
12pub mod digest;
13pub mod error;
14pub mod hmac;
15pub mod pbkdf2;
16#[cfg(feature = "publickey")]
17pub mod publickey;
18pub mod scrypt;
19
20pub use crate::error::Error;
21
22use subtle::ConstantTimeEq;
23use tiny_keccak::{Hasher, Keccak};
24
25pub const KEY_LENGTH: usize = 32;
26pub const KEY_ITERATIONS: usize = 10240;
27pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2;
28
29pub const DEFAULT_MAC: [u8; 2] = [0, 0];
31
32pub trait Keccak256<T> {
33 fn keccak256(&self) -> T
34 where
35 T: Sized;
36}
37
38impl<T> Keccak256<[u8; 32]> for T
39where
40 T: AsRef<[u8]>,
41{
42 fn keccak256(&self) -> [u8; 32] {
43 let mut keccak = Keccak::v256();
44 let mut result = [0u8; 32];
45 keccak.update(self.as_ref());
46 keccak.finalize(&mut result);
47 result
48 }
49}
50
51pub fn derive_key_iterations(password: &[u8], salt: &[u8], c: u32) -> (Vec<u8>, Vec<u8>) {
52 let mut derived_key = [0u8; KEY_LENGTH];
53 pbkdf2::sha256(c, pbkdf2::Salt(salt), pbkdf2::Secret(password), &mut derived_key);
54 let derived_right_bits = &derived_key[0..KEY_LENGTH_AES];
55 let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH];
56 (derived_right_bits.to_vec(), derived_left_bits.to_vec())
57}
58
59pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec<u8> {
60 let mut mac = vec![0u8; KEY_LENGTH_AES + cipher_text.len()];
61 mac[0..KEY_LENGTH_AES].copy_from_slice(derived_left_bits);
62 mac[KEY_LENGTH_AES..cipher_text.len() + KEY_LENGTH_AES].copy_from_slice(cipher_text);
63 mac
64}
65
66pub fn is_equal(a: &[u8], b: &[u8]) -> bool {
67 a.ct_eq(b).into()
68}
69
70#[cfg(test)]
71mod test {
72 use super::*;
73
74 #[test]
75 fn can_test_for_equality() {
76 let a = b"abc";
77 let b = b"abc";
78 let c = b"efg";
79 assert!(is_equal(a, b));
80 assert!(!is_equal(a, c));
81 }
82}