silk/random
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc.
Provider-replaceable cryptographically secure random bytes and derived values.
When to use
Require Random for secrets, credentials, cryptographic keys, nonces, tokens, randomized
protocols, or any value that must remain unpredictable. Supply an explicit production CSPRNG at
the application boundary and a scripted provider only in deterministic tests.
Details
The service primitive exactly fills borrowed storage. nextU64, nextBool, and below
have stable source-defined byte consumption and do not select a concrete provider.
Gotchas
A provider claiming this service must return fresh unpredictable bytes and must treat failure as
fatal. An environment without such a source must omit the capability, never substitute
deterministic data. Random.fillBytes performs no provider call for empty storage.
Examples
Test word decoding with scripted bytes
import silk.effect {Effect}
import silk.random {Random}
import silk.usize
// A deterministic test double; never supply it for secrets or credentials.
struct Scripted {
filled: usize
}
impl Random for Scripted {
effect fn fillBytes(self: &mut Self, output: &mut [u8]) -> () {
let mut index = usize.ZERO
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: usize.ZERO}
let word = run Random.nextU64()
|> Effect.provideMut<Random>(&mut provider)
if word == 42 && provider.filled == 8 {
return 42
}
return 0
}Import as Random with import silk.random { Random }.
Public declarations: 1.
Random
pub service RandomAn exclusive source of fresh cryptographically secure random bytes.
Details
Providers must fill every requested byte, must not advance for an empty slice, and must never return weak or partial data after failure.
Operation fillBytes
effect<'life0> fn fillBytes<'life0>(output: &'life0 mut [u8]) -> () ? &mut RandomFills the complete exclusive byte slice with fresh unpredictable data.
Associated function Random.nextU64
pub effect<'static> fn nextU64() -> u64 ? &mut RandomReturns one secure u64 decoded least-significant byte first from exactly eight provider bytes.
Associated function Random.nextBool
pub effect<'static> fn nextBool() -> bool ? &mut RandomReturns whether bit 63 of one secure provider word is set.
Associated function Random.below
pub effect<'static> fn below(upperExclusive: u64) -> silk/option.Option<u64> ? &mut RandomReturns an unbiased secure value below upperExclusive, or None for zero.
Details
A zero bound consumes no provider bytes. Positive bounds use complete-word rejection sampling.