Snap for 10453938 from 1df27553ccea135ec8c64649af6e018b0b277e98 to mainline-odp-release

Change-Id: I8533e18b89d8537f6318d0fe827af4fbaec0fab3
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 7f98fc0..4787b56 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "8792268dfe57e49bb4518190bf4fe66176759a44"
-  }
-}
+    "sha1": "89a1336b934c68ddce548127c6f8afd910b35a18"
+  },
+  "path_in_vcs": "rand_core"
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 6d2506f..841b4e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@
     host_supported: true,
     crate_name: "rand_core",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.6.3",
+    cargo_pkg_version: "0.6.4",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
@@ -58,6 +58,8 @@
         "//apex_available:platform",
         "com.android.virt",
     ],
+    product_available: true,
+    vendor_available: true,
 }
 
 rust_test {
@@ -65,7 +67,7 @@
     host_supported: true,
     crate_name: "rand_core",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.6.3",
+    cargo_pkg_version: "0.6.4",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82c8300..75fcbc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.6.4] - 2022-09-15
+- Fix unsoundness in `<BlockRng64 as RngCore>::next_u32` (#1160)
+- Reduce use of `unsafe` and improve gen_bytes performance (#1180)
+- Add `CryptoRngCore` trait (#1187, #1230)
+
 ## [0.6.3] - 2021-06-15
 ### Changed
 - Improved bound for `serde` impls on `BlockRng` (#1130)
diff --git a/Cargo.toml b/Cargo.toml
index 06ba1e8..fd8c96d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,32 +3,47 @@
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
 #
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
 
 [package]
 edition = "2018"
 name = "rand_core"
-version = "0.6.3"
-authors = ["The Rand Project Developers", "The Rust Project Developers"]
-description = "Core random number generator traits and tools for implementation.\n"
+version = "0.6.4"
+authors = [
+    "The Rand Project Developers",
+    "The Rust Project Developers",
+]
+description = """
+Core random number generator traits and tools for implementation.
+"""
 homepage = "https://rust-random.github.io/book"
 documentation = "https://docs.rs/rand_core"
 readme = "README.md"
-keywords = ["random", "rng"]
-categories = ["algorithms", "no-std"]
+keywords = [
+    "random",
+    "rng",
+]
+categories = [
+    "algorithms",
+    "no-std",
+]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-random/rand"
+
 [package.metadata.docs.rs]
 all-features = true
-rustdoc-args = ["--cfg", "doc_cfg"]
+rustdoc-args = [
+    "--cfg",
+    "doc_cfg",
+]
 
 [package.metadata.playground]
 all-features = true
+
 [dependencies.getrandom]
 version = "0.2"
 optional = true
@@ -41,4 +56,8 @@
 [features]
 alloc = []
 serde1 = ["serde"]
-std = ["alloc", "getrandom", "getrandom/std"]
+std = [
+    "alloc",
+    "getrandom",
+    "getrandom/std",
+]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 6604bc5..bfaa029 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "rand_core"
-version = "0.6.3"
+version = "0.6.4"
 authors = ["The Rand Project Developers", "The Rust Project Developers"]
 license = "MIT OR Apache-2.0"
 readme = "README.md"
@@ -14,15 +14,6 @@
 categories = ["algorithms", "no-std"]
 edition = "2018"
 
-[features]
-std = ["alloc", "getrandom", "getrandom/std"]    # use std library; should be default but for above bug
-alloc = []  # enables Vec and Box support without std
-serde1 = ["serde"] # enables serde for BlockRng wrapper
-
-[dependencies]
-serde = { version = "1", features = ["derive"], optional = true }
-getrandom = { version = "0.2", optional = true }
-
 [package.metadata.docs.rs]
 # To build locally:
 # RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --no-deps --open
@@ -31,3 +22,12 @@
 
 [package.metadata.playground]
 all-features = true
+
+[features]
+std = ["alloc", "getrandom", "getrandom/std"]    # use std library; should be default but for above bug
+alloc = []  # enables Vec and Box support without std
+serde1 = ["serde"] # enables serde for BlockRng wrapper
+
+[dependencies]
+serde = { version = "1", features = ["derive"], optional = true }
+getrandom = { version = "0.2", optional = true }
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 17d7468..455787c 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -185,17 +185,3 @@
    file or class name and description of purpose be included on the
    same "printed page" as the copyright notice for easier
    identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/METADATA b/METADATA
index 6c047cf..88a399e 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/rand_core
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "rand_core"
 description: "Core random number generator traits and tools for implementation."
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/rand_core/rand_core-0.6.3.crate"
+    value: "https://static.crates.io/crates/rand_core/rand_core-0.6.4.crate"
   }
-  version: "0.6.3"
+  version: "0.6.4"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2021
-    month: 6
-    day: 21
+    year: 2022
+    month: 12
+    day: 13
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index cd4547e..05d9335 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -23,6 +23,12 @@
       "path": "external/rust/crates/crossbeam-utils"
     },
     {
+      "path": "external/rust/crates/flate2"
+    },
+    {
+      "path": "external/rust/crates/hashbrown"
+    },
+    {
       "path": "external/rust/crates/mio"
     },
     {
@@ -42,64 +48,52 @@
     },
     {
       "path": "external/rust/crates/tokio"
+    },
+    {
+      "path": "external/rust/crates/zerocopy"
+    },
+    {
+      "path": "external/uwb/src"
+    },
+    {
+      "path": "packages/modules/Virtualization/apkdmverity"
+    },
+    {
+      "path": "packages/modules/Virtualization/authfs"
+    },
+    {
+      "path": "packages/modules/Virtualization/avmd"
+    },
+    {
+      "path": "packages/modules/Virtualization/libs/devicemapper"
+    },
+    {
+      "path": "packages/modules/Virtualization/microdroid_manager"
+    },
+    {
+      "path": "packages/modules/Virtualization/virtualizationmanager"
+    },
+    {
+      "path": "packages/modules/Virtualization/vm"
+    },
+    {
+      "path": "packages/modules/Virtualization/zipfuse"
+    },
+    {
+      "path": "system/security/keystore2"
+    },
+    {
+      "path": "system/security/keystore2/legacykeystore"
     }
   ],
   "presubmit": [
     {
-      "name": "ZipFuseTest"
-    },
-    {
-      "name": "apkdmverity.test"
-    },
-    {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
-      "name": "keystore2_test"
-    },
-    {
-      "name": "keystore2_test_utils_test"
-    },
-    {
-      "name": "legacykeystore_test"
-    },
-    {
-      "name": "microdroid_manager_test"
-    },
-    {
       "name": "rand_core_test_src_lib"
-    },
-    {
-      "name": "virtualizationservice_device_test"
     }
   ],
   "presubmit-rust": [
     {
-      "name": "ZipFuseTest"
-    },
-    {
-      "name": "apkdmverity.test"
-    },
-    {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
-      "name": "keystore2_test"
-    },
-    {
-      "name": "keystore2_test_utils_test"
-    },
-    {
-      "name": "legacykeystore_test"
-    },
-    {
-      "name": "microdroid_manager_test"
-    },
-    {
       "name": "rand_core_test_src_lib"
-    },
-    {
-      "name": "virtualizationservice_device_test"
     }
   ]
 }
