bmilleare / drand-php
A PHP client for the drand distributed randomness beacon network with BLS12-381 signature verification.
Requires
- php: >=8.2
- ext-json: *
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.1 || ^2.0
Requires (Dev)
- guzzlehttp/guzzle: ^7.8
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
- ext-ffi: Enables the high-performance blst verifier backend (needs the libblst shared library).
- ext-gmp: Required by the pure-PHP BLS12-381 verifier (the default, native-library-free backend).
- guzzlehttp/guzzle: A PSR-18 HTTP client; any PSR-18 client works. Falls back to a bundled cURL client if none is provided.
This package is auto-updated.
Last update: 2026-05-30 12:37:31 UTC
README
A PHP client for the drand distributed randomness beacon network (the League of Entropy), with cryptographic verification of the BLS12-381 threshold signatures.
drand-php is fail-closed: latest() and round() return a beacon only when
its signature verifies against the chain's distributed public key — otherwise
they throw. You never get unverified randomness by accident.
use Bmilleare\Drand\DrandClient; $client = DrandClient::create($httpClient, $httpFactory, beaconId: 'quicknet'); $beacon = $client->latest(); // fetched AND verified echo $beacon->round, PHP_EOL; // e.g. 29110875 echo $beacon->randomnessHex(), PHP_EOL; // 32-byte verifiable random value
Features
- Fetch randomness from any drand relay over the v2 (and v1) HTTP API.
- Verify BLS12-381 signatures for all three League-of-Entropy schemes.
- Two interchangeable verification backends behind one interface:
- blst — the audited supranational/blst C library via FFI (fast).
- pure-PHP — a dependency-free backend using
ext-gmp(portable).
- PSR-18 / PSR-17 transport: bring your own HTTP client (Guzzle, Symfony, ...) or use the bundled cURL client.
- Round/time helpers: compute the round at any timestamp and vice-versa.
Requirements
- PHP 8.2+
ext-json,ext-curl(for the bundled HTTP client)- A verification backend (at least one):
ext-ffi+ alibblstshared library, orext-gmp(pure-PHP backend)
Installation
composer require bmilleare/drand-php
Verification backend
The client refuses to run without a working verification backend (it throws
VerifierUnavailableException). Enable one:
Option A — blst (fast): enable ext-ffi and provide a libblst shared
library. Build it once:
php vendor/bmilleare/drand-php/bin/install-blst.php
# builds resources/lib/libblst.<so|dylib|dll>
(or build blst yourself with
./build.sh -shared and point BlstVerifier at the resulting library).
Option B — pure-PHP (portable): install ext-gmp. No native library needed.
VerifierFactory::auto() prefers blst when available and falls back to pure-PHP.
Usage
Quick start
use Bmilleare\Drand\DrandClient; use Bmilleare\Drand\Http\CurlHttpClient; use GuzzleHttp\Psr7\HttpFactory; // any PSR-17 factory $factory = new HttpFactory(); $http = new CurlHttpClient($factory, $factory); $client = DrandClient::create($http, $factory, beaconId: 'quicknet'); $beacon = $client->latest(); printf("round %d: %s\n", $beacon->round, $beacon->randomnessHex());
A specific round
$beacon = $client->round(29110875); // verified, or throws InvalidSignatureException
Verify a beacon you already have
if ($client->verify($beacon)) { // signature is valid }
Round / time math
$info = $client->chainInfo(); $round = $info->roundAt(time()); // current round number $emittedAt = $info->timeOfRound($round);
Beacons and schemes
The League of Entropy mainnet runs these chains:
| Beacon | Scheme | Period | Signature | Public key | Message |
|---|---|---|---|---|---|
quicknet |
bls-unchained-g1-rfc9380 |
3s | G1 (48 B) | G2 (96 B) | sha256(round) |
default |
pedersen-bls-chained |
30s | G2 (96 B) | G1 (48 B) | sha256(prev‖round) |
quicknet is recommended for new applications: it is unchained (statelessly
verifiable) and has smaller, faster signatures. The randomness for every scheme
is sha256(signature).
Security
- Fail-closed by design. The client never returns an unverified beacon. A
verification failure raises
InvalidSignatureException; an environment with no backend raisesVerifierUnavailableException. - Pin the chain hash / public key you expect for production use, and fetch chain info over a trusted channel — a malicious relay could otherwise serve a self-consistent fake chain.
- The blst backend uses an audited C library. The pure-PHP backend is a from-scratch implementation provided for portability; prefer blst where you can.
Testing
composer install vendor/bin/phpunit # all tests (network tests skip if offline) vendor/bin/phpunit --testsuite unit # offline only
Cryptographic correctness is pinned by tests that verify genuine captured beacons (positive vectors) and reject tampered ones (negative vectors).
License
MIT — see LICENSE.