Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add `rand_core::InfallibleRng` marker trait by newpavlov · Pull Request #1412 · rust-random/rand · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rand_chacha/src/chacha.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
use self::core::fmt;
use crate::guts::ChaCha;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(feature = "serde1")] use serde::{Serialize, Deserialize, Serializer, Deserializer};

Expand DownExpand Up@@ -101,6 +101,8 @@ macro_rules! chacha_impl {

impl CryptoBlockRng for $ChaChaXCore {}

impl InfallibleRng for $ChaChaXRng {}

/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
Expand Down
8 changes: 8 additions & 0 deletions rand_core/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -212,6 +212,14 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng: RngCore {}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to never return errors from the [`RngCore::try_fill_bytes`] method
/// and never panic on unwrapping [`Error`] while calling other methods.
///
/// This trait is usually implemented by PRNGs, as opposed to OS, hardware,
/// and periodically-reseeded RNGs, which may fail with IO errors.
pub trait InfallibleRng: RngCore {}
Comment on lines +215 to +221

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting just for visibility of the significant addition.

It falls into the same trap as std::iter::TrustedLen in that it promises something about another trait.

I think I'm okay with this, but worth thinking about / getting more input on.

@newpavlovnewpavlovMar 22, 2024

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about different alternatives and it looks like it's the simplest option. Plus, we already have the CryptoRng trait.

One potential option is to make error an associated type (and CryptoRng may become associated bool constant). This way we could use Infallible by default. But without trait aliases it would be significantly less ergonomic to work with. Here is a draft of how it could look in future: playground.

@dhardydhardyMar 22, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding associated types + consts to RngCore changes the meaning on every existing usage as a generic bound.

For "crypto grade", I prefer the trait-inheritance model. After all, every CryptoRng is also a valid RNG. Also, can't have CRYPTO_STRONG default to true on all impls.

For infallibility, we'd at least need a bound on that error type: Error: std::error::Error or Error: Into<Something> where Something is a summarized RNG error (NotInitialized, EndOfSequence, IOError, MissingHardwareDevice, ???).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every CryptoRng is also a valid RNG.

Yes, and? I don't see why the associated constant would be at odds with it. "Cryptographically strong" is a binary property of RNG, which can be modeled perfectly by an associated bool constant.

Also, can't have CRYPTO_STRONG default to true on all impls.

Yes, it should've been false in my example.

For infallibility, we'd at least need a bound on that error type

Sure. But I think it's an unimportant detail. Without stabilization of at least trait aliases, this approach is, arguably, not practical anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and?

Only that this case does work well with the trait inheritance model; not every boolean property does.


/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
Expand Down
5 changes: 4 additions & 1 deletion rand_pcg/src/pcg128.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (XSL RR 128/64 (LCG) variant).
Expand DownExpand Up@@ -159,6 +159,7 @@ impl RngCore for Lcg128Xsl64 {
}
}

impl InfallibleRng for Lcg128Xsl64 {}

/// A PCG random number generator (XSL 128/64 (MCG) variant).
///
Expand DownExpand Up@@ -269,6 +270,8 @@ impl RngCore for Mcg128Xsl64 {
}
}

impl InfallibleRng for Mcg128Xsl64 {}

#[inline(always)]
fn output_xsl_rr(state: u128) -> u64 {
// Output function XSL RR ("xorshift low (bits), random rotation")
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg128cm.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
const MULTIPLIER: u64 = 15750249268501108917;

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

/// A PCG random number generator (CM DXSM 128/64 (LCG) variant).
Expand DownExpand Up@@ -165,6 +165,8 @@ impl RngCore for Lcg128CmDxsm64 {
}
}

impl InfallibleRng for Lcg128CmDxsm64 {}

#[inline(always)]
fn output_dxsm(state: u128) -> u64 {
// See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016
Expand Down
4 changes: 3 additions & 1 deletion rand_pcg/src/pcg64.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@
//! PCG random number generators

use core::fmt;
use rand_core::{impls, le, Error, RngCore, SeedableRng};
use rand_core::{impls, le, Error, InfallibleRng, RngCore, SeedableRng};
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};

// This is the default multiplier used by PCG for 64-bit state.
Expand DownExpand Up@@ -167,3 +167,5 @@ impl RngCore for Lcg64Xsh32 {
Ok(())
}
}

impl InfallibleRng for Lcg64Xsh32 {}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,7 +92,7 @@ macro_rules! error { ($($x:tt)*) => (
) }

// Re-exports from rand_core
pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
pub use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

// Public modules
pub mod distributions;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/mock.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! Mock random number generator

use rand_core::{impls, Error, RngCore};
use rand_core::{impls, Error, InfallibleRng, RngCore};

#[cfg(feature = "serde1")]
use serde::{Serialize, Deserialize};
Expand DownExpand Up@@ -81,6 +81,8 @@ impl RngCore for StepRng {
}
}

impl InfallibleRng for StepRng {}

#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde1"))]
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/small.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! A small fast RNG

use rand_core::{Error, RngCore, SeedableRng};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(target_pointer_width = "64")]
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
Expand DownExpand Up@@ -64,6 +64,8 @@ impl RngCore for SmallRng {
}
}

impl InfallibleRng for SmallRng {}

impl SmallRng {
/// Construct an instance seeded from another `Rng`
///
Expand Down
3 changes: 2 additions & 1 deletion src/rngs/std.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@

//! The standard RNG

use crate::{CryptoRng, Error, RngCore, SeedableRng};
use rand_core::{CryptoRng, Error, InfallibleRng, RngCore, SeedableRng};

#[cfg(any(test, feature = "getrandom"))]
pub(crate) use rand_chacha::ChaCha12Core as Core;
Expand DownExpand Up@@ -73,6 +73,7 @@ impl SeedableRng for StdRng {

impl CryptoRng for StdRng {}

impl InfallibleRng for StdRng {}

#[cfg(test)]
mod test {
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro128plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::{next_u64_via_u32, fill_bytes_via_next};
use rand_core::le::read_u32_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro128++ random number generator.
///
Expand DownExpand Up@@ -97,6 +97,8 @@ impl RngCore for Xoshiro128PlusPlus {
}
}

impl InfallibleRng for Xoshiro128PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 3 additions & 1 deletion src/rngs/xoshiro256plusplus.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
use rand_core::impls::fill_bytes_via_next;
use rand_core::le::read_u64_into;
use rand_core::{SeedableRng, RngCore, Error};
use rand_core::{Error, InfallibleRng, RngCore, SeedableRng};

/// A xoshiro256++ random number generator.
///
Expand DownExpand Up@@ -99,6 +99,8 @@ impl RngCore for Xoshiro256PlusPlus {
}
}

impl InfallibleRng for Xoshiro256PlusPlus {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down