diff --git a/cargo2android.json b/cargo2android.json
index b73c7b4..8945bb0 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -7,5 +7,6 @@
   "device": true,
   "features": "std",
   "run": true,
-  "tests": true
-}
\ No newline at end of file
+  "tests": true,
+  "vendor-available": true
+}
diff --git a/src/block.rs b/src/block.rs
index a54cadf..d311b68 100644
--- a/src/block.rs
+++ b/src/block.rs
@@ -95,7 +95,7 @@
 /// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
 /// also handle the bookkeeping of when to generate a new batch of values.
 ///
-/// No whole generated `u32` values are thown away and all values are consumed
+/// No whole generated `u32` values are thrown away and all values are consumed
 /// in-order. [`next_u32`] simply takes the next available `u32` value.
 /// [`next_u64`] is implemented by combining two `u32` values, least
 /// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
@@ -352,27 +352,21 @@
 {
     #[inline]
     fn next_u32(&mut self) -> u32 {
-        let mut index = self.index * 2 - self.half_used as usize;
-        if index >= self.results.as_ref().len() * 2 {
+        let mut index = self.index - self.half_used as usize;
+        if index >= self.results.as_ref().len() {
             self.core.generate(&mut self.results);
             self.index = 0;
+            index = 0;
             // `self.half_used` is by definition `false`
             self.half_used = false;
-            index = 0;
         }
 
+        let shift = 32 * (self.half_used as usize);
+
         self.half_used = !self.half_used;
         self.index += self.half_used as usize;
 
-        // Index as if this is a u32 slice.
-        unsafe {
-            let results = &*(self.results.as_ref() as *const [u64] as *const [u32]);
-            if cfg!(target_endian = "little") {
-                *results.get_unchecked(index)
-            } else {
-                *results.get_unchecked(index ^ 1)
-            }
-        }
+        (self.results.as_ref()[index] >> shift) as u32
     }
 
     #[inline]
@@ -435,3 +429,111 @@
 }
 
 impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
+
+#[cfg(test)]
+mod test {
+    use crate::{SeedableRng, RngCore};
+    use crate::block::{BlockRng, BlockRng64, BlockRngCore};
+
+    #[derive(Debug, Clone)]
+    struct DummyRng {
+        counter: u32,
+    }
+
+    impl BlockRngCore for DummyRng {
+        type Item = u32;
+
+        type Results = [u32; 16];
+
+        fn generate(&mut self, results: &mut Self::Results) {
+            for r in results {
+                *r = self.counter;
+                self.counter = self.counter.wrapping_add(3511615421);
+            }
+        }
+    }
+
+    impl SeedableRng for DummyRng {
+        type Seed = [u8; 4];
+
+        fn from_seed(seed: Self::Seed) -> Self {
+            DummyRng { counter: u32::from_le_bytes(seed) }
+        }
+    }
+
+    #[test]
+    fn blockrng_next_u32_vs_next_u64() {
+        let mut rng1 = BlockRng::<DummyRng>::from_seed([1, 2, 3, 4]);
+        let mut rng2 = rng1.clone();
+        let mut rng3 = rng1.clone();
+
+        let mut a = [0; 16];
+        (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+        (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
+        (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+
+        let mut b = [0; 16];
+        (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+        (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+        (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
+        assert_eq!(a, b);
+
+        let mut c = [0; 16];
+        (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
+        (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+        (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+        assert_eq!(a, c);
+    }
+
+    #[derive(Debug, Clone)]
+    struct DummyRng64 {
+        counter: u64,
+    }
+
+    impl BlockRngCore for DummyRng64 {
+        type Item = u64;
+
+        type Results = [u64; 8];
+
+        fn generate(&mut self, results: &mut Self::Results) {
+            for r in results {
+                *r = self.counter;
+                self.counter = self.counter.wrapping_add(2781463553396133981);
+            }
+        }
+    }
+
+    impl SeedableRng for DummyRng64 {
+        type Seed = [u8; 8];
+
+        fn from_seed(seed: Self::Seed) -> Self {
+            DummyRng64 { counter: u64::from_le_bytes(seed) }
+        }
+    }
+
+    #[test]
+    fn blockrng64_next_u32_vs_next_u64() {
+        let mut rng1 = BlockRng64::<DummyRng64>::from_seed([1, 2, 3, 4, 5, 6, 7, 8]);
+        let mut rng2 = rng1.clone();
+        let mut rng3 = rng1.clone();
+
+        let mut a = [0; 16];
+        (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+        (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
+        (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
+
+        let mut b = [0; 16];
+        (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+        (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
+        (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
+        assert_ne!(a, b);
+        assert_eq!(&a[..4], &b[..4]);
+        assert_eq!(&a[4..12], &b[8..]);
+
+        let mut c = [0; 16];
+        (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
+        (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+        (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
+        assert_eq!(b, c);
+    }
+}
diff --git a/src/error.rs b/src/error.rs
index a64c430..411896f 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -82,7 +82,7 @@
     ///
     /// This method is identical to `std::io::Error::raw_os_error()`, except
     /// that it works in `no_std` contexts. If this method returns `None`, the
-    /// error value can still be formatted via the `Diplay` implementation.
+    /// error value can still be formatted via the `Display` implementation.
     #[inline]
     pub fn raw_os_error(&self) -> Option<i32> {
         #[cfg(feature = "std")]
diff --git a/src/impls.rs b/src/impls.rs
index 2588a72..4b7688c 100644
--- a/src/impls.rs
+++ b/src/impls.rs
@@ -52,36 +52,59 @@
     }
 }
 
-macro_rules! fill_via_chunks {
-    ($src:expr, $dst:expr, $ty:ty) => {{
-        const SIZE: usize = core::mem::size_of::<$ty>();
-        let chunk_size_u8 = min($src.len() * SIZE, $dst.len());
-        let chunk_size = (chunk_size_u8 + SIZE - 1) / SIZE;
+trait Observable: Copy {
+    type Bytes: AsRef<[u8]>;
+    fn to_le_bytes(self) -> Self::Bytes;
 
-        // The following can be replaced with safe code, but unfortunately it's
-        // ca. 8% slower.
-        if cfg!(target_endian = "little") {
-            unsafe {
-                core::ptr::copy_nonoverlapping(
-                    $src.as_ptr() as *const u8,
-                    $dst.as_mut_ptr(),
-                    chunk_size_u8);
-            }
-        } else {
-            for (&n, chunk) in $src.iter().zip($dst.chunks_mut(SIZE)) {
-                let tmp = n.to_le();
-                let src_ptr = &tmp as *const $ty as *const u8;
-                unsafe {
-                    core::ptr::copy_nonoverlapping(
-                        src_ptr,
-                        chunk.as_mut_ptr(),
-                        chunk.len());
-                }
-            }
+    // Contract: observing self is memory-safe (implies no uninitialised padding)
+    fn as_byte_slice(x: &[Self]) -> &[u8];
+}
+impl Observable for u32 {
+    type Bytes = [u8; 4];
+    fn to_le_bytes(self) -> Self::Bytes {
+        self.to_le_bytes()
+    }
+    fn as_byte_slice(x: &[Self]) -> &[u8] {
+        let ptr = x.as_ptr() as *const u8;
+        let len = x.len() * core::mem::size_of::<Self>();
+        unsafe { core::slice::from_raw_parts(ptr, len) }
+    }
+}
+impl Observable for u64 {
+    type Bytes = [u8; 8];
+    fn to_le_bytes(self) -> Self::Bytes {
+        self.to_le_bytes()
+    }
+    fn as_byte_slice(x: &[Self]) -> &[u8] {
+        let ptr = x.as_ptr() as *const u8;
+        let len = x.len() * core::mem::size_of::<Self>();
+        unsafe { core::slice::from_raw_parts(ptr, len) }
+    }
+}
+
+fn fill_via_chunks<T: Observable>(src: &[T], dest: &mut [u8]) -> (usize, usize) {
+    let size = core::mem::size_of::<T>();
+    let byte_len = min(src.len() * size, dest.len());
+    let num_chunks = (byte_len + size - 1) / size;
+
+    if cfg!(target_endian = "little") {
+        // On LE we can do a simple copy, which is 25-50% faster:
+        dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]);
+    } else {
+        // This code is valid on all arches, but slower than the above:
+        let mut i = 0;
+        let mut iter = dest[..byte_len].chunks_exact_mut(size);
+        for chunk in &mut iter {
+            chunk.copy_from_slice(src[i].to_le_bytes().as_ref());
+            i += 1;
         }
+        let chunk = iter.into_remainder();
+        if !chunk.is_empty() {
+            chunk.copy_from_slice(&src[i].to_le_bytes().as_ref()[..chunk.len()]);
+        }
+    }
 
-        (chunk_size, chunk_size_u8)
-    }};
+    (num_chunks, byte_len)
 }
 
 /// Implement `fill_bytes` by reading chunks from the output buffer of a block
@@ -115,7 +138,7 @@
 /// }
 /// ```
 pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
-    fill_via_chunks!(src, dest, u32)
+    fill_via_chunks(src, dest)
 }
 
 /// Implement `fill_bytes` by reading chunks from the output buffer of a block
@@ -129,7 +152,7 @@
 ///
 /// See `fill_via_u32_chunks` for an example.
 pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize) {
-    fill_via_chunks!(src, dest, u64)
+    fill_via_chunks(src, dest)
 }
 
 /// Implement `next_u32` via `fill_bytes`, little-endian order.
diff --git a/src/lib.rs b/src/lib.rs
index bc24270..1234a56 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -196,7 +196,7 @@
 /// Some generators may satisfy an additional property, however this is not
 /// required by this trait: if the CSPRNG's state is revealed, it should not be
 /// computationally-feasible to reconstruct output prior to this. Some other
-/// generators allow backwards-computation and are consided *reversible*.
+/// generators allow backwards-computation and are considered *reversible*.
 ///
 /// Note that this trait is provided for guidance only and cannot guarantee
 /// suitability for cryptographic applications. In general it should only be
@@ -208,6 +208,35 @@
 /// [`BlockRngCore`]: block::BlockRngCore
 pub trait CryptoRng {}
 
+/// An extension trait that is automatically implemented for any type
+/// implementing [`RngCore`] and [`CryptoRng`].
+///
+/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
+/// the [`CryptoRngCore::as_rngcore`] method.
+///
+/// # Example
+///
+/// ```
+/// use rand_core::CryptoRngCore;
+///
+/// #[allow(unused)]
+/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
+///     let mut buf = [0u8; 32];
+///     rng.fill_bytes(&mut buf);
+///     buf
+/// }
+/// ```
+pub trait CryptoRngCore: CryptoRng + RngCore {
+    /// Upcast to an [`RngCore`] trait object.
+    fn as_rngcore(&mut self) -> &mut dyn RngCore;
+}
+
+impl<T: CryptoRng + RngCore> CryptoRngCore for T {
+    fn as_rngcore(&mut self) -> &mut dyn RngCore {
+        self
+    }
+}
+
 /// A random number generator that can be explicitly seeded.
 ///
 /// This trait encapsulates the low-level functionality common to all
@@ -215,7 +244,7 @@
 ///
 /// [`rand`]: https://docs.rs/rand
 pub trait SeedableRng: Sized {
-    /// Seed type, which is restricted to types mutably-dereferencable as `u8`
+    /// Seed type, which is restricted to types mutably-dereferenceable as `u8`
     /// arrays (we recommend `[u8; N]` for some `N`).
     ///
     /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
@@ -448,10 +477,10 @@
     }
 }
 
-// Implement `CryptoRng` for references to an `CryptoRng`.
+// Implement `CryptoRng` for references to a `CryptoRng`.
 impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
 
-// Implement `CryptoRng` for boxed references to an `CryptoRng`.
+// Implement `CryptoRng` for boxed references to a `CryptoRng`.
 #[cfg(feature = "alloc")]
 impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}