19
19
/// Re-export the particular version of the `rand` crate whose types appear in the API.
20
20
pub use rand;
21
21
22
+ use lazy_static:: lazy_static;
22
23
use rand:: Rng ;
24
+ use std:: sync:: RwLock ;
25
+
26
+ /// Possible factory functions for producing [`Generator`] instances.
27
+ pub enum Factory {
28
+ ThreadRng ,
29
+ OsRng ,
30
+ User ( fn ( ) -> Box < dyn Generator > ) ,
31
+ }
32
+
33
+ lazy_static ! {
34
+ /// Global factory that produces [`Generator`] instances.
35
+ static ref RNG_FACTORY : RwLock <fn ( ) -> Box <dyn Generator >> = RwLock :: new( thread_rng_factory) ;
36
+ }
23
37
24
38
/// Trait that encapsulates the required traits that a generator instance
25
39
/// must implement.
@@ -29,9 +43,32 @@ pub trait Generator: rand::RngCore + rand::CryptoRng {}
29
43
/// suitable as a Tink [`Generator`].
30
44
impl < T > Generator for T where T : rand:: RngCore + rand:: CryptoRng { }
31
45
46
+ /// Factory function that produces [`rand::rngs::ThreadRng`] instances.
47
+ fn thread_rng_factory ( ) -> Box < dyn Generator > {
48
+ // Available if `rand` has feature `std` enabled.
49
+ Box :: new ( rand:: thread_rng ( ) )
50
+ }
51
+
52
+ /// Factory function that produces [`rand::rngs::OsRng`] instances.
53
+ fn os_rng_factory ( ) -> Box < dyn Generator > {
54
+ // Available if `rand` has feature `getrandom` enabled.
55
+ Box :: new ( rand:: rngs:: OsRng )
56
+ }
57
+
58
+ /// Set the global factory that produces [`Generator`] instances.
59
+ pub fn set_factory ( factory : Factory ) {
60
+ let mut global = RNG_FACTORY . write ( ) . unwrap ( ) ; // safe: lock
61
+ * global = match factory {
62
+ Factory :: ThreadRng => thread_rng_factory,
63
+ Factory :: OsRng => os_rng_factory,
64
+ Factory :: User ( f) => f,
65
+ } ;
66
+ }
67
+
32
68
/// Return a random number generator suitable for cryptographic operation.
33
69
pub fn rng ( ) -> Box < dyn Generator > {
34
- Box :: new ( rand:: thread_rng ( ) )
70
+ let factory = RNG_FACTORY . read ( ) . unwrap ( ) ; // safe: lock
71
+ factory ( )
35
72
}
36
73
37
74
/// Return a vector of the given `size` filled with random bytes.
0 commit comments