Synchronous raw_rand

I would like to initiate discussion of adding a synchronous raw_rand function call to the System API.

Currently raw_rand can only be called asynchronously, and as far as I know it is the only way for a canister to retrieve “secure” (secure meaning it has the properties of randomness that the IC’s VRF provides) randomness directly from the IC. Unfortunately because raw_rand is asynchronous, it cannot be called in canister_init or canister_post_upgrade, and I assume it also couldn’t be called in (start).

This is problematic as a canister may have need for randomness synchronously during canister initialization. For example, Azle and Kybra both execute their respective source code entrypoints during canister initialization, and both must call ic_wasi_polyfill::init (which accepts a random seed) during initialization. Secure randomness is not accessible to this initialization code.

Workarounds have been discussed, and Azle/Kybra have used them to some extent. One of them is to create a timer of 0 that sets a global randomness seed as quickly as possible after initialization. The drawback is that this doesn’t happen inside of the same call as the initialization.

Another workaround would be to set the randomness as an initialization parameter to canister_init or canister_post_upgrade, but of course this would call into question the security of the original randomness.

Let’s discuss the merits of a synchronous raw_rand and move it forward if possible.

Prior Discussion

  1. Introducing WASI for IC - #28 by sgaflv

  2. Introducing WASI for IC - #30 by ulan

  3. Generating custom principals/uuids in Rust - #13 by lastmjs

  4. Issue about generate random string Panicked at 'could not initialize thread_rng: getrandom: this target is not supported' - #4 by paulyoung

2 Likes