Skip to main content

tfhe_csprng/generators/implem/aesni/
generator.rs

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