From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001
From: Daniel Baumann <daniel.baumann@progress-linux.org>
Date: Sun, 28 Apr 2024 16:29:10 +0200
Subject: Adding upstream version 86.0.1.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
---
 third_party/rust/rand/src/rngs/adapter/mod.rs      |  15 +
 third_party/rust/rand/src/rngs/adapter/read.rs     | 148 +++++++++
 .../rust/rand/src/rngs/adapter/reseeding.rs        | 357 +++++++++++++++++++++
 third_party/rust/rand/src/rngs/entropy.rs          |  76 +++++
 third_party/rust/rand/src/rngs/mock.rs             |  64 ++++
 third_party/rust/rand/src/rngs/mod.rs              | 119 +++++++
 third_party/rust/rand/src/rngs/small.rs            | 115 +++++++
 third_party/rust/rand/src/rngs/std.rs              | 103 ++++++
 third_party/rust/rand/src/rngs/thread.rs           | 124 +++++++
 9 files changed, 1121 insertions(+)
 create mode 100644 third_party/rust/rand/src/rngs/adapter/mod.rs
 create mode 100644 third_party/rust/rand/src/rngs/adapter/read.rs
 create mode 100644 third_party/rust/rand/src/rngs/adapter/reseeding.rs
 create mode 100644 third_party/rust/rand/src/rngs/entropy.rs
 create mode 100644 third_party/rust/rand/src/rngs/mock.rs
 create mode 100644 third_party/rust/rand/src/rngs/mod.rs
 create mode 100644 third_party/rust/rand/src/rngs/small.rs
 create mode 100644 third_party/rust/rand/src/rngs/std.rs
 create mode 100644 third_party/rust/rand/src/rngs/thread.rs

(limited to 'third_party/rust/rand/src/rngs')

diff --git a/third_party/rust/rand/src/rngs/adapter/mod.rs b/third_party/rust/rand/src/rngs/adapter/mod.rs
new file mode 100644
index 0000000000..659ff26218
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/adapter/mod.rs
@@ -0,0 +1,15 @@
+// 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
+
+#[cfg(feature="std")] mod read;
+mod reseeding;
+
+#[cfg(feature="std")] pub use self::read::{ReadRng, ReadError};
+pub use self::reseeding::ReseedingRng;
diff --git a/third_party/rust/rand/src/rngs/adapter/read.rs b/third_party/rust/rand/src/rngs/adapter/read.rs
new file mode 100644
index 0000000000..901462ea7c
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/adapter/read.rs
@@ -0,0 +1,148 @@
+// 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.
+
+use std::io::Read;
+use std::fmt;
+
+use rand_core::{RngCore, Error, impls};
+
+
+/// 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.
+///
+/// # Example
+///
+/// ```
+/// use rand::Rng;
+/// use rand::rngs::adapter::ReadRng;
+///
+/// let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
+/// let mut rng = ReadRng::new(&data[..]);
+/// println!("{:x}", rng.gen::<u32>());
+/// ```
+///
+/// [`OsRng`]: crate::rngs::OsRng
+/// [`try_fill_bytes`]: RngCore::try_fill_bytes
+#[derive(Debug)]
+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)]
+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 super::ReadRng;
+    use crate::RngCore;
+
+    #[test]
+    fn test_reader_rng_u64() {
+        // transmute from the target to avoid endianness concerns.
+        let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1,
+                     0  , 0, 0, 0, 0, 0, 0, 2,
+                     0,   0, 0, 0, 0, 0, 0, 3];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u64(), 1_u64.to_be());
+        assert_eq!(rng.next_u64(), 2_u64.to_be());
+        assert_eq!(rng.next_u64(), 3_u64.to_be());
+    }
+
+    #[test]
+    fn test_reader_rng_u32() {
+        let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
+        let mut rng = ReadRng::new(&v[..]);
+
+        assert_eq!(rng.next_u32(), 1_u32.to_be());
+        assert_eq!(rng.next_u32(), 2_u32.to_be());
+        assert_eq!(rng.next_u32(), 3_u32.to_be());
+    }
+
+    #[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());
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/adapter/reseeding.rs b/third_party/rust/rand/src/rngs/adapter/reseeding.rs
new file mode 100644
index 0000000000..ec88efe218
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/adapter/reseeding.rs
@@ -0,0 +1,357 @@
+// 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::{RngCore, CryptoRng, SeedableRng, Error};
+use rand_core::block::{BlockRngCore, BlockRng};
+
+/// 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.
+/// - After a process is forked, the RNG in the child process is reseeded within
+///   the next few generated values, depending on the block size of the
+///   underlying PRNG. For ChaCha and Hc128 this is a maximum of
+///   15 `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.
+///
+/// # 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, AtomicBool, Ordering};
+    #[allow(deprecated)]  // Required for compatibility with Rust < 1.24.
+    use core::sync::atomic::{ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};
+
+    // 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.
+
+    #[allow(deprecated)]
+    static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
+    pub fn get_fork_counter() -> usize {
+        RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
+    }
+
+    #[allow(deprecated)]
+    static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;
+
+    extern 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() {
+        if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {
+            unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
+            FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
+        }
+    }
+}
+
+#[cfg(not(all(unix, not(target_os="emscripten"))))]
+mod fork {
+    pub fn get_fork_counter() -> usize { 0 }
+    pub fn register_fork_handler() {}
+}
+
+
+#[cfg(test)]
+mod test {
+    use crate::{Rng, SeedableRng};
+    use crate::rngs::std::Core;
+    use crate::rngs::mock::StepRng;
+    use super::ReseedingRng;
+
+    #[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() {
+        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>());
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/entropy.rs b/third_party/rust/rand/src/rngs/entropy.rs
new file mode 100644
index 0000000000..1ed59ab150
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/entropy.rs
@@ -0,0 +1,76 @@
+// 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.
+
+//! Entropy generator, or wrapper around external generators
+
+#![allow(deprecated)]   // whole module is deprecated
+
+use rand_core::{RngCore, CryptoRng, Error};
+use crate::rngs::OsRng;
+
+/// An interface returning random data from external source(s), provided
+/// specifically for securely seeding algorithmic generators (PRNGs).
+///
+/// This is deprecated. It is suggested you use [`rngs::OsRng`] instead.
+/// 
+/// [`rngs::OsRng`]: crate::rngs::OsRng
+#[derive(Debug)]
+#[deprecated(since="0.7.0", note="use rngs::OsRng instead")]
+pub struct EntropyRng {
+    source: OsRng,
+}
+
+impl EntropyRng {
+    /// Create a new `EntropyRng`.
+    ///
+    /// This method will do no system calls or other initialization routines,
+    /// those are done on first use. This is done to make `new` infallible,
+    /// and `try_fill_bytes` the only place to report errors.
+    pub fn new() -> Self {
+        EntropyRng { source: OsRng }
+    }
+}
+
+impl Default for EntropyRng {
+    fn default() -> Self {
+        EntropyRng::new()
+    }
+}
+
+impl RngCore for EntropyRng {
+    fn next_u32(&mut self) -> u32 {
+        self.source.next_u32()
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        self.source.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.source.fill_bytes(dest)
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        self.source.try_fill_bytes(dest)
+    }
+}
+
+impl CryptoRng for EntropyRng {}
+
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_entropy() {
+        let mut rng = EntropyRng::new();
+        let n = (rng.next_u32() ^ rng.next_u32()).count_ones();
+        assert!(n >= 2);    // p(failure) approx 1e-7
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/mock.rs b/third_party/rust/rand/src/rngs/mock.rs
new file mode 100644
index 0000000000..b4081daf35
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/mock.rs
@@ -0,0 +1,64 @@
+// 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::{RngCore, Error, impls};
+
+/// 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)]
+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(())
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/mod.rs b/third_party/rust/rand/src/rngs/mod.rs
new file mode 100644
index 0000000000..abf3243c10
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/mod.rs
@@ -0,0 +1,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 ChaCha20,
+//!     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].
+//!
+//! [`SmallRng`]: rngs::SmallRng
+//! [`StdRng`]: rngs::StdRng
+//! [`OsRng`]: rngs::OsRng
+//! [`ThreadRng`]: rngs::ThreadRng
+//! [`mock::StepRng`]: rngs::mock::StepRng
+//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
+//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
+//! [`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
+
+pub mod adapter;
+
+#[cfg(feature="std")] mod entropy;
+pub mod mock;   // Public so we don't export `StepRng` directly, making it a bit
+                // more clear it is intended for testing.
+#[cfg(feature="small_rng")]
+mod small;
+mod std;
+#[cfg(feature="std")] pub(crate) mod thread;
+
+#[allow(deprecated)]
+#[cfg(feature="std")] pub use self::entropy::EntropyRng;
+
+#[cfg(feature="small_rng")]
+pub use self::small::SmallRng;
+pub use self::std::StdRng;
+#[cfg(feature="std")] pub use self::thread::ThreadRng;
+
+#[cfg(feature="getrandom")] pub use rand_core::OsRng;
diff --git a/third_party/rust/rand/src/rngs/small.rs b/third_party/rust/rand/src/rngs/small.rs
new file mode 100644
index 0000000000..657136395f
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/small.rs
@@ -0,0 +1,115 @@
+// 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.
+
+//! A small fast RNG
+
+use rand_core::{RngCore, SeedableRng, Error};
+
+#[cfg(all(not(target_os = "emscripten"), target_pointer_width = "64"))]
+type Rng = rand_pcg::Pcg64Mcg;
+#[cfg(not(all(not(target_os = "emscripten"), target_pointer_width = "64")))]
+type Rng = rand_pcg::Pcg32;
+
+/// A small-state, fast non-crypto PRNG
+///
+/// `SmallRng` may be a good choice when a PRNG with small state, cheap
+/// initialization, good statistical quality and good performance are required.
+/// It is **not** a good choice when security against prediction or
+/// reproducibility are important.
+///
+/// This PRNG is **feature-gated**: to use, you must enable the crate feature
+/// `small_rng`.
+///
+/// The algorithm is deterministic but should not be considered reproducible
+/// due to dependence on platform and possible replacement in future
+/// library versions. For a reproducible generator, use a named PRNG from an
+/// external crate, e.g. [rand_pcg] or [rand_chacha].
+/// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html).
+///
+/// The PRNG algorithm in `SmallRng` is chosen to be
+/// efficient on the current platform, without consideration for cryptography
+/// or security. The size of its state is much smaller than [`StdRng`].
+/// The current algorithm is [`Pcg64Mcg`](rand_pcg::Pcg64Mcg) on 64-bit
+/// platforms and [`Pcg32`](rand_pcg::Pcg32) on 32-bit platforms. Both are
+/// implemented by the [rand_pcg] crate.
+///
+/// # Examples
+///
+/// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
+///
+/// ```
+/// use rand::{Rng, SeedableRng};
+/// use rand::rngs::SmallRng;
+///
+/// // Create small, cheap to initialize and fast RNG with a random seed.
+/// // The randomness is supplied by the operating system.
+/// let mut small_rng = SmallRng::from_entropy();
+/// # let v: u32 = small_rng.gen();
+/// ```
+///
+/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
+/// efficient:
+///
+/// ```
+/// use std::iter;
+/// use rand::{SeedableRng, thread_rng};
+/// use rand::rngs::SmallRng;
+///
+/// // Create a big, expensive to initialize and slower, but unpredictable RNG.
+/// // This is cached and done only once per thread.
+/// let mut thread_rng = thread_rng();
+/// // Create small, cheap to initialize and fast RNGs with random seeds.
+/// // One can generally assume this won't fail.
+/// let rngs: Vec<SmallRng> = iter::repeat(())
+///     .map(|()| SmallRng::from_rng(&mut thread_rng).unwrap())
+///     .take(10)
+///     .collect();
+/// ```
+///
+/// [`StdRng`]: crate::rngs::StdRng
+/// [`thread_rng`]: crate::thread_rng
+/// [rand_chacha]: https://crates.io/crates/rand_chacha
+/// [rand_pcg]: https://crates.io/crates/rand_pcg
+#[derive(Clone, Debug)]
+pub struct SmallRng(Rng);
+
+impl RngCore for SmallRng {
+    #[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 SmallRng {
+    type Seed = <Rng as SeedableRng>::Seed;
+
+    #[inline(always)]
+    fn from_seed(seed: Self::Seed) -> Self {
+        SmallRng(Rng::from_seed(seed))
+    }
+
+    #[inline(always)]
+    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
+        Rng::from_rng(rng).map(SmallRng)
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/std.rs b/third_party/rust/rand/src/rngs/std.rs
new file mode 100644
index 0000000000..8ebe6b8ec1
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/std.rs
@@ -0,0 +1,103 @@
+// 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::{RngCore, CryptoRng, Error, SeedableRng};
+
+#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))]
+pub(crate) use rand_hc::Hc128Core as Core;
+#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))]
+pub(crate) use rand_chacha::ChaCha20Core as Core;
+
+#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng;
+#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha20Rng 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 either 20 or 12
+/// rounds (see the `stdrng_*` feature flags, documented in the README).
+/// 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
+#[derive(Clone, Debug)]
+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::{RngCore, SeedableRng};
+    use crate::rngs::StdRng;
+
+    #[test]
+    fn test_stdrng_construction() {
+        // Test value-stability of StdRng. This is expected to break any time
+        // the algorithm is changed.
+        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];
+
+        #[cfg(any(feature="stdrng_strong", not(feature="stdrng_fast")))]
+        let target = [3950704604716924505, 5573172343717151650];
+        #[cfg(all(not(feature="stdrng_strong"), feature="stdrng_fast"))]
+        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);
+    }
+}
diff --git a/third_party/rust/rand/src/rngs/thread.rs b/third_party/rust/rand/src/rngs/thread.rs
new file mode 100644
index 0000000000..2006f4176f
--- /dev/null
+++ b/third_party/rust/rand/src/rngs/thread.rs
@@ -0,0 +1,124 @@
+// 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 std::cell::UnsafeCell;
+use std::ptr::NonNull;
+
+use crate::{RngCore, CryptoRng, SeedableRng, Error};
+use crate::rngs::adapter::ReseedingRng;
+use crate::rngs::OsRng;
+use super::std::Core;
+
+// 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 noticable impact with thresholds
+// of 32 kB and less. We choose 64 kB to avoid significant overhead.
+const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
+
+/// The type returned by [`thread_rng`], essentially just a reference to the
+/// PRNG in thread-local memory.
+///
+/// `ThreadRng` uses the same PRNG as [`StdRng`] for security and performance.
+/// As hinted by the name, the generator is thread-local. `ThreadRng` is a
+/// handle to this generator and thus supports `Copy`, but not `Send` or `Sync`.
+///
+/// Unlike `StdRng`, `ThreadRng` uses the  [`ReseedingRng`] wrapper to reseed
+/// the PRNG from fresh entropy every 64 kiB of random data.
+/// [`OsRng`] is used to provide seed data.
+///
+/// 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
+#[derive(Copy, Clone, Debug)]
+pub struct ThreadRng {
+    // inner raw pointer implies type is neither Send nor Sync
+    rng: NonNull<ReseedingRng<Core, OsRng>>,
+}
+
+thread_local!(
+    static THREAD_RNG_KEY: 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);
+        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`].
+pub fn thread_rng() -> ThreadRng {
+    let raw = THREAD_RNG_KEY.with(|t| t.get());
+    let nn = NonNull::new(raw).unwrap();
+    ThreadRng { rng: nn }
+}
+
+impl Default for ThreadRng {
+    fn default() -> ThreadRng {
+        crate::prelude::thread_rng()
+    }
+}
+
+impl RngCore for ThreadRng {
+    #[inline(always)]
+    fn next_u32(&mut self) -> u32 {
+        unsafe { self.rng.as_mut().next_u32() }
+    }
+
+    #[inline(always)]
+    fn next_u64(&mut self) -> u64 {
+        unsafe { self.rng.as_mut().next_u64() }
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        unsafe { self.rng.as_mut().fill_bytes(dest) }
+    }
+
+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
+        unsafe { self.rng.as_mut().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);
+    }
+}
-- 
cgit v1.2.3