1919/// Re-export the particular version of the `rand` crate whose types appear in the API.
2020pub use rand;
2121
22+ use lazy_static:: lazy_static;
2223use 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+ }
2337
2438/// Trait that encapsulates the required traits that a generator instance
2539/// must implement.
@@ -29,9 +43,32 @@ pub trait Generator: rand::RngCore + rand::CryptoRng {}
2943/// suitable as a Tink [`Generator`].
3044impl < T > Generator for T where T : rand:: RngCore + rand:: CryptoRng { }
3145
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+
3268/// Return a random number generator suitable for cryptographic operation.
3369pub fn rng ( ) -> Box < dyn Generator > {
34- Box :: new ( rand:: thread_rng ( ) )
70+ let factory = RNG_FACTORY . read ( ) . unwrap ( ) ; // safe: lock
71+ factory ( )
3572}
3673
3774/// Return a vector of the given `size` filled with random bytes.
0 commit comments