# BitBop.dev v2.1 — Complete Agentic Reference (`llms-full.txt`) > Single-file technical reference for AI coding agents (Cursor, Claude Code, Windsurf, Antigravity, custom LLM pipelines) integrating with the BitBop v2.1 Hardware Quantum Entropy & Post-Quantum Provenance API. --- ## 1. Architecture & Cryptographic Guarantees 1. **Physically Secured Hardware Entropy Source**: Raw RF thermal noise (`rf-thermal-noise` on `trng-device-01`) is harvested inside a physically secured hardware appliance, continuously audited against 7 NIST SP 800-90B statistical tests, and packaged into 1 MiB (`1,048,576` byte) beacon blocks. 2. **End-to-End Quantum-Safe (Q-Safe) Pipeline**: - **Zero-Plaintext Sealed Provenance**: Every 1 MiB hardware block is signed with **NIST FIPS 204 `ML-DSA-44`** and quantum-resistant sealed at rest (`entropy.sealed: true`) so zero plaintext `bytes_hex` is ever stored at rest. - **Client Receipts (`ml-dsa-44` Exclusively)**: Every `/consume`, `/order`, `/escrow/commit`, and `/escrow/reveal` receipt is signed and verified exclusively with **NIST FIPS 204 `ML-DSA-44`** (`2,420 bytes`). Classical `ed25519` receipt requests are rejected (`HTTP 400`). - **Mandatory `ML-KEM-768` Post-Quantum E2EE**: `POST /consume`, `POST /escrow/reveal`, `POST /api/keys/free`, and `POST /api/checkout/claim` require a `1,184`-byte (`2,368` hex char) **NIST FIPS 203 `ML-KEM-768`** public key (`kyber_public_key`) and return a post-quantum encapsulated `cipher` (`kyber_ciphertext_hex`, `aes_iv_hex`, `aes_ciphertext_hex`). `POST /order` omits `bytes_used_hex` from public receipts (recording `beacon_byte_offset`, `bytes_consumed`, and `entropy_sha256` for server-side `/verify` replay) and returns `cipher` when `kyber_public_key` is provided. - **100% Automated in SDKs, CLI & Web UI**: `@bitbop/sdk` (Node.js/TS), `bitbop` (Python), the `bitbop` CLI, and the Web UI automatically generate ephemeral `ML-KEM-768` keypairs in RAM, decapsulate `cipher` responses, verify `SHA-256` and `ML-DSA-44` bindings offline, and zero the secret key in memory. 3. **Zero-Plaintext API Keys**: - API keys (`bb_free_...` and `bb_live_...`) are minted from 32 bytes of hardware TRNG entropy and delivered exclusively inside an `ML-KEM-768` encrypted envelope. Only one-way `SHA-256` key hashes are retained for authentication; plaintext keys are never persisted at rest. --- ## 2. Authentication & Base URL - **Base URL**: `https://api.bitbop.dev` - **Official Node.js / TypeScript SDK & CLI (`@bitbop/sdk` v2.1.0)**: `npm install https://www.bitbop.dev/downloads/bitbop-sdk-2.1.0.tgz` - **Official Python SDK & CLI (`bitbop` v2.1.0)**: `pip install https://www.bitbop.dev/downloads/bitbop-2.1.0-py3-none-any.whl` - **Self-Serve Free Tier Key (`500 req/day`, `60-day TTL`, `$0`)**: Mint via `POST https://api.bitbop.dev/api/keys/free` (max 2 keys per IP `/64` per UTC day) or on `https://www.bitbop.dev/get-key`. - **Sandbox Evaluation Key (`100 req/day/IP`)**: `test-key-1` (pass via `Authorization: Bearer test-key-1`) - **CORS & Telemetry Headers**: Responses expose `cf-ray`, `cf-cache-status`, `date`, `x-bitbop-tier`, `x-ratelimit-limit`, `x-ratelimit-remaining`, `x-ratelimit-reset`, and `Timing-Allow-Origin: *`. | Endpoint | Method | Auth Required | Purpose | | :--- | :---: | :---: | :--- | | `/api/keys/free` | `POST` | **No** | Mint a dedicated `bb_free_...` hardware-TRNG API key (500/day, 60d TTL) | | `/api/keys/status` | `GET` | `Bearer ` | Inspect API key tier, quota, remaining calls, and expiry (consumes 0 quota) | | `/health` | `GET` | No | Edge health, `pool_depth`, and active beacon sequence | | `/beacon` | `GET` | No | Latest 1 MiB quantum-safe sealed hardware block + `ML-DSA-44` signature | | `/consume` | `POST` | `Bearer ` | Slice `1..1024` raw quantum bytes with signed beacon provenance | | `/order` | `POST` | `Bearer ` | Unbiased Fisher-Yates shuffle (32-bit rejection sampling) | | `/escrow/commit` | `POST` | `Bearer ` | Seal payload (`AES-256-GCM`) with `forever` or `once` policy, time-lock, or PIN | | `/escrow/reveal` | `POST` | **No** | Publicly reveal escrow entropy key (and hosted `≤512B` envelope if stored) | | `/verify` | `POST` | **No** | Verify any `/consume`, `/order`, or `/escrow/reveal` receipt against the signed beacon chain | --- ## 3. Endpoint Specifications & Executable Examples ### 3.1 `GET /health` (Public) #### Request (`cURL`) ```bash curl -s https://api.bitbop.dev/health ``` #### Response (`200 OK`) ```json { "status": "healthy", "pool_depth": 3, "latest_sequence": 14424, "timestamp": "2026-10-19T07:50:00.000Z" } ``` --- ### 3.2 `GET /beacon` (Public) Returns the current 1 MiB sealed beacon block, or a specific historical block via `GET /beacon?sequence=`. #### Request (`cURL`) ```bash curl -s https://api.bitbop.dev/beacon ``` #### Response (`200 OK`, truncated `bytes_cipher_hex`) ```json { "version": "2.0", "sequence": 14424, "timestamp": "2026-10-19T07:45:01.000Z", "entropy": { "sealed": true, "cipher": "AES-256-GCM", "iv_hex": "a1b2c3d4e5f60718293a4b5c", "bytes_cipher_hex": "<2,097,184 hex chars (1 MiB ciphertext + 16B GCM auth tag)>", "hash": "sha256:de78082db5a5a83f3dd18ab319f735efdb84fc7168bf558631315eb3c4c8..." }, "signature": "ed25519:...", "signature_mldsa44": "mldsa44:..." } ``` --- ### 3.3 `POST /consume` (Authenticated — The Forge, Mandatory `ML-KEM-768` E2EE) Draws `bytes_requested` (`1` to `1024`) exclusive hardware entropy bytes from the active beacon block, encapsulates the slice using the caller's ephemeral `1,184`-byte `ML-KEM-768` public key (`kyber_public_key`) + `AES-256-GCM`, and signs `cipher + attestation` with `ML-DSA-44`. #### Request (`Node.js / @bitbop/sdk` — Automated `ML-KEM-768` & Offline Verify) ```javascript import { Bitbop } from '@bitbop/sdk'; const client = new Bitbop('test-key-1'); const res = await client.forgeKey(32); // Automatically generates ML-KEM-768 keypair & decapsulates console.log(res.entropyHex, res.attestation); ``` #### Raw Wire Request (`POST /consume`) ```json { "bytes_requested": 32, "kyber_public_key": "<2,368 hex chars (1,184-byte ML-KEM-768 public key)>", "signature_scheme": "ml-dsa-44" } ``` #### Response (`200 OK`) ```json { "version": "2.0", "timestamp": "2026-10-20T04:50:11.032Z", "delivery_mechanism": "ML-KEM-768 + AES-256-GCM", "cipher": { "kyber_ciphertext_hex": "<2,176 hex chars (1,088-byte ML-KEM-768 ciphertext)>", "aes_iv_hex": "<24 hex chars (12-byte GCM IV)>", "aes_ciphertext_hex": "<96 hex chars (32B ciphertext + 16B GCM auth tag)>" }, "attestation": { "beacon_sequence": 14424, "beacon_hash": "sha256:de78082db5a5a83f3dd18ab319f735efdb84fc7168bf558631315eb3c4c8...", "beacon_byte_offset": 41920, "byte_count": 32, "entropy_sha256": "sha256:9b8142...", "source_type": "rf-thermal-noise", "blessed_wasm_hash": "4b254ec63f32b714073e20866fa05d73423e9f125a6e1d3e997a5d2976a550d0", "signature_scheme": "ml-dsa-44", "signature": "<4,840 hex chars (2,420-byte ML-DSA-44 signature)>" } } ``` --- ### 3.4 `POST /order` (Authenticated — Unbiased Fisher-Yates Ordering) Performs an unbiased Fisher-Yates permutation using 32-bit unsigned integer rejection sampling (`limit = Math.floor(0x100000000 / range) * range`) to eliminate modulo bias. Plaintext `bytes_used_hex` is omitted from the public receipt (storing `beacon_byte_offset`, `bytes_consumed`, and `entropy_sha256` so `POST /verify` can deterministically replay and verify the shuffle against the referenced beacon block). If `kyber_public_key` is provided (automated in the SDKs), the response also includes `cipher` (`ML-KEM-768 + AES-256-GCM`) for offline replay verification. #### Request (`cURL`) ```bash curl -s -X POST https://api.bitbop.dev/order \ -H "Authorization: Bearer test-key-1" \ -H "Content-Type: application/json" \ -d '{ "items": ["Alice — Ticket #101", "Bob — Ticket #102", "Charlie — Ticket #103", "Diana — Ticket #104"], "signature_scheme": "ml-dsa-44" }' ``` #### Response (`200 OK`) ```json { "ordered": [ "Charlie — Ticket #103", "Alice — Ticket #101", "Diana — Ticket #104", "Bob — Ticket #102" ], "ordering": [2, 0, 3, 1], "receipt": { "version": "2.0", "timestamp": "2026-10-20T04:51:00.000Z", "entropy": { "beacon_sequence": 14424, "beacon_hash": "sha256:de78082db5a5a83f3dd18ab319f735efdb84fc7168bf558631315eb3c4c8...", "beacon_byte_offset": 88120, "bytes_consumed": 12, "entropy_sha256": "sha256:4a90e1..." }, "input": { "item_count": 4, "items_hash": "sha256:...", "mode": "open", "items": ["Alice — Ticket #101", "Bob — Ticket #102", "Charlie — Ticket #103", "Diana — Ticket #104"] }, "output": { "ordering": [2, 0, 3, 1], "algorithm": "fisher-yates-uint32-rejection", "signature_scheme": "ml-dsa-44" }, "receipt_hash": "sha256:...", "signature": "<4,840 hex chars (2,420-byte ML-DSA-44 signature)>" } } ``` --- ### 3.5 `POST /escrow/commit` (Authenticated — Local Run Sheet or Hosted ≤512B Secret) Draws 32 bytes of hardware quantum entropy (`entropy_hex`), derives an `AES-256-GCM` key via `SHA-256(utf8(entropy_hex))`, and optionally encrypts `seal_payload_b64`. - **Pattern A — Local Zero-Storage Game Run Sheet (`store_sealed_envelope: false`, `reveal_policy: "forever"`)**: - `seal_payload_b64` up to `1 MiB`. BitBop returns `sealed_envelope` in the response and stores only the sealed 32-byte key commitment. - **Pattern B — Hosted One-Time Secret / Shortcode (`store_sealed_envelope: true`, `reveal_policy: "once"`)**: - `seal_payload_b64` must decode to **`≤ 512 bytes`** (returns `HTTP 413` if larger). BitBop hosts `sealed_envelope` alongside the sealed key and permanently burns both on the first valid `/escrow/reveal`. - **Optional Controls**: - `unlock_after_seconds`: Integer `>= 0` time-lock embargo. - `unlock_key`: Optional passphrase/PIN (stored only as `SHA-256` hash). #### Request (`cURL` — Hosted One-Time Secret with PIN) ```bash curl -s -X POST https://api.bitbop.dev/escrow/commit \ -H "Authorization: Bearer test-key-1" \ -H "Content-Type: application/json" \ -d '{ "context_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "reveal_policy": "once", "unlock_after_seconds": 0, "signature_scheme": "ml-dsa-44", "seal_payload_b64": "UVJCT1AtNzc0MS1YOSA6OiByb290LXBhc3M6IEs5I21QMiR2TDhAcVI1IQ==", "store_sealed_envelope": true, "unlock_key": "rosebud-42" }' ``` #### Response (`200 OK`) ```json { "escrow_id": "esc_8f91a2c4b5e6...", "context_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "reveal_policy": "once", "unlock_at": "2026-10-19T07:52:00.000Z", "requires_unlock_key": true, "store_sealed_envelope": true, "beacon_sequence": 14424, "beacon_hash": "sha256:...", "sealed_envelope": { "cipher": "aes-256-gcm", "key_derivation": "sha256(utf8(entropy_hex))", "iv_hex": "f0112233445566778899aabb", "ciphertext_b64": "...", "plaintext_bytes": 43, "plaintext_sha256": "sha256:..." }, "signature_scheme": "ml-dsa-44", "signature": "mldsa44:...", "timestamp": "2026-10-19T07:52:00.000Z" } ``` --- ### 3.6 `POST /escrow/reveal` (Public — Mandatory `ML-KEM-768` E2EE, No API Key Required) Encapsulates the escrowed entropy slice via `ML-KEM-768 + AES-256-GCM` (`cipher` field) and releases `sealed_envelope` (if `store_sealed_envelope: true`) once policy checks pass: - Returns `HTTP 425 Too Early` if `now < unlock_at`. - Returns `HTTP 403 Forbidden` (or `HTTP 429` during per-IP exponential backoff after 5 failures) if `unlock_key` is missing or wrong (does **not** burn `"once"` escrows on wrong PIN). - Returns `HTTP 409 Conflict` if `reveal_policy === "once"` was already revealed and burned. #### Request (`Node.js / @bitbop/sdk` — Automated `ML-KEM-768` & Envelope Decryption) ```javascript const revealed = await client.escrowReveal('esc_8f91a2c4b5e6...', { unlockKey: 'rosebud-42', }); console.log(revealed.entropy_hex, revealed.unsealed_text); ``` #### Raw Wire Request (`POST /escrow/reveal`) ```json { "escrow_id": "esc_8f91a2c4b5e6...", "unlock_key": "rosebud-42", "kyber_public_key": "<2,368 hex chars (1,184-byte ML-KEM-768 public key)>", "signature_scheme": "ml-dsa-44" } ``` #### Response (`200 OK` — Top-Level Signed Receipt + `cipher` + `sealed_envelope`) > **IMPORTANT**: `POST /escrow/reveal` (and `POST /escrow/commit`) return the signed receipt fields (`escrow_id`, `commitment_hash`, `beacon_sequence`, `beacon_hash`, `signature_scheme`, `signature`) at the **top level** of the JSON response (`data` itself is the signed receipt — there is NO nested `data.receipt` sub-object). To verify provenance, POST the entire response object `data` directly to `POST https://api.bitbop.dev/verify` or `POST https://api.bitbop.dev/verify/escrow_receipt`, or link users to `https://www.bitbop.dev/provenance?sequence=${data.beacon_sequence}&escrow_id=${data.escrow_id}`. ```json { "version": "1.0", "escrow_id": "esc_8f91a2c4b5e6...", "delivery_mechanism": "ML-KEM-768 + AES-256-GCM", "cipher": { "kyber_ciphertext_hex": "<2,176 hex chars>", "aes_iv_hex": "<24 hex chars>", "aes_ciphertext_hex": "<96 hex chars (32B raw entropy + 16B GCM tag)>" }, "context_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "commitment_hash": "sha256:...", "entropy_sha256": "sha256:...", "beacon_sequence": 14424, "beacon_hash": "sha256:...", "beacon_byte_offset": 88120, "byte_count": 32, "reveal_policy": "once", "reveal_count": 1, "failed_unlock_attempts": 1, "unlock_at": "2026-10-19T07:52:00.000Z", "timestamp_committed": "2026-10-19T07:52:00.000Z", "timestamp_revealed": "2026-10-19T07:52:15.000Z", "signature_scheme": "ml-dsa-44", "sealed_envelope": { "cipher": "aes-256-gcm", "key_derivation": "sha256(utf8(entropy_hex))", "iv_hex": "f0112233445566778899aabb", "ciphertext_b64": "...", "plaintext_bytes": 43, "plaintext_sha256": "sha256:..." }, "signature": "<4,840 hex chars (2,420-byte ML-DSA-44 signature)>" } ``` #### Client-Side Decryption (`Node.js / WebCrypto` — `ML-KEM-768` `cipher` + `sealed_envelope`) ```javascript import crypto from 'node:crypto'; import { MlKem768 } from 'mlkem'; // Exact export in mlkem v2.7+: MlKem768 class (NOT Mlkem768 or mlkem768) const kem = new MlKem768(); const [publicKey, secretKey] = await kem.generateKeyPair(); // Returns [Uint8Array(1184), Uint8Array(2400)] tuple const kyberPublicKeyHex = Buffer.from(publicKey).toString('hex'); // Step 1: Decapsulate reveal.cipher using ML-KEM-768 + AES-256-GCM to recover the 64-char entropyHex // IMPORTANT: Use the 32-byte ML-KEM sharedSecret DIRECTLY as the AES-256-GCM key (do NOT SHA-256 hash sharedSecret), // and convert the decrypted 32 raw bytes to hex (.toString('hex')) to get entropyHex! async function decapBitBopCipherNode(cipher, secretKey, kemInstance = kem) { const sharedSecret = await kemInstance.decap(Buffer.from(cipher.kyber_ciphertext_hex, 'hex'), secretKey); const iv = Buffer.from(cipher.aes_iv_hex, 'hex'); const buf = Buffer.from(cipher.aes_ciphertext_hex, 'hex'); const decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(sharedSecret), iv); decipher.setAuthTag(buf.subarray(buf.length - 16)); const rawEntropyBytes = Buffer.concat([decipher.update(buf.subarray(0, buf.length - 16)), decipher.final()]); return rawEntropyBytes.toString('hex'); // 64-char hex string } // Step 2: Unseal reveal.sealed_envelope using SHA-256(utf8(entropyHex)) function unsealBitBopEnvelopeNode(entropyHex, sealedEnvelope) { const aesKey = crypto.createHash('sha256').update(entropyHex, 'utf8').digest(); const iv = Buffer.from(sealedEnvelope.iv_hex, 'hex'); const buf = Buffer.from(sealedEnvelope.ciphertext_b64, 'base64'); const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv); decipher.setAuthTag(buf.subarray(buf.length - 16)); return Buffer.concat([decipher.update(buf.subarray(0, buf.length - 16)), decipher.final()]).toString('utf8'); } ``` --- ### 3.7 `POST /verify` (Public — Cryptographic Receipt Verifier) Verifies any `/consume`, `/order`, or `/escrow/reveal` receipt against the historical signed beacon chain: 1. Confirms the referenced beacon `#` exists and its `SHA-256` hash matches `beacon_hash`. 2. Verifies the hardware `ML-DSA-44` signature on the beacon block. 3. Confirms the exact slice at `beacon_byte_offset` matches the receipt's entropy digest (`entropy_bound_to_beacon: true`). 4. Replays Fisher-Yates 32-bit rejection sampling (for `/order` receipts) and verifies the `ML-DSA-44` receipt signature. #### Request (`cURL`) ```bash curl -s -X POST https://api.bitbop.dev/verify \ -H "Content-Type: application/json" \ -d @receipt.json ``` #### Response (`200 OK`) ```json { "valid": true, "receipt_type": "consume", "checks": { "beacon_exists": true, "beacon_hash_match": true, "beacon_signature_valid": true, "entropy_bound_to_beacon": true, "receipt_signature_valid": true } } ```