1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use aes::cipher::{NewCipher, StreamCipher};
use aes::Aes128Ctr;
use digest::generic_array::{ArrayLength, GenericArray};
use digest::{BlockInput, FixedOutput, Reset, Update};
use hmac::{crypto_mac, Hmac, Mac, NewMac};
pub mod keys;
pub use keys::*;
pub const STREAM_CIPHER_KEY_SIZE: usize = 16;
pub const STREAM_CIPHER_INIT_VECTOR: [u8; 16] = [0u8; 16];
pub type HmacOutput<D> = crypto_mac::Output<Hmac<D>>;
pub fn generate_pseudorandom_bytes(
key: &[u8; STREAM_CIPHER_KEY_SIZE],
iv: &[u8; STREAM_CIPHER_KEY_SIZE],
length: usize,
) -> Vec<u8> {
let cipher_key = GenericArray::from_slice(&key[..]);
let cipher_nonce = GenericArray::from_slice(&iv[..]);
let mut cipher = Aes128Ctr::new(cipher_key, cipher_nonce);
let mut data = vec![0u8; length];
cipher.apply_keystream(&mut data);
data
}
pub fn compute_keyed_hmac<D>(key: &[u8], data: &[u8]) -> HmacOutput<D>
where
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
D::BlockSize: ArrayLength<u8>,
D::OutputSize: ArrayLength<u8>,
{
let mut hmac =
Hmac::<D>::new_from_slice(key).expect("HMAC should be able to take key of any size!");
hmac.update(data);
hmac.finalize()
}
#[cfg(test)]
mod generating_pseudorandom_bytes {
use super::*;
#[test]
fn it_generates_output_of_size_10000() {
let key: [u8; STREAM_CIPHER_KEY_SIZE] =
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
let iv: [u8; STREAM_CIPHER_KEY_SIZE] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let rand_bytes = generate_pseudorandom_bytes(&key, &iv, 10000);
assert_eq!(10000, rand_bytes.len());
}
}