Skip to content

add crandom.py, for our RNG, where we mix stuff with os.urandom - #10794

Draft
SomberNight wants to merge 2 commits into
spesmilo:masterfrom
SomberNight:202607_crandom
Draft

add crandom.py, for our RNG, where we mix stuff with os.urandom#10794
SomberNight wants to merge 2 commits into
spesmilo:masterfrom
SomberNight:202607_crandom

Conversation

@SomberNight

@SomberNight SomberNight commented Aug 3, 2026

Copy link
Copy Markdown
Member

(still WIP)

Currently we rely on os.urandom() ~everywhere for cryptographically secure randomness. Existing code already checks at runtime that the output of os.urandom() looks at least somewhat sane (see if it compresses with zlib) and hard-fails if it does not.

However, os.urandom could still be subtly "broken" (undetected by us) and produce bad quality output. That's the motivation of the new code here. We expect os.urandom to work well, BUT if it undetectably does not, mixing in other sources of entropy mitigates the situation somewhat.

This PR introduces a new module crandom.py that manages the RNG, and that our other code should call. Extreme care should be taken here not to make things worse than the status quo by "rolling our own" thing.

The logic is split across two modules: crandom.py and crandom_env.py.

  • The core sensitive logic (RNG mixing, extracting random bytes) is in crandom.py, which is absolutely security critical and is kept concise to ease review.
  • crandom_env.py contains secondary sources of entropy and potentially platform-specific code. It is just a companion to crandom.py and is only intended to be accessed from there. Even if all the entropy sources listed in crandom_env.py are broken, assuming os.urandom() produces high quality random, crandom.py should never produce low-quality random output. Hence crandom_env.py is much less critical tro review in depth.

This is inspired by https://github.com/bitcoin/bitcoin/blob/67efced1fc83a0b7215cc1513e7c4754fee0f12f/src/random.h#L25, which is significantly more advanced. But I wanted to (1) lessen our dependence on os.urandom(), (2) while keeping it simple.

@SomberNight SomberNight added the security 🔐 technical issue that affects security of funds label Aug 3, 2026
Currently we rely on `os.urandom()` ~everywhere for cryptographically secure randomness.
Existing code already checks at runtime that the output of `os.urandom()` looks at least somewhat sane (see if it compresses with zlib) and hard-fails if it does not.

However, `os.urandom` could still be subtly "broken" (undetected by us) and produce bad quality output. That's the motivation of the new code here. We expect `os.urandom` to work well, BUT if it undetectably does not, mixing in other sources of entropy mitigates the situation somewhat.

This PR introduces a new module `crandom.py` that manages the RNG, and that our other code should call. Extreme care should be taken here not to make things worse than the status quo by "rolling our own" thing.

The logic is split across two modules: `crandom.py` and `crandom_env.py`.
- The core sensitive logic (RNG mixing, extracting random bytes) is in `crandom.py`,
  which is absolutely security critical and is kept concise to ease review.
- `crandom_env.py` contains secondary sources of entropy and potentially platform-specific code.
  It is just a companion to `crandom.py` and is only intended to be accessed from there.
  Even if all the entropy sources listed in `crandom_env.py` are broken, assuming `os.urandom()` produces high quality random, `crandom.py` should never produce low-quality random output. Hence `crandom_env.py` is much less critical tro review in depth.

This is inspired by https://github.com/bitcoin/bitcoin/blob/67efced1fc83a0b7215cc1513e7c4754fee0f12f/src/random.h#L25, which is significantly more advanced. But I wanted to (1) lessen our dependence on `os.urandom()`, (2) while keeping it simple.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security 🔐 technical issue that affects security of funds

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant