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.

Fixes

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.

Fixes #1009

@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 (401e98e) to head (a25867b).
⚠️ Report is 1 commits behind head on master.

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       17735    17750      +15     
==========================================
+ Hits        14165    14169       +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
@mrdomino
Copy link
Contributor Author

mrdomino commented Dec 9, 2025

@tarcieri PTAL - I added a mitigation for the compiler bug that allows us to keep using ct_lt for the comparison.

NB. this mitigation could also be applied to any of the other attempts, including the original reverted PR, at your preference; it may also make sense to merge it separately, in which case feel free to cherry-pick the commit onto a new branch or I can do the same.

@mrdomino
Copy link
Contributor Author

#1029 has just the cherry-picked mitigation commit.

@tarcieri
Copy link
Member

@mrdomino can you rebase now that #1029 is merged?

## 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`.

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`.

[0]: rust-lang/rust#149522
@mrdomino mrdomino force-pushed the random-mod-bytewise branch from f98c931 to a25867b Compare December 10, 2025 18:10
@mrdomino
Copy link
Contributor Author

Done. Two clean commits, one that adds the test (passing on 64-bit, failing on 32-bit), one that implements the change (and shows the diffs against the test.)

@tarcieri tarcieri merged commit ba4f0e0 into RustCrypto:master Dec 10, 2025
27 checks passed
@mrdomino mrdomino deleted the random-mod-bytewise branch December 12, 2025 18:57
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