Module soroban_sdk::prng

source ·
Expand description

Prng contains a pseudo-random number generator.

§Warning

Do not use the PRNG in this module without a clear understanding of two major limitations in the way it is deployed in the Stellar network:

  1. The PRNG is seeded with data that is public as soon as each ledger is nominated. Therefore it should never be used to generate secrets.

  2. The PRNG is seeded with data that is under the control of validators. Therefore it should only be used in applications where the risk of validator influence is acceptable.

The PRNG in this module is a strong CSPRNG (ChaCha20) and can be manually re-seeded by contracts, in order to support commit/reveal schemes, oracles, or similar advanced types of pseudo-random contract behaviour. Any PRNG is however only as strong as its seed.

The network runs in strict consensus, so every node in the network seeds its PRNG with a consensus value, not a random entropy source. It uses data that is generally difficult to predict in advance, and generally difficult for network users to bias to a specific value: the seed is derived from the overall transaction-set hash and the hash-sorted position number of each transaction within it. But this seed is not secret and not cryptographically hard to bias if a corrupt validator were to choose to do so (similar to the way a corrupt validator can bias overall transaction admission in the network).

In other words the network will provide a stronger seed than a contract could likely derive on-chain using any other public data visible to it (eg. better than using a timestamp, ledger number, counter, or a similarly weak seed) but weaker than a contract could acquire using a commit/reveal scheme with an off-chain source of trusted random entropy.

You should carefully consider whether these limitations are acceptable for your application before using this module.

§Operation

The host has a single hidden “base” PRNG that is seeded by the network. The base PRNG is then used to seed separate, independent “local” PRNGs for each contract invocation. This independence has the following characteristics:

  • Contract invocations can only access (use or reseed) their local PRNG.
  • Contract invocations cannot influence any other invocation’s local PRNG, except by influencing the other invocation to make a call to its PRNG.
  • Contracts cannot influence the base PRNG that seeds local PRNGs, except by making calls and thereby creating new local PRNGs with new seeds.
  • A contract invocation’s local PRNG maintains state through the life of the invocation.
  • That state is advanced by each call from the invocation to a PRNG function in this module.
  • A contract invocation’s local PRNG is destroyed after the invocation.
  • Any re-entry of a contract counts as a separate invocation.

§Testing

In local tests, the base PRNG of each host is seeded to zero when the host is constructed, so each contract invocation’s local PRNG seed (and all its PRNG-derived calls) will be determined strictly by its order of invocation in the test. Assuming this order is stable, each test run should see stable output from the local PRNG.

Structs§

  • Prng is a pseudo-random generator.

Traits§

  • Implemented by types that support being filled by a Prng.
  • Implemented by types that support being generated by a Prng.
  • Implemented by types that support being generated of specific length by a Prng.
  • Implemented by types that support being generated in a specific range by a Prng.
  • Implemented by types that support being shuffled by a Prng.
  • Implemented by types that support being shuffled by a Prng.