QUANTUM
ENTROPY
A free API for high-quality randomness. Created on real quantum hardware.
Real randomness created on quantum hardware, delivered over a simple API — free to use, for seeds, keys, and anything that needs genuine entropy. Try it now with a live dice roll.
What is a QRNG?
A quantum random number generator measures a genuinely probabilistic quantum process — here, superposition and measurement on real quantum hardware (IBM Quantum / Amazon Braket) — to produce bits that are unbiased by construction, not merely hard to predict. Those raw quantum bits never leave this service directly. Instead they periodically reseed a standards-based DRBG (HMAC-DRBG, SP 800-90A), which stretches a finite quantum sample into effectively unlimited, cryptographically strong output — served free over the API as seeds, dice rolls, and key material for anyone who needs it.
How the pool actually gets used
Every 15 minutes (or sooner under sustained heavy traffic), the service pulls a fresh 32 bytesof raw quantum entropy from the pool and uses it as the DRBG’s root_key. That one 32-byte key is expanded by HMAC-DRBG into as much pseudorandom output as requests demand for that window — a monotonic counter mixed into each call keeps every response distinct, even under concurrent requests.
32 bytes in → unlimited served bytes out. Request volume alone can’t drain the pool faster than wall-clock time; only the 15-minute rotation (or a sustained flood of 100k+ requests inside 5 minutes) consumes fresh entropy.
Is the output “truly” random?
Only the 32-byte seed is physically near perfectly random. Everything downstream is cryptographically secure pseudorandom output — deterministic given the key, but computationally indistinguishable from random to anyone without it. This is the same architecture behind TLS, SSH, and most production crypto systems: a strong entropy seed feeding a standards DRBG, rather than streaming raw entropy bits over the wire per request.
Security rests on three things holding: the root_key stays encrypted at rest and is zeroized on rotation, the per-call counter never repeats, and the underlying quantum seed carries genuine entropy. All three hold here — which is what makes this setup suitable for real networking use (session keys, nonces, key material), not just as a demo.
The pipeline
1. Quantum bits
IBM Quantum / Braket measurement
2. Encrypted pool
AES-256-GCM at rest
3. HMAC-DRBG
root key + atomic counter
4. Seeds · dice · ML-KEM keys
everything served here
How to use the API
Every response is DRBG-derived — raw QRNG bits are never served. The anonymous endpoints need no key and are rate-limited. Developer endpoints need an X-API-Key minted by an admin and are quota-metered per tier. Every developer/KEM issue returns a signed receipt you can check at POST /v1/verify without the value ever being stored. Admin endpoints need an X-Admin-Token.
Want an API key? Email peter.jas@cnl.sk.
Public (anonymous, rate-limited, no key)
/health
Usage: uptime checks and monitoring dashboards — confirms the pool/DRBG isn't degraded before you rely on it for real traffic.
- Params/body: —
- {status, quantum_entropy_level, pool_bytes_remaining, drbg_reseeds, uptime}
curl -s "<base>/health"/random?bytes=N
Usage: quick no-signup random bytes for demos, small scripts, or anything lightweight that doesn't need a key.
- Params/body: bytes 1–64 (default 32)
- base64; anon daily ceiling applies
curl -s "<base>/random?bytes=32"/dice
Usage: fair dice rolls for tabletop bots and giveaways, where players can audit every DRBG byte drawn behind a roll.
- Params/body: {"sides":2–100, "count":1–6}
- echoes the DRBG bytes drawn
curl -s -X POST <base>/dice \
-H 'content-type: application/json' \
-d '{"sides":20,"count":3}'Developer (require X-API-Key, quota-metered)
/v1/random/bytes?size=N&format=hex|base64
Usage: the main developer integration — production-grade random bytes paired with a signed receipt to prove provenance later.
- Params/body: size 32–4096, format (default hex)
- returns request_id, data, entropy_epoch, timestamp, receipt
curl -s "<base>/v1/random/bytes?size=32&format=hex" \
-H "X-API-Key: <your-key>"/v1/kem/keypair
Usage: generating post-quantum ML-KEM-768 key material for testing; real deployments should keygen client-side, this route is a demo path.
- Params/body: {"include_secret_key": bool}
- public_key always; secret_key demo-only
curl -s -X POST <base>/v1/kem/keypair \
-H "X-API-Key: <your-key>" -H 'content-type: application/json' -d '{}'/v1/kem/encapsulate
Usage: demoing the encapsulation half of ML-KEM-768 against a public key you already hold; no server-side decapsulation route exists.
- Params/body: {"public_key": b64, "include_shared_secret": bool}
- ciphertext always; shared_secret/demo_key demo-only
curl -s -X POST <base>/v1/kem/encapsulate \
-H "X-API-Key: <your-key>" -H 'content-type: application/json' \
-d '{"public_key":"<ek>","include_shared_secret":true}'Provenance (anonymous)
/v1/verify
Usage: proving a given output really came from this service, useful for audits or disputes, without ever re-exposing the underlying bytes.
- Params/body: {"request_id": str} and/or {"receipt": str}
- {request_id, verified, provenance, note}; not a value oracle
curl -s -X POST <base>/v1/verify \
-H 'content-type: application/json' -d '{"receipt":"qeaas1...."}'/v1/pubkey
Usage: verifying receipts fully offline using the published signing key, with no call back to this service needed.
- Params/body: —
- {algorithm:"Ed25519", format:"base64", public_key}
curl -s <base>/v1/pubkeyAdmin (require X-Admin-Token)
/admin/keys
Usage: operators provisioning a brand-new API key for a developer or customer, shown once at mint time.
- Params/body: {"owner", "tier"?, "daily_quota_bytes"?}
- returns the plaintext key once
curl -s -X POST <base>/admin/keys \
-H "X-Admin-Token: <token>" -H 'content-type: application/json' \
-d '{"owner":"you","tier":"default"}'/admin/keys/revoke
Usage: operators killing a compromised or offboarded key immediately, effective on the very next request.
- Params/body: {"key_hash"}
- takes effect on the next request
curl -s -X POST <base>/admin/keys/revoke \
-H "X-Admin-Token: <token>" -H 'content-type: application/json' \
-d '{"key_hash":"<hash>"}'/admin/ingest
Usage: operators refilling the entropy pool from a fresh batch of raw QRNG bits, encrypted before it ever touches disk.
- Params/body: multipart .txt of 0/1, ≤10 MB
- AES-256-GCM encrypted at rest
curl -s -X POST <base>/admin/ingest \
-H "X-Admin-Token: <token>" -F "file=@bits.txt"/admin/purge
Usage: operators wiping the entropy pool clean for rotation, incident response, or test resets — an irreversible action.
- Params/body: —
- {purged, chunks_removed, pool_bytes_remaining}; irreversible, re-ingest after
curl -s -X POST <base>/admin/purge \
-H "X-Admin-Token: <token>"Getting started with the API
- 1. Get a keyan admin mints one (
POST /admin/keyswith yourowner/tier); the plaintext key is shown once, store it securely (the server keeps only a hash). - 2. Authenticatesend it as the
X-API-Keyheader on every developer/KEM call. - 3. First call
GET /v1/random/bytes?size=32&format=hex→ you getdataplus provenance (request_id,entropy_epoch,timestamp,receipt). - 4. Check provenance
POST /v1/verify {"receipt": "<the receipt>"}→verified:trueand the QRNG batch/epoch it came from. The value itself is never stored or echoed. - 5. Watch your limits
GET /healthshows entropy status; over-quota/over-rate calls return429; a degraded pool returns503on developer/KEM endpoints (dice keeps working).
Rules of usage
- Anonymous: 60 requests/min per IP;
/randomcapped at 64 bytes/request; global anon output ceiling 5 MiB/day (daily_limit_reached429over it). - API-key tiers (per-key rate → daily byte quota):
default120/min → 256 KiB/day;iot600/min → 10 MiB/day;trusted1200/min → 500 MiB/day. A per-keydaily_quota_bytesoverride wins over the tier default. Over-rate →rate_limited; over-quota →quota_exceeded(both429, withRetry-After). - Low-entropy gate: when the pool is degraded, developer/KEM endpoints return
503 low_quantum_entropy; anon dice//randomkeep serving from the current DRBG. - Invariants: raw QRNG bits are never served (all output is DRBG-derived); revocation is instant;
/v1/verifyproves provenance, not the secret — it never stores or confirms a value. - Error envelope: every error is
{"error": "<slug>"}(bad_request422,missing_api_key/invalid_api_key/unauthorized401,rate_limited/daily_limit_reached/quota_exceeded429,low_quantum_entropy503,file_too_large413,not_found404).
Verify a receipt
Every developer/KEM issue ships a signed receipt. Paste one here — or just its request_id — to check its provenance without ever sending the value itself.