Skip to content

Switch dice RNG - #2473

Open
mark9064 wants to merge 1 commit into
InfiniTimeOrg:mainfrom
mark9064:dice-rng
Open

Switch dice RNG#2473
mark9064 wants to merge 1 commit into
InfiniTimeOrg:mainfrom
mark9064:dice-rng

Conversation

@mark9064

@mark9064 mark9064 commented Aug 9, 2026

Copy link
Copy Markdown
Member

The mersenne twister uses multiple KBs of state and is not needed for a dice app in terms of RNG quality

When we pick up GCC16, we can switch to philox4x32

This is an alternative to #2385: while I agree that PR is a better RNG than the one here, I don't think it's worth carrying a new dependency / implementation for it

@mark9064 mark9064 added the maintenance Background work label Aug 9, 2026
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Build size and comparison to main:

Section Size Difference
text 385024B -208B
data 944B 0B
bss 22640B 0B

Run in InfiniEmu

@DavisNT

DavisNT commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

@mark9064 Could we just use BT chip RNG?
I would be happy to write something similar to:

/*
* Passkey is a 6 digits code (1'000'000 possibilities).
* It is important every possible value has an equal probability
* of getting generated. Simply applying a modulo creates a bias
* since 2^32 is not a multiple of 1'000'000.
* To prevent that, we can reject values greater than 999'999.
*
* Rejecting values would happen a lot since 2^32-1 is way greater
* than 1'000'000. An optimisation is to use a multiple of 1'000'000.
* The greatest multiple of 1'000'000 lesser than 2^32-1 is
* 4'294'000'000.
*
* Great explanation at:
* https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
*/
uint32_t passkey_rand;
do {
passkey_rand = ble_ll_rand();
} while (passkey_rand > 4293999999);
pkey.passkey = passkey_rand % 1000000;
probably adding a simple XOR of all 4 bytes if the requested random value is a small power of 2 (e.g. a coin toss).

I think using BT chip's RNG would need very little code and also would provide a good (more secure) randomness.

P.S. We could also XOR "in" the existing seeds from motionController and xTaskGetTickCount() as additional sources of entropy. Or we could even do a clock jitter against xTaskGetTickCount() as the additional source - in any case the code should be small and lightweight.

@mark9064

Copy link
Copy Markdown
Member Author

I don't think this complexity is at all required. I think you'll find that this RNG is perfectly fine

Seriously, give it a go if you're worried :)

Reaching out to hardware opens up the risk of more problems in terms of correctness, performance and error handling

@DavisNT

DavisNT commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

@mark9064 You are right that tightly-coupling Dice app to BT chip is a very counter-intuitive thing and has a potential of causing issues later (especially when adopting to new hardware).

The thing that is worrying me when using a simple (non-secure) PRNG in such application is ability to gather enough data to reconstruct the internal state of PRNG (afaik std::minstd_rand has only 32-bits of internal state, so a little more than 13 rolls of 6 side dice should allow to reconstruct the internal state) and predict all subsequent PRNG output.

Could it be possible to reinitialize the PRNG on every roll of the Dice app? It would not only prevent a security issue like this, but also have a pretty cool side effect - the Dice app acting more like a physical dice (being affected by how it is shaken, though in a very hard to predict manner). 😎
I have created #2478 with such change and it does not increase firmware size at all.

@mark9064

Copy link
Copy Markdown
Member Author

I'm not sure how worried we should be about state recovery attacks on a watch dice app. Isn't the goal to have randomly distributed outputs, not randomly distributed and mathematically unpredictable outputs? Like in any situation where the dice app is going to be used, I'm really struggling to think of a case where being able to predict the RNG is a problem

I get it's nice to have things theoretically perfect, but it just seems like extra complexity to me

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

Labels

maintenance Background work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants