зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1806766 - Update rand_core to 0.6.4. r=emilio,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D165510
This commit is contained in:
Родитель
1e26a73a6b
Коммит
30676e53f8
|
@ -4410,9 +4410,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
|
|
@ -1422,6 +1422,11 @@ The core logic is very simple, and acts as an abstraction trait for `Cell<T>`
|
|||
and `AtomicT`.
|
||||
"""
|
||||
|
||||
[[audits.rand_core]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.6.3 -> 0.6.4"
|
||||
|
||||
[[audits.raw-window-handle]]
|
||||
who = "Jim Blandy <jimb@red-bean.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"25e64e1e95a61d0ba0eb476b3512cdacec6e64cbad44e560678efa16242ea291","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"262864cafee79bee4b22c53f4ba25bb938bab7e96495042241242e3472ba0262","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"bb3bd3831adc9eaabbcea108ab7f02f5837e9d2f81e872ffd7d340ad466df4de","src/block.rs":"724d13d7721396b46c18999231823c3ea9f6736492102c7c05ee057606372c39","src/error.rs":"0b6d5a188a256fa367dfa368e7dd846b58977a957489c03902307eb78ce4c9e8","src/impls.rs":"d6a97255d92c06bdd1a54590648bbe4cfb41111ac9e761496baf6b7eb5e92f6a","src/le.rs":"f302239d09cc8d915aa8d4fe46c32c8981900cb20d42b12eef9c34e2e820bc88","src/lib.rs":"8b17ae9af2eb43c28320a87893cb234c3889b4dd6246899bbc11e310ce142fa6","src/os.rs":"47849479e19c43dd01259eb14be7b4daf8474d23567dc32a1547c10b108b7069"},"package":"d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"}
|
||||
{"files":{"CHANGELOG.md":"a33a4318dd822ef757ec79c5e6027d50d9feee5c40f85d9aadf0f598eb7ef1b7","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"4a6762f8364d1a60f1436f4ba7d710de22465722340d2028101fcbd68e89396f","LICENSE-APACHE":"6df43f6f4b5d4587f3d8d71e45532c688fd168afa5fe89d571cb32fa09c4ef51","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"bb3bd3831adc9eaabbcea108ab7f02f5837e9d2f81e872ffd7d340ad466df4de","src/block.rs":"c0b606dc404a1f4b25eebf388e9c0da583ee571214cdcb0bac1b592450d6b4fa","src/error.rs":"c34af905a9ffbae65970f508a9e74480b56747128d05ad350475150898fc6452","src/impls.rs":"b861532f8a3500de6bd0e926b3677a15261df4b12d253e4a8fd6acc5e64f1d36","src/le.rs":"f302239d09cc8d915aa8d4fe46c32c8981900cb20d42b12eef9c34e2e820bc88","src/lib.rs":"df270489b859465fce144098d5e709b318d9f3b703a92f4a28e5f74334119107","src/os.rs":"47849479e19c43dd01259eb14be7b4daf8474d23567dc32a1547c10b108b7069"},"package":"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"}
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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 {
|
||||
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());
|
||||
// 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.
|
||||
|
|
|
@ -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> {}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче