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 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 #[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