tfhe_csprng/generators/implem/aesni/
generator.rs

1use crate::generators::aes_ctr::{AesCtrGenerator, ChildrenIterator};
2use crate::generators::implem::aesni::block_cipher::AesniBlockCipher;
3use crate::generators::{ByteCount, BytesPerChild, ChildrenCount, ForkError, RandomGenerator};
4use crate::seeders::SeedKind;
5
6/// A random number generator using the `aesni` instructions.
7pub struct AesniRandomGenerator(pub(super) AesCtrGenerator<AesniBlockCipher>);
8
9/// The children iterator used by [`AesniRandomGenerator`].
10///
11/// Outputs children generators one by one.
12pub struct AesniChildrenIterator(ChildrenIterator<AesniBlockCipher>);
13
14impl Iterator for AesniChildrenIterator {
15    type Item = AesniRandomGenerator;
16
17    fn next(&mut self) -> Option<Self::Item> {
18        self.0.next().map(AesniRandomGenerator)
19    }
20}
21
22impl RandomGenerator for AesniRandomGenerator {
23    type ChildrenIter = AesniChildrenIterator;
24    fn new(seed: impl Into<SeedKind>) -> Self {
25        AesniRandomGenerator(AesCtrGenerator::from_seed(seed))
26    }
27    fn remaining_bytes(&self) -> ByteCount {
28        self.0.remaining_bytes()
29    }
30    fn try_fork(
31        &mut self,
32        n_children: ChildrenCount,
33        n_bytes: BytesPerChild,
34    ) -> Result<Self::ChildrenIter, ForkError> {
35        self.0
36            .try_fork(n_children, n_bytes)
37            .map(AesniChildrenIterator)
38    }
39}
40
41impl Iterator for AesniRandomGenerator {
42    type Item = u8;
43
44    fn next(&mut self) -> Option<Self::Item> {
45        self.0.next()
46    }
47}
48
49#[cfg(test)]
50mod test {
51    use crate::generators::aes_ctr::aes_ctr_generic_test;
52    use crate::generators::implem::aesni::block_cipher::AesniBlockCipher;
53    use crate::generators::{generator_generic_test, AesniRandomGenerator};
54
55    #[test]
56    fn prop_fork_first_state_table_index() {
57        aes_ctr_generic_test::prop_fork_first_state_table_index::<AesniBlockCipher>();
58    }
59
60    #[test]
61    fn prop_fork_last_bound_table_index() {
62        aes_ctr_generic_test::prop_fork_last_bound_table_index::<AesniBlockCipher>();
63    }
64
65    #[test]
66    fn prop_fork_parent_bound_table_index() {
67        aes_ctr_generic_test::prop_fork_parent_bound_table_index::<AesniBlockCipher>();
68    }
69
70    #[test]
71    fn prop_fork_parent_state_table_index() {
72        aes_ctr_generic_test::prop_fork_parent_state_table_index::<AesniBlockCipher>();
73    }
74
75    #[test]
76    fn prop_fork() {
77        aes_ctr_generic_test::prop_fork::<AesniBlockCipher>();
78    }
79
80    #[test]
81    fn prop_fork_children_remaining_bytes() {
82        aes_ctr_generic_test::prop_fork_children_remaining_bytes::<AesniBlockCipher>();
83    }
84
85    #[test]
86    fn prop_fork_parent_remaining_bytes() {
87        aes_ctr_generic_test::prop_fork_parent_remaining_bytes::<AesniBlockCipher>();
88    }
89
90    #[test]
91    fn test_roughly_uniform() {
92        generator_generic_test::test_roughly_uniform::<AesniRandomGenerator>();
93    }
94
95    #[test]
96    fn test_generator_determinism() {
97        generator_generic_test::test_generator_determinism::<AesniRandomGenerator>();
98    }
99
100    #[test]
101    fn test_fork() {
102        generator_generic_test::test_fork_children::<AesniRandomGenerator>();
103    }
104
105    #[test]
106    #[should_panic(expected = "expected test panic")]
107    fn test_bounded_panic() {
108        generator_generic_test::test_bounded_none_should_panic::<AesniRandomGenerator>();
109    }
110
111    #[test]
112    fn test_vector() {
113        generator_generic_test::test_vectors::<AesniRandomGenerator>();
114    }
115
116    #[test]
117    fn test_vector_xof_seed() {
118        generator_generic_test::test_vectors_xof_seed::<AesniRandomGenerator>();
119    }
120
121    #[test]
122    fn test_vector_xof_seed_bytes() {
123        generator_generic_test::test_vectors_xof_seed_bytes::<AesniRandomGenerator>();
124    }
125}