hmip20/
rand.rs

1use rand_chacha::ChaChaRng;
2use rand_core::{RngCore, SeedableRng};
3
4use sha2::{Digest, Sha256};
5
6pub fn sha_256(data: &[u8]) -> [u8; 32]{
7    let mut hasher = Sha256::new();
8    hasher.update(data);
9    let hash = hasher.finalize();
10
11    let mut result = [0u8; 32];
12    result.copy_from_slice(hash.as_slice());
13    result
14}
15
16pub struct Prng {
17    rng: ChaChaRng,
18}
19
20impl Prng {
21    pub fn new(seed: &[u8], entropy: &[u8]) -> Self {
22        let mut hasher = Sha256::new();
23
24        // write input message
25        hasher.update(&seed);
26        hasher.update(&entropy);
27        let hash = hasher.finalize();
28
29        let mut hash_bytes = [0u8; 32];
30        hash_bytes.copy_from_slice(hash.as_slice());
31
32        let rng: ChaChaRng = ChaChaRng::from_seed(hash_bytes);
33
34        Self { rng }
35    }
36
37    pub fn rand_bytes(&mut self) -> [u8; 32] {
38        let mut bytes = [0u8; 32];
39        self.rng.fill_bytes(&mut bytes);
40
41        bytes
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    /// This test checks that the rng is stateful and generates
50    /// different random bytes every time it is called.
51    #[test]
52    fn test_rng() {
53        let mut rng = Prng::new(b"foo", b"bar!");
54        let r1: [u8; 32] = [
55            155, 11, 21, 97, 252, 65, 160, 190, 100, 126, 85, 251, 47, 73, 160, 49, 216, 182, 93,
56            30, 185, 67, 166, 22, 34, 10, 213, 112, 21, 136, 49, 214,
57        ];
58        let r2: [u8; 32] = [
59            46, 135, 19, 242, 111, 125, 59, 215, 114, 130, 122, 155, 202, 23, 36, 118, 83, 11, 6,
60            180, 97, 165, 218, 136, 134, 243, 191, 191, 149, 178, 7, 149,
61        ];
62        let r3: [u8; 32] = [
63            9, 2, 131, 50, 199, 170, 6, 68, 168, 28, 242, 182, 35, 114, 15, 163, 65, 139, 101, 221,
64            207, 147, 119, 110, 81, 195, 6, 134, 14, 253, 245, 244,
65        ];
66        let r4: [u8; 32] = [
67            68, 196, 114, 205, 225, 64, 201, 179, 18, 77, 216, 197, 211, 13, 21, 196, 11, 102, 106,
68            195, 138, 250, 29, 185, 51, 38, 183, 0, 5, 169, 65, 190,
69        ];
70        assert_eq!(r1, rng.rand_bytes());
71        assert_eq!(r2, rng.rand_bytes());
72        assert_eq!(r3, rng.rand_bytes());
73        assert_eq!(r4, rng.rand_bytes());
74    }
75}
76