tfhe_csprng/generators/implem/soft/
generator.rs

1use crate::generators::aes_ctr::{AesCtrGenerator, ChildrenIterator};
2use crate::generators::implem::soft::block_cipher::SoftwareBlockCipher;
3use crate::generators::{ByteCount, BytesPerChild, ChildrenCount, ForkError, RandomGenerator};
4use crate::seeders::SeedKind;
5
6/// A random number generator using a software implementation.
7pub struct SoftwareRandomGenerator(pub(super) AesCtrGenerator<SoftwareBlockCipher>);
8
9/// The children iterator used by [`SoftwareRandomGenerator`].
10///
11/// Outputs children generators one by one.
12pub struct SoftwareChildrenIterator(ChildrenIterator<SoftwareBlockCipher>);
13
14impl Iterator for SoftwareChildrenIterator {
15    type Item = SoftwareRandomGenerator;
16
17    fn next(&mut self) -> Option<Self::Item> {
18        self.0.next().map(SoftwareRandomGenerator)
19    }
20}
21
22impl RandomGenerator for SoftwareRandomGenerator {
23    type ChildrenIter = SoftwareChildrenIterator;
24    fn new(seed: impl Into<SeedKind>) -> Self {
25        SoftwareRandomGenerator(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(SoftwareChildrenIterator)
38    }
39}
40
41impl Iterator for SoftwareRandomGenerator {
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 super::*;
52    use crate::generators::aes_ctr::aes_ctr_generic_test;
53    use crate::generators::generator_generic_test;
54
55    // We use powerpc64 as the target to test behavior on big-endian
56    // However, we run these tests using an emulator. Thus, these get really slow
57    // so we skip them
58    #[cfg(not(target_arch = "powerpc64"))]
59    mod fork_tests {
60        use super::*;
61
62        #[test]
63        fn prop_fork_first_state_table_index() {
64            aes_ctr_generic_test::prop_fork_first_state_table_index::<SoftwareBlockCipher>();
65        }
66
67        #[test]
68        fn prop_fork_last_bound_table_index() {
69            aes_ctr_generic_test::prop_fork_last_bound_table_index::<SoftwareBlockCipher>();
70        }
71
72        #[test]
73        fn prop_fork_parent_bound_table_index() {
74            aes_ctr_generic_test::prop_fork_parent_bound_table_index::<SoftwareBlockCipher>();
75        }
76
77        #[test]
78        fn prop_fork_parent_state_table_index() {
79            aes_ctr_generic_test::prop_fork_parent_state_table_index::<SoftwareBlockCipher>();
80        }
81
82        #[test]
83        fn prop_fork() {
84            aes_ctr_generic_test::prop_fork::<SoftwareBlockCipher>();
85        }
86
87        #[test]
88        fn prop_fork_children_remaining_bytes() {
89            aes_ctr_generic_test::prop_fork_children_remaining_bytes::<SoftwareBlockCipher>();
90        }
91
92        #[test]
93        fn prop_fork_parent_remaining_bytes() {
94            aes_ctr_generic_test::prop_fork_parent_remaining_bytes::<SoftwareBlockCipher>();
95        }
96
97        #[test]
98        fn test_fork() {
99            generator_generic_test::test_fork_children::<SoftwareRandomGenerator>();
100        }
101
102        #[test]
103        fn test_roughly_uniform() {
104            generator_generic_test::test_roughly_uniform::<SoftwareRandomGenerator>();
105        }
106    }
107
108    #[test]
109    fn test_generator_determinism() {
110        generator_generic_test::test_generator_determinism::<SoftwareRandomGenerator>();
111    }
112
113    #[test]
114    #[should_panic(expected = "expected test panic")]
115    fn test_bounded_panic() {
116        generator_generic_test::test_bounded_none_should_panic::<SoftwareRandomGenerator>();
117    }
118
119    #[test]
120    fn test_vector() {
121        generator_generic_test::test_vectors::<SoftwareRandomGenerator>();
122    }
123
124    #[test]
125    fn test_vector_xof_seed() {
126        generator_generic_test::test_vectors_xof_seed::<SoftwareRandomGenerator>();
127    }
128
129    #[test]
130    fn test_vector_xof_seed_bytes() {
131        generator_generic_test::test_vectors_xof_seed_bytes::<SoftwareRandomGenerator>();
132    }
133}