1use std::mem;
13
14use aes::{
15 Aes128,
16 cipher::{BlockCipherEncrypt, KeyInit},
17};
18use rand::{RngExt, SeedableRng};
19use rand_core::{
20 TryCryptoRng, TryRng,
21 block::{BlockRng, Generator},
22};
23
24use crate::{AES_PAR_BLOCKS, Block};
25
26#[derive(Clone, Debug)]
32pub struct AesRng(BlockRng<AesRngCore>);
33
34impl TryRng for AesRng {
35 type Error = core::convert::Infallible;
36
37 #[inline]
38 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
39 Ok(self.0.next_word())
40 }
41
42 #[inline]
43 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
44 Ok(self.0.next_u64_from_u32())
45 }
46
47 #[inline]
48 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
49 let block_size = mem::size_of::<aes::Block>();
50 let block_len = dest.len() / block_size * block_size;
51 let (block_bytes, rest_bytes) = dest.split_at_mut(block_len);
52 let blocks = bytemuck::cast_slice_mut::<_, aes::Block>(block_bytes);
55 for chunk in blocks.chunks_mut(AES_PAR_BLOCKS) {
56 for block in chunk.iter_mut() {
57 *block = aes::cipher::Array(self.0.core.state.to_le_bytes());
58 self.0.core.state += 1;
59 }
60 self.0.core.aes.encrypt_blocks(chunk);
61 }
62 self.0.fill_bytes(rest_bytes);
64 Ok(())
65 }
66}
67
68impl SeedableRng for AesRng {
69 type Seed = Block;
70
71 #[inline]
72 fn from_seed(seed: Self::Seed) -> Self {
73 AesRng(BlockRng::new(AesRngCore::from_seed(seed)))
74 }
75}
76
77impl TryCryptoRng for AesRng {}
78
79impl AesRng {
80 #[inline]
83 pub fn new() -> Self {
84 let seed = rand::random::<Block>();
85 AesRng::from_seed(seed)
86 }
87
88 #[inline]
90 pub fn fork(&mut self) -> Self {
91 let seed = self.random::<Block>();
92 AesRng::from_seed(seed)
93 }
94}
95
96impl Default for AesRng {
97 #[inline]
98 fn default() -> Self {
99 Self::new()
100 }
101}
102
103#[derive(Clone)]
105pub struct AesRngCore {
106 aes: Aes128,
107 state: u128,
108}
109
110impl std::fmt::Debug for AesRngCore {
111 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112 write!(f, "AesRngCore {{}}")
113 }
114}
115
116impl Generator for AesRngCore {
117 type Output = [u32; AES_PAR_BLOCKS * (mem::size_of::<aes::Block>() / mem::size_of::<u32>())];
119
120 #[inline]
122 fn generate(&mut self, results: &mut Self::Output) {
123 let blocks = bytemuck::cast_slice_mut::<_, aes::Block>(results);
124 blocks.iter_mut().for_each(|blk| {
125 *blk = aes::cipher::Array(self.state.to_le_bytes());
128 self.state += 1;
129 });
130 self.aes.encrypt_blocks(blocks);
131 }
132}
133
134impl SeedableRng for AesRngCore {
135 type Seed = Block;
136
137 #[inline]
138 fn from_seed(seed: Self::Seed) -> Self {
139 let aes = Aes128::new(&seed.into());
140 AesRngCore {
141 aes,
142 state: Default::default(),
143 }
144 }
145}
146
147impl From<AesRngCore> for AesRng {
148 #[inline]
149 fn from(core: AesRngCore) -> Self {
150 AesRng(BlockRng::new(core))
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn test_generate() {
160 let mut rng = AesRng::new();
161 let a = rng.random::<[Block; 8]>();
162 let b = rng.random::<[Block; 8]>();
163 assert_ne!(a, b);
164 }
165}