← Lararand 3 / 9

Sources

Four, and only these four can be named in chain.

Key Where it comes from Needs
system The machine's CSPRNG, via random_bytes nothing
anu_public ANU vacuum noise, free endpoint, 1 request a minute nothing
anu_quantum The same vacuum fluctuations, metered endpoint an API key
random_org Atmospheric noise, from random.org an API key

A quantum generator is unpredictable because there is nothing to invert: the field jitters whether or not anyone is measuring it. A CSPRNG is unpredictable because inverting it is expensive. That distinction rarely changes a threat model, and it changes what you can say.

Configuring them

'sources' => [

    'system' => [
        'driver' => 'system',
    ],

    'anu_public' => [
        'driver' => 'anu_public',
        'timeout' => 4,
        'cooldown' => 120,
    ],

    'anu_quantum' => [
        'driver' => 'anu_quantum',
        'key' => env('QUANTUM_ANU_API_KEY'),
        'timeout' => 4,
        'cooldown' => 864000,
    ],

    'random_org' => [
        'driver' => 'random_org',
        'key' => env('RANDOM_ORG_KEY'),
        'timeout' => 4,
        'cooldown' => 3600,
    ],

],

Timeouts are deliberately short. Somebody is waiting on the other side of this, and a slow generator should hand over to the next source rather than hold up the response.

Adding your own

A class implementing Contracts\RandomSource and an entry in the config. One method:

namespace App\Randomness;

use EduLazaro\Lararand\Contracts\RandomSource;

class HardwareDongle implements RandomSource
{
    public function bytes(int $count): string
    {
        // Return exactly $count bytes, or throw.
    }
}

Throw Exceptions\RandomnessUnavailable when you cannot serve, and the chain moves on to the next source. Anything else propagates, which is what you want for a bug rather than an outage.

Nothing that draws, shuffles or deals ever learns which source it got. That is the point of the contract being bytes.

Why the directory has five files and four choices

Sources/ holds exactly what you can name in chain, and nothing else. Buffer, Fallback and Cooldown live in Decorators/ because they produce no randomness of their own. They are RandomSource by type and by no other measure, and filing them beside the real ones would make a directory look like seven things to choose between.