From 369d11587339ce74f8ebc76f2607fe55545eaf7d Mon Sep 17 00:00:00 2001 From: garhve Date: Tue, 20 Dec 2022 11:04:25 +0800 Subject: Build small project following the book --- .../target/doc/src/rand/rngs/adapter/mod.rs.html | 35 + .../target/doc/src/rand/rngs/adapter/read.rs.html | 303 ++++++++ .../doc/src/rand/rngs/adapter/reseeding.rs.html | 775 +++++++++++++++++++++ .../target/doc/src/rand/rngs/mock.rs.html | 177 +++++ .../target/doc/src/rand/rngs/mod.rs.html | 241 +++++++ .../target/doc/src/rand/rngs/std.rs.html | 199 ++++++ .../target/doc/src/rand/rngs/thread.rs.html | 289 ++++++++ 7 files changed, 2019 insertions(+) create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/mod.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/read.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/reseeding.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mock.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mod.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/std.rs.html create mode 100644 rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/thread.rs.html (limited to 'rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs') diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/mod.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/mod.rs.html new file mode 100644 index 0000000..a272f93 --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/mod.rs.html @@ -0,0 +1,35 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Wrappers / adapters forming RNGs
+
+mod read;
+mod reseeding;
+
+#[allow(deprecated)]
+pub use self::read::{ReadError, ReadRng};
+pub use self::reseeding::ReseedingRng;
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/read.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/read.rs.html new file mode 100644 index 0000000..d16c0fb --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/read.rs.html @@ -0,0 +1,303 @@ +read.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+
// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around any Read to treat it as an RNG.
+
+#![allow(deprecated)]
+
+use std::fmt;
+use std::io::Read;
+
+use rand_core::{impls, Error, RngCore};
+
+
+/// An RNG that reads random bytes straight from any type supporting
+/// [`std::io::Read`], for example files.
+///
+/// This will work best with an infinite reader, but that is not required.
+///
+/// This can be used with `/dev/urandom` on Unix but it is recommended to use
+/// [`OsRng`] instead.
+///
+/// # Panics
+///
+/// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts.
+/// All other errors from the underlying reader, including when it does not
+/// have enough data, will only be reported through [`try_fill_bytes`].
+/// The other [`RngCore`] methods will panic in case of an error.
+///
+/// [`OsRng`]: crate::rngs::OsRng
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Debug)]
+#[deprecated(since="0.8.4", note="removal due to lack of usage")]
+pub struct ReadRng<R> {
+    reader: R,
+}
+
+impl<R: Read> ReadRng<R> {
+    /// Create a new `ReadRng` from a `Read`.
+    pub fn new(r: R) -> ReadRng<R> {
+        ReadRng { reader: r }
+    }
+}
+
+impl<R: Read> RngCore for ReadRng<R> {
+    fn next_u32(&mut self) -> u32 {
+        impls::next_u32_via_fill(self)
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        impls::next_u64_via_fill(self)
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.try_fill_bytes(dest).unwrap_or_else(|err| {
+            panic!(
+                "reading random bytes from Read implementation failed; error: {}",
+                err
+            )
+        });
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        if dest.is_empty() {
+            return Ok(());
+        }
+        // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`.
+        self.reader
+            .read_exact(dest)
+            .map_err(|e| Error::new(ReadError(e)))
+    }
+}
+
+/// `ReadRng` error type
+#[derive(Debug)]
+#[deprecated(since="0.8.4")]
+pub struct ReadError(std::io::Error);
+
+impl fmt::Display for ReadError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ReadError: {}", self.0)
+    }
+}
+
+impl std::error::Error for ReadError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        Some(&self.0)
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use std::println;
+
+    use super::ReadRng;
+    use crate::RngCore;
+
+    #[test]
+    fn test_reader_rng_u64() {
+        // transmute from the target to avoid endianness concerns.
+        #[rustfmt::skip]
+        let v = [0u8, 0, 0, 0, 0, 0, 0, 1,
+                 0,   4, 0, 0, 3, 0, 0, 2,
+                 5,   0, 0, 0, 0, 0, 0, 0];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u64(), 1 << 56);
+        assert_eq!(rng.next_u64(), (2 << 56) + (3 << 32) + (4 << 8));
+        assert_eq!(rng.next_u64(), 5);
+    }
+
+    #[test]
+    fn test_reader_rng_u32() {
+        let v = [0u8, 0, 0, 1, 0, 0, 2, 0, 3, 0, 0, 0];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u32(), 1 << 24);
+        assert_eq!(rng.next_u32(), 2 << 16);
+        assert_eq!(rng.next_u32(), 3);
+    }
+
+    #[test]
+    fn test_reader_rng_fill_bytes() {
+        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0u8; 8];
+
+        let mut rng = ReadRng::new(&v[..]);
+        rng.fill_bytes(&mut w);
+
+        assert!(v == w);
+    }
+
+    #[test]
+    fn test_reader_rng_insufficient_bytes() {
+        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0u8; 9];
+
+        let mut rng = ReadRng::new(&v[..]);
+
+        let result = rng.try_fill_bytes(&mut w);
+        assert!(result.is_err());
+        println!("Error: {}", result.unwrap_err());
+    }
+}
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/reseeding.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/reseeding.rs.html new file mode 100644 index 0000000..93f4eaf --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/adapter/reseeding.rs.html @@ -0,0 +1,775 @@ +reseeding.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+
// Copyright 2018 Developers of the Rand project.
+// Copyright 2013 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around another PRNG that reseeds it after it
+//! generates a certain number of random bytes.
+
+use core::mem::size_of;
+
+use rand_core::block::{BlockRng, BlockRngCore};
+use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
+
+/// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the
+/// ability to reseed it.
+///
+/// `ReseedingRng` reseeds the underlying PRNG in the following cases:
+///
+/// - On a manual call to [`reseed()`].
+/// - After `clone()`, the clone will be reseeded on first use.
+/// - When a process is forked on UNIX, the RNGs in both the parent and child
+///   processes will be reseeded just before the next call to
+///   [`BlockRngCore::generate`], i.e. "soon". For ChaCha and Hc128 this is a
+///   maximum of fifteen `u32` values before reseeding.
+/// - After the PRNG has generated a configurable number of random bytes.
+///
+/// # When should reseeding after a fixed number of generated bytes be used?
+///
+/// Reseeding after a fixed number of generated bytes is never strictly
+/// *necessary*. Cryptographic PRNGs don't have a limited number of bytes they
+/// can output, or at least not a limit reachable in any practical way. There is
+/// no such thing as 'running out of entropy'.
+///
+/// Occasionally reseeding can be seen as some form of 'security in depth'. Even
+/// if in the future a cryptographic weakness is found in the CSPRNG being used,
+/// or a flaw in the implementation, occasionally reseeding should make
+/// exploiting it much more difficult or even impossible.
+///
+/// Use [`ReseedingRng::new`] with a `threshold` of `0` to disable reseeding
+/// after a fixed number of generated bytes.
+///
+/// # Limitations
+///
+/// It is recommended that a `ReseedingRng` (including `ThreadRng`) not be used
+/// from a fork handler.
+/// Use `OsRng` or `getrandom`, or defer your use of the RNG until later.
+///
+/// # Error handling
+///
+/// Although unlikely, reseeding the wrapped PRNG can fail. `ReseedingRng` will
+/// never panic but try to handle the error intelligently through some
+/// combination of retrying and delaying reseeding until later.
+/// If handling the source error fails `ReseedingRng` will continue generating
+/// data from the wrapped PRNG without reseeding.
+///
+/// Manually calling [`reseed()`] will not have this retry or delay logic, but
+/// reports the error.
+///
+/// # Example
+///
+/// ```
+/// use rand::prelude::*;
+/// use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that
+///                              // implements BlockRngCore
+/// use rand::rngs::OsRng;
+/// use rand::rngs::adapter::ReseedingRng;
+///
+/// let prng = ChaCha20Core::from_entropy();
+/// let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
+///
+/// println!("{}", reseeding_rng.gen::<u64>());
+///
+/// let mut cloned_rng = reseeding_rng.clone();
+/// assert!(reseeding_rng.gen::<u64>() != cloned_rng.gen::<u64>());
+/// ```
+///
+/// [`BlockRngCore`]: rand_core::block::BlockRngCore
+/// [`ReseedingRng::new`]: ReseedingRng::new
+/// [`reseed()`]: ReseedingRng::reseed
+#[derive(Debug)]
+pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)
+where
+    R: BlockRngCore + SeedableRng,
+    Rsdr: RngCore;
+
+impl<R, Rsdr> ReseedingRng<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng,
+    Rsdr: RngCore,
+{
+    /// Create a new `ReseedingRng` from an existing PRNG, combined with a RNG
+    /// to use as reseeder.
+    ///
+    /// `threshold` sets the number of generated bytes after which to reseed the
+    /// PRNG. Set it to zero to never reseed based on the number of generated
+    /// values.
+    pub fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
+        ReseedingRng(BlockRng::new(ReseedingCore::new(rng, threshold, reseeder)))
+    }
+
+    /// Reseed the internal PRNG.
+    pub fn reseed(&mut self) -> Result<(), Error> {
+        self.0.core.reseed()
+    }
+}
+
+// TODO: this should be implemented for any type where the inner type
+// implements RngCore, but we can't specify that because ReseedingCore is private
+impl<R, Rsdr: RngCore> RngCore for ReseedingRng<R, Rsdr>
+where
+    R: BlockRngCore<Item = u32> + SeedableRng,
+    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>,
+{
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        self.0.next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        self.0.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.0.fill_bytes(dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.0.try_fill_bytes(dest)
+    }
+}
+
+impl<R, Rsdr> Clone for ReseedingRng<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng + Clone,
+    Rsdr: RngCore + Clone,
+{
+    fn clone(&self) -> ReseedingRng<R, Rsdr> {
+        // Recreating `BlockRng` seems easier than cloning it and resetting
+        // the index.
+        ReseedingRng(BlockRng::new(self.0.core.clone()))
+    }
+}
+
+impl<R, Rsdr> CryptoRng for ReseedingRng<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng + CryptoRng,
+    Rsdr: RngCore + CryptoRng,
+{
+}
+
+#[derive(Debug)]
+struct ReseedingCore<R, Rsdr> {
+    inner: R,
+    reseeder: Rsdr,
+    threshold: i64,
+    bytes_until_reseed: i64,
+    fork_counter: usize,
+}
+
+impl<R, Rsdr> BlockRngCore for ReseedingCore<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng,
+    Rsdr: RngCore,
+{
+    type Item = <R as BlockRngCore>::Item;
+    type Results = <R as BlockRngCore>::Results;
+
+    fn generate(&mut self, results: &mut Self::Results) {
+        let global_fork_counter = fork::get_fork_counter();
+        if self.bytes_until_reseed <= 0 || self.is_forked(global_fork_counter) {
+            // We get better performance by not calling only `reseed` here
+            // and continuing with the rest of the function, but by directly
+            // returning from a non-inlined function.
+            return self.reseed_and_generate(results, global_fork_counter);
+        }
+        let num_bytes = results.as_ref().len() * size_of::<Self::Item>();
+        self.bytes_until_reseed -= num_bytes as i64;
+        self.inner.generate(results);
+    }
+}
+
+impl<R, Rsdr> ReseedingCore<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng,
+    Rsdr: RngCore,
+{
+    /// Create a new `ReseedingCore`.
+    fn new(rng: R, threshold: u64, reseeder: Rsdr) -> Self {
+        use ::core::i64::MAX;
+        fork::register_fork_handler();
+
+        // Because generating more values than `i64::MAX` takes centuries on
+        // current hardware, we just clamp to that value.
+        // Also we set a threshold of 0, which indicates no limit, to that
+        // value.
+        let threshold = if threshold == 0 {
+            MAX
+        } else if threshold <= MAX as u64 {
+            threshold as i64
+        } else {
+            MAX
+        };
+
+        ReseedingCore {
+            inner: rng,
+            reseeder,
+            threshold: threshold as i64,
+            bytes_until_reseed: threshold as i64,
+            fork_counter: 0,
+        }
+    }
+
+    /// Reseed the internal PRNG.
+    fn reseed(&mut self) -> Result<(), Error> {
+        R::from_rng(&mut self.reseeder).map(|result| {
+            self.bytes_until_reseed = self.threshold;
+            self.inner = result
+        })
+    }
+
+    fn is_forked(&self, global_fork_counter: usize) -> bool {
+        // In theory, on 32-bit platforms, it is possible for
+        // `global_fork_counter` to wrap around after ~4e9 forks.
+        //
+        // This check will detect a fork in the normal case where
+        // `fork_counter < global_fork_counter`, and also when the difference
+        // between both is greater than `isize::MAX` (wrapped around).
+        //
+        // It will still fail to detect a fork if there have been more than
+        // `isize::MAX` forks, without any reseed in between. Seems unlikely
+        // enough.
+        (self.fork_counter.wrapping_sub(global_fork_counter) as isize) < 0
+    }
+
+    #[inline(never)]
+    fn reseed_and_generate(
+        &mut self, results: &mut <Self as BlockRngCore>::Results, global_fork_counter: usize,
+    ) {
+        #![allow(clippy::if_same_then_else)] // false positive
+        if self.is_forked(global_fork_counter) {
+            info!("Fork detected, reseeding RNG");
+        } else {
+            trace!("Reseeding RNG (periodic reseed)");
+        }
+
+        let num_bytes = results.as_ref().len() * size_of::<<R as BlockRngCore>::Item>();
+
+        if let Err(e) = self.reseed() {
+            warn!("Reseeding RNG failed: {}", e);
+            let _ = e;
+        }
+        self.fork_counter = global_fork_counter;
+
+        self.bytes_until_reseed = self.threshold - num_bytes as i64;
+        self.inner.generate(results);
+    }
+}
+
+impl<R, Rsdr> Clone for ReseedingCore<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng + Clone,
+    Rsdr: RngCore + Clone,
+{
+    fn clone(&self) -> ReseedingCore<R, Rsdr> {
+        ReseedingCore {
+            inner: self.inner.clone(),
+            reseeder: self.reseeder.clone(),
+            threshold: self.threshold,
+            bytes_until_reseed: 0, // reseed clone on first use
+            fork_counter: self.fork_counter,
+        }
+    }
+}
+
+impl<R, Rsdr> CryptoRng for ReseedingCore<R, Rsdr>
+where
+    R: BlockRngCore + SeedableRng + CryptoRng,
+    Rsdr: RngCore + CryptoRng,
+{
+}
+
+
+#[cfg(all(unix, not(target_os = "emscripten")))]
+mod fork {
+    use core::sync::atomic::{AtomicUsize, Ordering};
+    use std::sync::Once;
+
+    // Fork protection
+    //
+    // We implement fork protection on Unix using `pthread_atfork`.
+    // When the process is forked, we increment `RESEEDING_RNG_FORK_COUNTER`.
+    // Every `ReseedingRng` stores the last known value of the static in
+    // `fork_counter`. If the cached `fork_counter` is less than
+    // `RESEEDING_RNG_FORK_COUNTER`, it is time to reseed this RNG.
+    //
+    // If reseeding fails, we don't deal with this by setting a delay, but just
+    // don't update `fork_counter`, so a reseed is attempted as soon as
+    // possible.
+
+    static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    pub fn get_fork_counter() -> usize {
+        RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
+    }
+
+    extern "C" fn fork_handler() {
+        // Note: fetch_add is defined to wrap on overflow
+        // (which is what we want).
+        RESEEDING_RNG_FORK_COUNTER.fetch_add(1, Ordering::Relaxed);
+    }
+
+    pub fn register_fork_handler() {
+        static REGISTER: Once = Once::new();
+        REGISTER.call_once(|| {
+            // Bump the counter before and after forking (see #1169):
+            let ret = unsafe { libc::pthread_atfork(
+                Some(fork_handler),
+                Some(fork_handler),
+                Some(fork_handler),
+            ) };
+            if ret != 0 {
+                panic!("libc::pthread_atfork failed with code {}", ret);
+            }
+        });
+    }
+}
+
+#[cfg(not(all(unix, not(target_os = "emscripten"))))]
+mod fork {
+    pub fn get_fork_counter() -> usize {
+        0
+    }
+    pub fn register_fork_handler() {}
+}
+
+
+#[cfg(feature = "std_rng")]
+#[cfg(test)]
+mod test {
+    use super::ReseedingRng;
+    use crate::rngs::mock::StepRng;
+    use crate::rngs::std::Core;
+    use crate::{Rng, SeedableRng};
+
+    #[test]
+    fn test_reseeding() {
+        let mut zero = StepRng::new(0, 0);
+        let rng = Core::from_rng(&mut zero).unwrap();
+        let thresh = 1; // reseed every time the buffer is exhausted
+        let mut reseeding = ReseedingRng::new(rng, thresh, zero);
+
+        // RNG buffer size is [u32; 64]
+        // Debug is only implemented up to length 32 so use two arrays
+        let mut buf = ([0u32; 32], [0u32; 32]);
+        reseeding.fill(&mut buf.0);
+        reseeding.fill(&mut buf.1);
+        let seq = buf;
+        for _ in 0..10 {
+            reseeding.fill(&mut buf.0);
+            reseeding.fill(&mut buf.1);
+            assert_eq!(buf, seq);
+        }
+    }
+
+    #[test]
+    fn test_clone_reseeding() {
+        #![allow(clippy::redundant_clone)]
+
+        let mut zero = StepRng::new(0, 0);
+        let rng = Core::from_rng(&mut zero).unwrap();
+        let mut rng1 = ReseedingRng::new(rng, 32 * 4, zero);
+
+        let first: u32 = rng1.gen();
+        for _ in 0..10 {
+            let _ = rng1.gen::<u32>();
+        }
+
+        let mut rng2 = rng1.clone();
+        assert_eq!(first, rng2.gen::<u32>());
+    }
+}
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mock.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mock.rs.html new file mode 100644 index 0000000..819baf1 --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mock.rs.html @@ -0,0 +1,177 @@ +mock.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Mock random number generator
+
+use rand_core::{impls, Error, RngCore};
+
+#[cfg(feature = "serde1")]
+use serde::{Serialize, Deserialize};
+
+/// A simple implementation of `RngCore` for testing purposes.
+///
+/// This generates an arithmetic sequence (i.e. adds a constant each step)
+/// over a `u64` number, using wrapping arithmetic. If the increment is 0
+/// the generator yields a constant.
+///
+/// ```
+/// use rand::Rng;
+/// use rand::rngs::mock::StepRng;
+///
+/// let mut my_rng = StepRng::new(2, 1);
+/// let sample: [u64; 3] = my_rng.gen();
+/// assert_eq!(sample, [2, 3, 4]);
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+pub struct StepRng {
+    v: u64,
+    a: u64,
+}
+
+impl StepRng {
+    /// Create a `StepRng`, yielding an arithmetic sequence starting with
+    /// `initial` and incremented by `increment` each time.
+    pub fn new(initial: u64, increment: u64) -> Self {
+        StepRng {
+            v: initial,
+            a: increment,
+        }
+    }
+}
+
+impl RngCore for StepRng {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        let result = self.v;
+        self.v = self.v.wrapping_add(self.a);
+        result
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        impls::fill_bytes_via_next(self, dest);
+    }
+
+    #[inline]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.fill_bytes(dest);
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    #[cfg(feature = "serde1")]
+    fn test_serialization_step_rng() {
+        use super::StepRng;
+
+        let some_rng = StepRng::new(42, 7);
+        let de_some_rng: StepRng =
+            bincode::deserialize(&bincode::serialize(&some_rng).unwrap()).unwrap();
+        assert_eq!(some_rng.v, de_some_rng.v);
+        assert_eq!(some_rng.a, de_some_rng.a);
+
+    }
+}
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mod.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mod.rs.html new file mode 100644 index 0000000..48767fa --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/mod.rs.html @@ -0,0 +1,241 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Random number generators and adapters
+//!
+//! ## Background: Random number generators (RNGs)
+//!
+//! Computers cannot produce random numbers from nowhere. We classify
+//! random number generators as follows:
+//!
+//! -   "True" random number generators (TRNGs) use hard-to-predict data sources
+//!     (e.g. the high-resolution parts of event timings and sensor jitter) to
+//!     harvest random bit-sequences, apply algorithms to remove bias and
+//!     estimate available entropy, then combine these bits into a byte-sequence
+//!     or an entropy pool. This job is usually done by the operating system or
+//!     a hardware generator (HRNG).
+//! -   "Pseudo"-random number generators (PRNGs) use algorithms to transform a
+//!     seed into a sequence of pseudo-random numbers. These generators can be
+//!     fast and produce well-distributed unpredictable random numbers (or not).
+//!     They are usually deterministic: given algorithm and seed, the output
+//!     sequence can be reproduced. They have finite period and eventually loop;
+//!     with many algorithms this period is fixed and can be proven sufficiently
+//!     long, while others are chaotic and the period depends on the seed.
+//! -   "Cryptographically secure" pseudo-random number generators (CSPRNGs)
+//!     are the sub-set of PRNGs which are secure. Security of the generator
+//!     relies both on hiding the internal state and using a strong algorithm.
+//!
+//! ## Traits and functionality
+//!
+//! All RNGs implement the [`RngCore`] trait, as a consequence of which the
+//! [`Rng`] extension trait is automatically implemented. Secure RNGs may
+//! additionally implement the [`CryptoRng`] trait.
+//!
+//! All PRNGs require a seed to produce their random number sequence. The
+//! [`SeedableRng`] trait provides three ways of constructing PRNGs:
+//!
+//! -   `from_seed` accepts a type specific to the PRNG
+//! -   `from_rng` allows a PRNG to be seeded from any other RNG
+//! -   `seed_from_u64` allows any PRNG to be seeded from a `u64` insecurely
+//! -   `from_entropy` securely seeds a PRNG from fresh entropy
+//!
+//! Use the [`rand_core`] crate when implementing your own RNGs.
+//!
+//! ## Our generators
+//!
+//! This crate provides several random number generators:
+//!
+//! -   [`OsRng`] is an interface to the operating system's random number
+//!     source. Typically the operating system uses a CSPRNG with entropy
+//!     provided by a TRNG and some type of on-going re-seeding.
+//! -   [`ThreadRng`], provided by the [`thread_rng`] function, is a handle to a
+//!     thread-local CSPRNG with periodic seeding from [`OsRng`]. Because this
+//!     is local, it is typically much faster than [`OsRng`]. It should be
+//!     secure, though the paranoid may prefer [`OsRng`].
+//! -   [`StdRng`] is a CSPRNG chosen for good performance and trust of security
+//!     (based on reviews, maturity and usage). The current algorithm is ChaCha12,
+//!     which is well established and rigorously analysed.
+//!     [`StdRng`] provides the algorithm used by [`ThreadRng`] but without
+//!     periodic reseeding.
+//! -   [`SmallRng`] is an **insecure** PRNG designed to be fast, simple, require
+//!     little memory, and have good output quality.
+//!
+//! The algorithms selected for [`StdRng`] and [`SmallRng`] may change in any
+//! release and may be platform-dependent, therefore they should be considered
+//! **not reproducible**.
+//!
+//! ## Additional generators
+//!
+//! **TRNGs**: The [`rdrand`] crate provides an interface to the RDRAND and
+//! RDSEED instructions available in modern Intel and AMD CPUs.
+//! The [`rand_jitter`] crate provides a user-space implementation of
+//! entropy harvesting from CPU timer jitter, but is very slow and has
+//! [security issues](https://github.com/rust-random/rand/issues/699).
+//!
+//! **PRNGs**: Several companion crates are available, providing individual or
+//! families of PRNG algorithms. These provide the implementations behind
+//! [`StdRng`] and [`SmallRng`] but can also be used directly, indeed *should*
+//! be used directly when **reproducibility** matters.
+//! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`].
+//! A full list can be found by searching for crates with the [`rng` tag].
+//!
+//! [`Rng`]: crate::Rng
+//! [`RngCore`]: crate::RngCore
+//! [`CryptoRng`]: crate::CryptoRng
+//! [`SeedableRng`]: crate::SeedableRng
+//! [`thread_rng`]: crate::thread_rng
+//! [`rdrand`]: https://crates.io/crates/rdrand
+//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
+//! [`rand_chacha`]: https://crates.io/crates/rand_chacha
+//! [`rand_pcg`]: https://crates.io/crates/rand_pcg
+//! [`rand_xoshiro`]: https://crates.io/crates/rand_xoshiro
+//! [`rng` tag]: https://crates.io/keywords/rng
+
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
+#[cfg(feature = "std")] pub mod adapter;
+
+pub mod mock; // Public so we don't export `StepRng` directly, making it a bit
+              // more clear it is intended for testing.
+
+#[cfg(all(feature = "small_rng", target_pointer_width = "64"))]
+mod xoshiro256plusplus;
+#[cfg(all(feature = "small_rng", not(target_pointer_width = "64")))]
+mod xoshiro128plusplus;
+#[cfg(feature = "small_rng")] mod small;
+
+#[cfg(feature = "std_rng")] mod std;
+#[cfg(all(feature = "std", feature = "std_rng"))] pub(crate) mod thread;
+
+#[cfg(feature = "small_rng")] pub use self::small::SmallRng;
+#[cfg(feature = "std_rng")] pub use self::std::StdRng;
+#[cfg(all(feature = "std", feature = "std_rng"))] pub use self::thread::ThreadRng;
+
+#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
+#[cfg(feature = "getrandom")] pub use rand_core::OsRng;
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/std.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/std.rs.html new file mode 100644 index 0000000..a7d324f --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/std.rs.html @@ -0,0 +1,199 @@ +std.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The standard RNG
+
+use crate::{CryptoRng, Error, RngCore, SeedableRng};
+
+pub(crate) use rand_chacha::ChaCha12Core as Core;
+
+use rand_chacha::ChaCha12Rng as Rng;
+
+/// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient
+/// on the current platform, to be statistically strong and unpredictable
+/// (meaning a cryptographically secure PRNG).
+///
+/// The current algorithm used is the ChaCha block cipher with 12 rounds. Please
+/// see this relevant [rand issue] for the discussion. This may change as new 
+/// evidence of cipher security and performance becomes available.
+///
+/// The algorithm is deterministic but should not be considered reproducible
+/// due to dependence on configuration and possible replacement in future
+/// library versions. For a secure reproducible generator, we recommend use of
+/// the [rand_chacha] crate directly.
+///
+/// [rand_chacha]: https://crates.io/crates/rand_chacha
+/// [rand issue]: https://github.com/rust-random/rand/issues/932
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std_rng")))]
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct StdRng(Rng);
+
+impl RngCore for StdRng {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        self.0.next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        self.0.next_u64()
+    }
+
+    #[inline(always)]
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.0.fill_bytes(dest);
+    }
+
+    #[inline(always)]
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.0.try_fill_bytes(dest)
+    }
+}
+
+impl SeedableRng for StdRng {
+    type Seed = <Rng as SeedableRng>::Seed;
+
+    #[inline(always)]
+    fn from_seed(seed: Self::Seed) -> Self {
+        StdRng(Rng::from_seed(seed))
+    }
+
+    #[inline(always)]
+    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
+        Rng::from_rng(rng).map(StdRng)
+    }
+}
+
+impl CryptoRng for StdRng {}
+
+
+#[cfg(test)]
+mod test {
+    use crate::rngs::StdRng;
+    use crate::{RngCore, SeedableRng};
+
+    #[test]
+    fn test_stdrng_construction() {
+        // Test value-stability of StdRng. This is expected to break any time
+        // the algorithm is changed.
+        #[rustfmt::skip]
+        let seed = [1,0,0,0, 23,0,0,0, 200,1,0,0, 210,30,0,0,
+                    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
+
+        let target = [10719222850664546238, 14064965282130556830];
+
+        let mut rng0 = StdRng::from_seed(seed);
+        let x0 = rng0.next_u64();
+
+        let mut rng1 = StdRng::from_rng(rng0).unwrap();
+        let x1 = rng1.next_u64();
+
+        assert_eq!([x0, x1], target);
+    }
+}
+
+
\ No newline at end of file diff --git a/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/thread.rs.html b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/thread.rs.html new file mode 100644 index 0000000..5243758 --- /dev/null +++ b/rust/theBook/chapter-2-guessing-game/guessing_game/target/doc/src/rand/rngs/thread.rs.html @@ -0,0 +1,289 @@ +thread.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+
// Copyright 2018 Developers of the Rand project.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Thread-local random number generator
+
+use core::cell::UnsafeCell;
+use std::rc::Rc;
+use std::thread_local;
+
+use super::std::Core;
+use crate::rngs::adapter::ReseedingRng;
+use crate::rngs::OsRng;
+use crate::{CryptoRng, Error, RngCore, SeedableRng};
+
+// Rationale for using `UnsafeCell` in `ThreadRng`:
+//
+// Previously we used a `RefCell`, with an overhead of ~15%. There will only
+// ever be one mutable reference to the interior of the `UnsafeCell`, because
+// we only have such a reference inside `next_u32`, `next_u64`, etc. Within a
+// single thread (which is the definition of `ThreadRng`), there will only ever
+// be one of these methods active at a time.
+//
+// A possible scenario where there could be multiple mutable references is if
+// `ThreadRng` is used inside `next_u32` and co. But the implementation is
+// completely under our control. We just have to ensure none of them use
+// `ThreadRng` internally, which is nonsensical anyway. We should also never run
+// `ThreadRng` in destructors of its implementation, which is also nonsensical.
+
+
+// Number of generated bytes after which to reseed `ThreadRng`.
+// According to benchmarks, reseeding has a noticeable impact with thresholds
+// of 32 kB and less. We choose 64 kB to avoid significant overhead.
+const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
+
+/// A reference to the thread-local generator
+///
+/// An instance can be obtained via [`thread_rng`] or via `ThreadRng::default()`.
+/// This handle is safe to use everywhere (including thread-local destructors),
+/// though it is recommended not to use inside a fork handler.
+/// The handle cannot be passed between threads (is not `Send` or `Sync`).
+///
+/// `ThreadRng` uses the same PRNG as [`StdRng`] for security and performance
+/// and is automatically seeded from [`OsRng`].
+///
+/// Unlike `StdRng`, `ThreadRng` uses the  [`ReseedingRng`] wrapper to reseed
+/// the PRNG from fresh entropy every 64 kiB of random data as well as after a
+/// fork on Unix (though not quite immediately; see documentation of
+/// [`ReseedingRng`]).
+/// Note that the reseeding is done as an extra precaution against side-channel
+/// attacks and mis-use (e.g. if somehow weak entropy were supplied initially).
+/// The PRNG algorithms used are assumed to be secure.
+///
+/// [`ReseedingRng`]: crate::rngs::adapter::ReseedingRng
+/// [`StdRng`]: crate::rngs::StdRng
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "std_rng"))))]
+#[derive(Clone, Debug)]
+pub struct ThreadRng {
+    // Rc is explicitly !Send and !Sync
+    rng: Rc<UnsafeCell<ReseedingRng<Core, OsRng>>>,
+}
+
+thread_local!(
+    // We require Rc<..> to avoid premature freeing when thread_rng is used
+    // within thread-local destructors. See #968.
+    static THREAD_RNG_KEY: Rc<UnsafeCell<ReseedingRng<Core, OsRng>>> = {
+        let r = Core::from_rng(OsRng).unwrap_or_else(|err|
+                panic!("could not initialize thread_rng: {}", err));
+        let rng = ReseedingRng::new(r,
+                                    THREAD_RNG_RESEED_THRESHOLD,
+                                    OsRng);
+        Rc::new(UnsafeCell::new(rng))
+    }
+);
+
+/// Retrieve the lazily-initialized thread-local random number generator,
+/// seeded by the system. Intended to be used in method chaining style,
+/// e.g. `thread_rng().gen::<i32>()`, or cached locally, e.g.
+/// `let mut rng = thread_rng();`.  Invoked by the `Default` trait, making
+/// `ThreadRng::default()` equivalent.
+///
+/// For more information see [`ThreadRng`].
+#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "std_rng"))))]
+pub fn thread_rng() -> ThreadRng {
+    let rng = THREAD_RNG_KEY.with(|t| t.clone());
+    ThreadRng { rng }
+}
+
+impl Default for ThreadRng {
+    fn default() -> ThreadRng {
+        crate::prelude::thread_rng()
+    }
+}
+
+impl RngCore for ThreadRng {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        // SAFETY: We must make sure to stop using `rng` before anyone else
+        // creates another mutable reference
+        let rng = unsafe { &mut *self.rng.get() };
+        rng.next_u32()
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        // SAFETY: We must make sure to stop using `rng` before anyone else
+        // creates another mutable reference
+        let rng = unsafe { &mut *self.rng.get() };
+        rng.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        // SAFETY: We must make sure to stop using `rng` before anyone else
+        // creates another mutable reference
+        let rng = unsafe { &mut *self.rng.get() };
+        rng.fill_bytes(dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        // SAFETY: We must make sure to stop using `rng` before anyone else
+        // creates another mutable reference
+        let rng = unsafe { &mut *self.rng.get() };
+        rng.try_fill_bytes(dest)
+    }
+}
+
+impl CryptoRng for ThreadRng {}
+
+
+#[cfg(test)]
+mod test {
+    #[test]
+    fn test_thread_rng() {
+        use crate::Rng;
+        let mut r = crate::thread_rng();
+        r.gen::<i32>();
+        assert_eq!(r.gen_range(0..1), 0);
+    }
+}
+
+
\ No newline at end of file -- cgit v1.2.3-70-g09d2