Skip to content

CHANGE: Re-enable ReseedingRng #1748

Description

@boquan-fang

Summary

How does this affect the API / end-user? (Include API-breaking changes, value-breaking changes and API additions.)

rand's user can access the ReseedingRng struct that was previously avaible until rand v0.10. This struct has been removed in v0.10. A related issue: #1721.

Details

What changes does this require internally?

It might be as simple as reverting this PR: #1722.

git revert bfa14ab4d0f2a5c161478aafe4a1edee02547f03

Essentially, we would like this struct to be made available, instead of be deprecated completely.

Motivation

What is the motivation for this change?

Since every change has a cost (even if just API churn or extra code size), every change must have sufficient motivation. This is arguably the most important part of the RFC.

We use rand for generating random bytes in s2n-quic: a rust implementation of the QUIC protocol. We use rand for both public and private generator. We will add more details about how we use ReseedingRng in our own issue: aws/s2n-quic#2986.

Alternatives

Which alternatives might be considered, and why or why not?

One alternative is to implement a ReseedingRng wrapper in s2n-quic for our own usage. I think having it from rand is more preferable.

Activity

  1. dhardy commented on Feb 24, 2026

    @dhardy
    Member

    Thanks for the report; it's been hard to find real uses of ReseedingRng outside of rand. I might reconsider if there are more requests, but find it unlikely given that most users will not need ReseedingRng and its removal significantly simplified rand.

    For now, I'd recommend either copying ReseedingRng from before #1722 or merging its functionality into your RNGs as we did with ThreadRng.

  2. LiosK commented on Feb 24, 2026

    @LiosK
    Contributor

    Could it be an option to expose BlockRng<ReseedingCore>> as say ReseedingStdRng? I know StdRng is sufficient usually, but since ThreadRng exists, I am strongly tempted to reproduce the "best practice" when a Send + Sync alternative is desired.

  3. LiosK commented on Feb 25, 2026

    @LiosK
    Contributor

    Or something like struct ThreadRngCore(BlockRng<ReseedingCore>);. ReseedingRng was a clunky solution to mimic ThreadRng behavior so will not be necessary if the ThreadRng logic is accessible.

  4. dhardy commented on Feb 25, 2026

    @dhardy
    Member

    So, something like this?

    pub struct ReseedingStdRng { ... }
    impl ReseedingStdRng {
        pub fn new() > Result<Self, SysError>;
        pub fn reseed(&mut self) > Result<(), SysError>;
    }
    impl TryRng for ReseedingStdRng {
        type Error = Infallible;
        // ...
    }
    impl TryCryptoRng for ReseedingStdRng {}

    This should be a reasonable addition: it can replace most of the internals of ThreadRng without unnecessary parametrisation.

    Would someone like to make a PR? (Not a promise, but I don't currently see a reason to block this.)

  5. newpavlov commented on Feb 25, 2026

    @newpavlov
    Member

    ThreadRng does not use ReseedingRng in rand v0.10. It no longer needs it since the new implementation gets number of generated blocks from the ChaCha cipher core.

    We could re-introduce ReseedingRng<R: SeedableRng>, but I think it should be done in a separate RNG crate.

    Since every change has a cost (even if just API churn or extra code size), every change must have sufficient motivation.

    Every part of public API also has cost. Both for users and maintainers.

  6. LiosK commented on Feb 25, 2026

    @LiosK
    Contributor

    Will try to make a PR later.

  7. dhardy commented on Feb 25, 2026

    @dhardy
    Member

    ReseedingRng<R: SeedableRng>

    No. To making it generic over R we'd need R: block::Generator + SeedableRng and then we'd want the block::CryptoGenerator trait again. Much simpler to just have ReseedingStdRng.

    But you are right that even this simpler version probably doesn't need to be in rand. Why not put your own copy in s2n-quic? I doubt many crates would use ReseedingStdRng (but let us know if yours does).

  8. newpavlov commented on Feb 25, 2026

    @newpavlov
    Member

    I meant the less efficient but much simpler variant of ReseedingRng which checks the reseeding condition on each next_u32/u64/fill_bytes call instead of doing it on each block generation. IIRC I even seen it implemented internally in some crate while researching how ReseedingRng used in the wild.

  9. LiosK commented on Mar 29, 2026

    @LiosK
    Contributor

    FYI, I published the reseeding_rng crate - a simplified reimplementation of ReseedingRng for use with rand v0.10. I went with a TryRng-based approach that checks the reseeding condition on every call to try_next_u32/try_next_u64/try_fill_bytes, since it makes for a nicer API.

    Performance is the obvious concern, but benchmarking shows the overhead is pretty negligible - under a nanosecond per call, probably just a couple of extra machine instructions. The catch is that a nanosecond can still eat up ~20% of total call time, so it's not nothing.

    Also, working on this made me appreciate how ergonomic the super/sub trait relationships in v0.10 are for this kind of thing - really nice design!

    EDIT (addition): I just noticed that the Generator-based implementation can sometimes be noticeably slower than the TryRng-based one when calling try_fill_bytes() with large buffers like [u8; 1024 * 4]. This is presumably because the TryRng-based one checks the reseeding condition once per try_fill_bytes() call usually, while the Generator-based one checks it multiple times.

  10. WesleyAC commented on May 12, 2026

    @WesleyAC

    We used ReseedingRng in Arti. We've switched to the reseeding_rng crate (thank @LiosK), but just wanted to mention here that we were a user of this API. Our use of it is here.

  11. dhardy commented on May 14, 2026

    @dhardy
    Member

    @WesleyAC I hadn't expected to see a frequently-reseeding ChaCha generator over JitterRng. I guess it's good enough as an additional source of entropy, though we don't recommend it as a primary source of entropy (I'm sure you've already seen #699). But is ReseedingRng the right tool for this anyway? In-lining its code wouldn't add much complexity and would allow mixing the old output with a fresh seed.

    If we do make some form of reseeding-rng public in rand, I don't believe we'd make it as configurable as the old ReseedingRng.

  12. LiosK commented on May 14, 2026

    @LiosK
    Contributor

    Btw, inlining ReseedingRng is easy, but writing tests to make sure it's properly working is not straightforward because it's indeterministic. That is one reason why users want to rely on a credible external crate.

  13. dhardy commented on Aug 20, 2026

    @dhardy
    Member

    See #1828.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions