Skip to content

math/rand global RNG always uses a fixed seed on RP2040/RP2350 #5123

@makiuchi-d

Description

@makiuchi-d

Description

On RP2040/RP2350, TinyGo always initializes the global math/rand RNG with a fixed seed.
This differs from Big Go, where since Go 1.20 the global RNG is seeded with randomness at startup.

Cause

The global math/rand RNG first tries to obtain randomness via n, ok := hardwareRand().
If hardwareRand() returns ok == true, the returned value n is used directly as the random source.
Otherwise, fastrand64() is used instead. (src/runtime/algorithm.go)

On RP2040/RP2350, however, hardwareRand() always returns 0, false. (src/runtime/rand_norng.go)
As a result, math/rand always falls back to fastrand64().
Since fastrand64() starts from a fixed initial state in this case,
the global RNG produces the same sequence on every run.

Proposed fix

RP2040/RP2350 provide a ROSC-based RNG via machine.GetRNG().
To avoid performance concerns, this RNG could be used only to provide initial entropy for fastrand64(),
rather than being used as the primary random source.

Notes

  • The ROSC-based RNG is not cryptographically secure and should not be used for crypto/rand.
  • RP2350 includes a hardware TRNG, but using it is out of scope for this issue.
  • RP2040 does not have a hardware TRNG; it may be worth discussing whether
    machine.GetRNG() should be used as the source for crypto/rand on this target.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions