Skip to content

Conversation

@mrdomino
Copy link
Contributor

@mrdomino mrdomino commented Dec 2, 2025

Breaking changes

  • Encoding::Repr is no longer required to implement Copy, so consumers of Encoding::Repr will need to explicitly call clone.

  • The numbers produced by both random_bits and random_mod will generally be different, and calling these functions will leave the RNG in a different state, than before.

Summary

This essentially applies #285 to random_bits as well as random_mod. Both functions behave the same way now, with the only difference being that random_mod adds rejection sampling; otherwise both will produce the same numbers over the same entropy stream.

Questions of platform dependence are now easy; we do not define these algorithms in terms of sequences of machine words but of bytes. Randomly sampled Uints are now always constructed little-endian over the entropy stream. This does not preclude future machine-specific optimizations, but given how perilous the landscape has been (e.g. #1018), I’ve elected to err in the direction of parsimony rather than performance for this change.

This leverages the existing work making Uint implement Encoding. It additionally needs Encoding on BoxedUint to make RandomMod and RandomBits work there; this is implemented, but requires dropping the Copy constraint on Encoding::Repr.

This change also uses a variable- rather than constant-time comparison for the rejection loop. The only real reason to do this is the linked compiler bug, but the only downside is that this makes random_mod leak somewhat more timing data than it otherwise would. However, random_mod inherently must leak some timing data (in the form of rejections), and so should arguably just be named random_mod_vartime in the first place.

Fixes #1009

In order to use `random_bits_core` in `random_mod_core`, we need to make
it produce `R::Error`; then we call `map_err` in `RandomBits`, rather
than in `random_bits_core`, to get a `RandomBitsError`.
## Breaking changes

- `Encoding::Repr` can no longer be assumed to implement `Copy`, so
  consumers of `Encoding::Repr` will need to explicitly call `clone`.

- The numbers produced by both `random_bits` and `random_mod` will
  generally be different, and calling these functions will leave the RNG
  in a different state, than before.

## Summary

This essentially applies RustCrypto#285 to `random_bits`
as well as `random_mod`. Both functions behave the same way now, with
the only difference being that `random_mod` adds rejection sampling;
otherwise both will produce the same numbers over the same entropy
stream.

Questions of platform dependence are now easy; we do not define these
algorithms in terms of machine words but in terms of bytes. Randomly
sampled `Uint`s are constructed little-endian over the entropy stream.

This leverages the existing work making `Uint` implement `Encoding`. It
additionally needs `Encoding` on `BoxedUint` to make `RandomMod` and
`RandomBits` work there; this is implemented, but requires dropping the
`Copy` constraint on `Encoding::Repr`.

This change also uses a variable- rather than constant-time comparison
for the rejection loop. The only real reason to do this is the linked
[compiler bug][0], but the only downside is that this makes `random_mod`
leak somewhat more timing data than it otherwise would. However,
`random_mod` inherently must leak some timing data (in the form of
rejections), and so should arguably just be named `random_mod_vartime`
in the first place.

[0]: rust-lang/rust#149522
@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 84.61538% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.82%. Comparing base (59b58ec) to head (2bbb108).

Files with missing lines Patch % Lines
src/uint/boxed/encoding.rs 50.00% 7 Missing ⚠️
src/uint/rand.rs 94.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1026      +/-   ##
==========================================
- Coverage   79.87%   79.82%   -0.05%     
==========================================
  Files         163      163              
  Lines       17737    17752      +15     
==========================================
+ Hits        14167    14171       +4     
- Misses       3570     3581      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tarcieri
Copy link
Member

tarcieri commented Dec 2, 2025

Encoding::Repr is no longer required to implement Copy, so consumers of Encoding::Repr will need to explicitly call clone.

That's probably a good change if we want to be able to impl Encoding for BoxedUint where it would be nice to use Vec<u8> for that value

@mrdomino mrdomino marked this pull request as ready for review December 2, 2025 06:20
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.

random_mod is not platform-independent

2 participants