aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:04:15 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:04:15 +0000
commita5fe3da1db87caae5ba6d1280dc26e206f5213f9 (patch)
treee23ce1a676a8e3c02b7eb1ef818b9fd2a8256ff4
parenta3140070a9531e36a7d3ea10d88f9ad64dd7a44b (diff)
parent1df27553ccea135ec8c64649af6e018b0b277e98 (diff)
downloadrand_core-android14-mainline-cellbroadcast-release.tar.gz
Change-Id: Ibd3503b2ae94dab27935128895ba217f8f2a2b64
-rw-r--r--.cargo_vcs_info.json7
-rw-r--r--Android.bp5
-rw-r--r--CHANGELOG.md5
-rw-r--r--Cargo.toml43
-rw-r--r--Cargo.toml.orig20
-rw-r--r--LICENSE-APACHE14
-rw-r--r--METADATA14
-rw-r--r--TEST_MAPPING56
-rw-r--r--src/block.rs128
-rw-r--r--src/error.rs2
-rw-r--r--src/impls.rs83
-rw-r--r--src/lib.rs37
12 files changed, 289 insertions, 125 deletions
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 a2ccace..841b4e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@ rust_library {
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,7 @@ rust_library {
"//apex_available:platform",
"com.android.virt",
],
+ product_available: true,
vendor_available: true,
}
@@ -66,7 +67,7 @@ rust_test {
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 @@ All notable changes to this project will be documented in this file.
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 @@ optional = true
[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 @@ keywords = ["random", "rng"]
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 @@ rustdoc-args = ["--cfg", "doc_cfg"]
[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 @@ APPENDIX: How to apply the Apache License to your work.
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 @@ third_party {
}
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"
- }
- ],
- "presubmit": [
- {
- "name": "ZipFuseTest"
- },
- {
- "name": "apkdmverity.test"
},
{
- "name": "authfs_device_test_src_lib"
+ "path": "external/rust/crates/zerocopy"
},
{
- "name": "keystore2_test"
+ "path": "external/uwb/src"
},
{
- "name": "keystore2_test_utils_test"
+ "path": "packages/modules/Virtualization/apkdmverity"
},
{
- "name": "legacykeystore_test"
+ "path": "packages/modules/Virtualization/authfs"
},
{
- "name": "microdroid_manager_test"
- },
- {
- "name": "rand_core_test_src_lib"
+ "path": "packages/modules/Virtualization/avmd"
},
{
- "name": "virtualizationservice_device_test"
- }
- ],
- "presubmit-rust": [
- {
- "name": "ZipFuseTest"
+ "path": "packages/modules/Virtualization/libs/devicemapper"
},
{
- "name": "apkdmverity.test"
+ "path": "packages/modules/Virtualization/microdroid_manager"
},
{
- "name": "authfs_device_test_src_lib"
+ "path": "packages/modules/Virtualization/virtualizationmanager"
},
{
- "name": "keystore2_test"
+ "path": "packages/modules/Virtualization/vm"
},
{
- "name": "keystore2_test_utils_test"
+ "path": "packages/modules/Virtualization/zipfuse"
},
{
- "name": "legacykeystore_test"
+ "path": "system/security/keystore2"
},
{
- "name": "microdroid_manager_test"
- },
+ "path": "system/security/keystore2/legacykeystore"
+ }
+ ],
+ "presubmit": [
{
"name": "rand_core_test_src_lib"
- },
+ }
+ ],
+ "presubmit-rust": [
{
- "name": "virtualizationservice_device_test"
+ "name": "rand_core_test_src_lib"
}
]
}
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 @@ pub trait BlockRngCore {
/// [`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 @@ where
{
#[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 + SeedableRng> SeedableRng for BlockRng64<R> {
}
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 @@ impl Error {
///
/// 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 @@ pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
}
}
-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;
-
- // 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());
- }
- }
+trait Observable: Copy {
+ type Bytes: AsRef<[u8]>;
+ fn to_le_bytes(self) -> Self::Bytes;
+
+ // 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 @@ macro_rules! fill_via_chunks {
/// }
/// ```
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 @@ pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
///
/// 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 @@ pub trait RngCore {
/// 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 @@ pub trait RngCore {
/// [`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 @@ pub trait CryptoRng {}
///
/// [`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 @@ impl std::io::Read for dyn RngCore {
}
}
-// 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> {}