silk.system.random.
The Random effect: random bytes that are safe for secrets.
When to use#
Require &mut Random for anything that an attacker must not guess: keys, nonces, tokens,
passwords, and session IDs. The program provides a cryptographically secure random number
generator. For simulations, games, and tests that must repeat, use silk.system.insecure_random.
Details#
A provider implements one operation, Random.fillBytes, that fills a slice.
Random.nextU64, Random.nextBool, and Random.below use it. The number of bytes that
each one reads is fixed, so a test provider gives the same results each time.
Gotchas#
A provider must return fresh, unpredictable bytes. If it cannot, it must stop the program. It must never return weak or predictable data instead. A test provider like the one below is only for tests.
Examples#
Test code that uses random words with a fixed provider#
import silk.core.effect { Effect }
import silk.system.random { Random }
// A test provider. Never use it for secrets.
struct Scripted {
filled: usize,
}
impl Random for Scripted {
effect fn fillBytes(self: &mut Self, output: &mut [u8]) -> () {
let mut index: usize = 0
while index < output.length {
output[index] = 0
index = index + 1
}
if output.length > 0 {
output[0] = 42
}
self.filled = self.filled + output.length
return ()
}
}
pub fn main() -> i32 {
let mut provider = Scripted { filled: 0 }
let word = run Random.nextU64() |> Effect.provideMut<Random>(&mut provider)
if word != 42 || provider.filled != 8 {
return 1
}
return 0
}Import as Random with import silk.system.random { Random }.
Public declarations: 1.
Random#
pub service RandomThe effect for random bytes that are safe for secrets.
When to use#
Require &mut Random for anything that an attacker must not guess: keys, nonces, tokens,
passwords, and session IDs. For simulations, games, and tests that must repeat, use
silk.system.insecure_random.
Details#
A provider implements Random.fillBytes. Random.nextU64, Random.nextBool, and
Random.below use it, and the number of bytes that each one reads is fixed, so a test
provider gives the same results each time. /// A provider fills each requested byte. For an
empty slice, it does nothing and does not use randomness. If it cannot get random bytes, it must
stop the program.
Operation fillBytes#
effect fn fillBytes(output: &mut [u8]) -> () ? &mut RandomFills all of output with fresh random bytes.
Implementation Random#
impl RandomAssociated function nextU64#
pub effect fn nextU64() -> u64 ? &mut RandomReturns a random u64. It reads 8 bytes and uses the first byte as the least significant
byte.
Associated function nextBool#
pub effect fn nextBool() -> bool ? &mut RandomReturns a random bool. It reads one u64 and returns true if its highest bit is set.
Associated function below#
pub effect fn below(upperExclusive: u64) -> Option<u64> ? &mut RandomReturns a random value from 0 to upperExclusive - 1, with the same chance for each value.
Returns an absent option if upperExclusive is 0.
Details#
It reads u64 values and drops values that would make some results more likely than others,
so it can read more than one u64. For 0, it reads nothing.
Category: System.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.