ddonche/goblin-lang
0.46.24
1
0
docs reference
[[secure-randomness]]

Secure Randomness


Secure Randomness

Goblin provides two tiers of randomness:

  • pick, random, shuffle, reap_random, and other ordinary random operations

    • Fast non-cryptographic randomness for ordinary scripting
  • secure_pick, secure_random, and secure_shuffle

    • Cryptographically secure randomness for passwords, tokens, session IDs, API keys, and other security-sensitive operations

Goblin's secure randomness system is powered by an internal CSPRNG implemented directly in the runtime.

The runtime obtains entropy from the operating system's cryptographically secure random source and expands that entropy into a secure byte stream using BLAKE3. Additional runtime and environmental information may also be mixed into the seed, but security does not depend on those supplemental sources.

The secure system is fail-closed — if secure operating-system randomness is unavailable, Goblin aborts the operation rather than silently producing weakened randomness.


Secure Pick

secure_pick works exactly like pick, but uses Goblin's secure CSPRNG internally.

nums | secure_pick 8 from 0...9 with dups

letters | secure_pick 12 from "a"..."z" with dups

symbols | raw "!@#$%^&*()-_=+[];:<>?"
sym_arr | secure_pick 4 from symbols with dups
nums | secure_pick 8 from 0...9 with dups

letters | secure_pick 12 from "a"..."z" with dups

symbols | raw "!@#$%^&*()-_=+[];:<>?"
sym_arr | secure_pick 4 from symbols with dups

secure_pick supports:

  • ranges
  • arrays
  • strings
  • duplicates
  • unbiased selection via rejection sampling

Unlike ordinary pick, all randomness comes from Goblin's secure runtime CSPRNG.


Secure Random

secure_random returns a cryptographically secure integer within a range.

x | secure_random from 1..100

port | secure_random from 20000..60000

roll | secure_random from 1..20
x | secure_random from 1..100

port | secure_random from 20000..60000

roll | secure_random from 1..20

Goblin ranges follow the standard range rules:

  • .. is exclusive
  • ... is inclusive

pick from 1..5     /// 1-4
pick from 1...5    /// 1-5
pick from 1..5     /// 1-4
pick from 1...5    /// 1-5

secure_random follows the same semantics.

Internally, Goblin performs unbiased bounded selection using rejection sampling over a secure byte stream.


Secure Shuffle

secure_shuffle securely randomizes arrays or strings using a cryptographically secure Fisher-Yates shuffle.

items | ["axe", "torch", "rope"]
items | secure_shuffle(items)

password | "hunter2"
password | secure_shuffle(password)
items | ["axe", "torch", "rope"]
items | secure_shuffle(items)

password | "hunter2"
password | secure_shuffle(password)

Strings remain strings after shuffling.


Password Generation Example

symbols | raw "!@#$%^&*()-_=+[];:<>?"

n, l, s | [
    secure_random from 3..8,
    secure_random from 5..12,
    secure_random from 2..5
]

nums_arr    | secure_pick n from 0...9 with dups
letters_arr | secure_pick l from "a"..."z" with dups
sym_arr     | secure_pick s from symbols with dups

numbers | :pack(nums_arr).str
letters | :pack(letters_arr).mixed
syms    | :pack(sym_arr).raw

password | numbers + letters + syms
password | secure_shuffle(password.raw)

:say(password)
symbols | raw "!@#$%^&*()-_=+[];:<>?"

n, l, s | [
    secure_random from 3..8,
    secure_random from 5..12,
    secure_random from 2..5
]

nums_arr    | secure_pick n from 0...9 with dups
letters_arr | secure_pick l from "a"..."z" with dups
sym_arr     | secure_pick s from symbols with dups

numbers | :pack(nums_arr).str
letters | :pack(letters_arr).mixed
syms    | :pack(sym_arr).raw

password | numbers + letters + syms
password | secure_shuffle(password.raw)

:say(password)


Runtime Design

Goblin's secure randomness system is built around a cryptographically secure entropy pipeline.

Primary entropy comes from:

  • the operating system's secure random source

Supplemental information may be mixed into the seed, including:

  • filesystem state
  • nanosecond timing
  • process identity
  • interpreter fingerprinting
  • filesystem timing data
  • CPU timing jitter
  • persistent runtime seed state

This supplemental information is used only to strengthen and diversify the seed. Goblin's security does not depend on any individual supplemental source being available.

Entropy is:

  • collected
  • domain-separated
  • compressed through BLAKE3
  • expanded into a secure stream
  • selected without modulo bias

The runtime maintains a persistent seed file:

~/.goblin/rng_seed
~/.goblin/rng_seed

which is folded into future entropy collection to improve unpredictability across runs.


Fail-Closed Security

Goblin's secure randomness system is intentionally fail-closed.

If the operating system's secure random source cannot be accessed:

  • secure_pick
  • secure_random
  • secure_shuffle

will abort with a runtime error.

Goblin will never silently fall back to ordinary randomness for secure operations.

This guarantees that security-sensitive workflows cannot accidentally degrade into weaker randomness without the programmer's knowledge.


Ordinary vs Secure Randomness

Operation Purpose
pick Fast non-secure selection
random Fast non-secure numeric randomization
shuffle Fast non-secure shuffle
reap_random Fast non-secure read-and-remove randomization
_random collection utilities Fast non-secure random collection operations
secure_pick Cryptographically secure selection
secure_random Cryptographically secure numeric selection
secure_shuffle Cryptographically secure shuffle

Use ordinary randomness for:

  • games
  • procedural generation
  • simulations
  • visual effects
  • general scripting

Use secure randomness for:

  • passwords
  • tokens
  • API keys
  • session IDs
  • security-sensitive workflows

Secure randomness is intentionally explicit. If you see secure_*, Goblin is using the runtime CSPRNG instead of the ordinary PRNG. Goblin obtains secure entropy from the operating system and will abort rather than silently falling back to weaker randomness.