Skip to content

Ugrade rand to 0.10.1#2042

Merged
ImplOfAnImpl merged 6 commits intorand_upgrade_autorename_gen_to_randomfrom
rand_upgrade
Apr 23, 2026
Merged

Ugrade rand to 0.10.1#2042
ImplOfAnImpl merged 6 commits intorand_upgrade_autorename_gen_to_randomfrom
rand_upgrade

Conversation

@ImplOfAnImpl
Copy link
Copy Markdown
Contributor

@ImplOfAnImpl ImplOfAnImpl commented Apr 20, 2026

Initially this PR was intended to address the recently discovered unsoundness in rand, where the fix was only available in versions 0.9.3 and 0.10.1, but not in 0.8.x (which we use widely in master) and earlier versions.
It turned out that 0.8.x has also been patched and 0.8.6 is sound. But I still would like to merge this:

  • First of all the work has already been done and I don't want to throw it away. And in general it's nicer to have a more recent version of a dependency.
  • Trait bounds are cleaner with newer versions of rand, since CryptoRng is now a sub-trait of Rng.
  • Eventually we'd want to switch to 2024 edition of Rust, where gen is a reserved keyword, so we'd have to do a massive auto-replace anyway, changing gen to r#gen. The latter is ugly, so why not just upgrade rand to a newer version, where this function has already been renamed to random.

So in this PR the version of rand that we directly use was upped to 0.10.1. Some of our dependencies still use 0.9.x and 0.8.x, so when a 0.10 RNG has to be passed to a method where an older one is expected, an adapter struct is used.

To avoid having to use an adapter struct with the random_using call that comes from fixed_hash, I created a wrapper for fixed_hash::construct_fixed_hash!, so that the constructed hash's random_using method accepts a 0.10 RNG instead of a 0.8 one.
After this, the number of places where an adapter has to be used is relatively small.

The list of breaking changes that happened in 0.9.x is here and in 0.10.x here.

Some notable changes:

  • Since gen is a reserved keyword in Rust 2024, the corresponding method was renamed to random. For consistency, gen_range became random_range and gen_bool became random_bool.
  • RngCore trait was renamed to Rng and the original Rng to RngExt.
  • As I've already said, CryptoRng is now a sub-trait of Rng, so impl Rng + CryptoRng can be replaced with just impl CryptoRng and the trait RngCoreAndCrypto is no longer needed.
  • Traits TryRng/TryCryptoRng were added, which are fallible versions of Rng/CryptoRng. Also, now TryRng<Error = Infallible> is a sub-trait of Rng and Rng is implemented for every R: TryRng<Error = Infallible>.
    And infallible RNGs now have to implement TryRng<Error = Infallible> instead of Rng.
  • StepRng, which we used for testing, was removed, so I had to add a custom struct in test-utils instead.
  • The choose_multiple method is now deprecated in favor of sample, but the difference is only in the name.
  • The distribution Standard was renamed to StandardUniform and it's no longer implemented for usize, so rng.random::<usize>() no longer compiles.
  • SliceRandom trait has been split into three traits: IndexedRandom, IndexedMutRandom and SliceRandom.

Additionally I updated secp256k1 to 0.31 (it uses rand 0.9). There is also 0.32, but according to their changelog - https://github.com/rust-bitcoin/rust-secp256k1/blob/master/CHANGELOG.md - there are lots of breaking changes and they still use rand 0.9, so I decided to leave it at 0.31 for now.
Related changes:
* methods that accept a slice were deprecated in favor of similar functions that accept a fixed-size array (Signature::from_slice -> from_byte_array, Message::from_digest_slice -> from_digest). So slice-to-array conversion now has to be done at the caller side.
* Signature::serialize was deprecated in favor of to_byte_array (only the name differs).
I reverted the update of secp256k1 to 0.31, because there were issues with building it for wasm. (More precisely, its dependency secp256k1-sys wasn't compiling because apparently the underlying C library uses memmove, but the crate's wasm-sysroot/string.h only declares memset/memcpy/memcmp. Looks like this is fixed in 0.32, but 0.32 hasn't been released yet it seems).

P.S.

  • In attempt to make this PR smaller, I've split off all the autoreplacing of "gen" with "random" and the similar ones into a separate PR Rand upgrade: autoreplace "gen" with "random" etc #2041. That code in that PR will obviously not compile. After both PRs are approved I'll merge this one into 2041 and then merge both to master.
  • deny.toml still has the exception for the rand unsoundness issue, because technically we still use rand 0.7.x as well, which is brought in by the probabilistic-collections crate. But we don't use probabilistic-collections in a way that would make it construct a new RNG, so the unsoundness is only "technical".
  • In wasm bindings, the generated js glue no longer works with nodejs v18. Apparently, getrandom v0.2 (used by rand 0.8) had some workarounds related to older nodejs versions that were removed in getrandom v0.3. But nodejs v18 is long past its EOL, so I upped node-version in .github/workflows/wasm.yml to 20.x (BTW nodejs 20 will also reach it EOL at the end of this month).

@ImplOfAnImpl ImplOfAnImpl force-pushed the rand_upgrade branch 2 times, most recently from 923130c to f6d8d3b Compare April 20, 2026 17:49
@ImplOfAnImpl ImplOfAnImpl marked this pull request as ready for review April 20, 2026 20:14
@ImplOfAnImpl ImplOfAnImpl force-pushed the rand_upgrade_autorename_gen_to_random branch from 2e45c58 to c9f47dd Compare April 23, 2026 10:20
@ImplOfAnImpl ImplOfAnImpl merged commit 252725e into rand_upgrade_autorename_gen_to_random Apr 23, 2026
20 checks passed
@ImplOfAnImpl ImplOfAnImpl deleted the rand_upgrade branch April 23, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants