Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# Standalone workspace — deliberately NOT a member of the repo-root
# workspace. This directory is designed to be extracted into its own
# repository (see PLAN.md §6) with `git mv` / `git filter-repo`; until
# then it builds independently against the repo's vendored sources
# (the root .cargo/config.toml source replacement applies here too).
# Standalone workspace. Current scope is README.md; PLAN.md is a frozen
# 2026-06 design note. This repository is already Bitcoin-PIR/attested-builder.

[workspace]
resolver = "2"
Expand Down
14 changes: 11 additions & 3 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# Attested Builder — Execution Plan
# Attested Builder — Execution Plan (frozen 2026-06-12)

Status: Phase 0 started 2026-06-12 (this directory). Owner decision log
at the bottom.
**Not current.** This file is the original design note (k-of-n Ed25519
root bundles, Nitro/TDX, client strict mode). What the repo actually
produces, and what it deliberately does not, is in [README.md](README.md).

Do not treat Phase 2–4 below as a backlog that means a backend is
unattested. Production trust is BuildEvidence v2 + SEV-SNP report-data
binding, consumed by BitcoinPIR pin tables.

Status when written: Phase 0 started 2026-06-12. Owner decision log at
the bottom.

## Goal

Expand Down
146 changes: 146 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Attested builder

Standalone producer of BitcoinPIR production databases and build
evidence. It is not the serving runtime, not the browser verifier, and
not a multi-builder quorum service.

The locked production commit is the one BitcoinPIR pins in
`PRODUCTION_ORAM_DB_PROOF_V2_PINS` and
`scripts/build_uki_attested_builder_tier3.sh`. Do not copy that hash
into this file. Operator steps that boot this code on VPSBG live in
BitcoinPIR: Flow H in `docs/PRODUCTION_OPERATIONS.md` and
`docs/ATTESTED_BUILDER_TIER3_UKI.md`.

`PLAN.md` is a frozen 2026-06 design note (k-of-n Ed25519 bundles,
Nitro, client strict mode). It is not the current contract.

## What one production run covers

A production generation is one native full-build V2 pipeline:

| Mode | Script | Input |
| --- | --- | --- |
| Snapshot | `scripts/build-snapshot-database.sh` | one Core `dumptxoutset` v2 file + `gettxoutsetinfo muhash` |
| Delta | `scripts/build-delta-database.sh` | two snapshot files + both MuHashes; set-diff is inside this process |

The measured UKI only accepts:

- `MODE=native-full-build-v2-snapshot`
- `MODE=native-full-build-v2-delta`
- `MODE=reattest-existing-v2` (proof-migration only; ineligible for
production TEE-ORAM)

Native V2 forces `ROOTS_ONLY=0`, `STAGE_SERVER_DB=1`, `RUN_ONION_FFI=1`,
`BUILD_EVIDENCE_VERSION=2`. `latest/` is published only after the
runner sees V2, `evidence_mode=full_build`, and no predecessor hashes.

From those inputs the same run emits every serving backend's bytes:

| Backend | Artifacts | Bound in evidence |
| --- | --- | --- |
| DPF-PIR | `batch_pir_cuckoo.bin`, `chunk_pir_cuckoo.bin`, bucket Merkle | `bucket_super_root` |
| HarmonyPIR queries | same INDEX/CHUNK + bucket Merkle as DPF | same `bucket_super_root` |
| OnionPIR | packed entries, cuckoo, Merkle, FFI `onion_shared_ntt.bin` / `onion_index_all.bin` / sibling rows | `onion_super_root` + typed Onion v2 layout |
| Direct ORAM | `oram-direct-inputs/utxo_chunks_{index,}_nodust.bin` and `[direct_oram]` in `server-db/MANIFEST.toml` | server-db manifest hash |

Plus the trust sidecars the BitcoinPIR runtime serves verbatim:

- `server-db/` (server-loadable tree + `MANIFEST.toml`)
- `root-bundle-payload.bin` (v2 payload; scanner-verified Onion layout)
- `build-evidence.bin` / `build-evidence.report-data`
- `build-evidence.sev-snp-report.bin` when `EMIT_SEV_SNP_QUOTE=1`
- `database.manifest.sha256`, `all-artifacts.manifest.sha256`

There is no separate “DPF builder” or “Onion builder”. A collection
assembled after the fact is not a production candidate.

## What this repo does not cover

These are out of scope here, not unfinished backends:

| Concern | Where it actually lives |
| --- | --- |
| Harmony hint blobs | pir1 runtime hint pool; fingerprint-checked in the browser, not a DB-proof family |
| BHTM / trust-chain (`fromMuhash`, block hash) | `Bitcoin-PIR/bhtm` producer; BitcoinPIR `web/public/proofs/trust-chain/` |
| Serving pir1 binary pin | BitcoinPIR `PIR1_PIN` |
| Serving pir2 UKI measurement | BitcoinPIR `PIR2_TIER3_PIN` (runtime UKI, not this image) |
| Formal / EasyCrypt wire-shape | BitcoinPIR `verification/locks/formal-proofs.json` |
| Client k-of-n builder-key quorum | `PLAN.md` Phase 2; not shipped. Production clients pin evidence + builder binary/commit |
| Nitro / TDX guests | not implemented; SEV-SNP `/dev/sev-guest` is the only quote provider |
| Multi-builder diversity | not implemented |
| Development databases | BitcoinPIR `scripts/build_full.sh` / `tools/db-builder` — must not produce a production rotation |

`BUILD_EVIDENCE_VERSION=1` and `ROOTS_ONLY=1` still exist as host/legacy
paths. They are not the production UKI contract. `reattest-existing-v2`
can re-bind already-built serving images and must report
`direct_oram_eligible=no`.

The live BitcoinPIR `940611 -> 948454` lineage is a mixed-provenance
exception retained on that side. Do not rebuild it here to make the
history look uniform.

## How BitcoinPIR consumes the output

BitcoinPIR does not treat this repo as the live pin catalog.

| Evidence | BitcoinPIR pin / lock | Who verifies |
| --- | --- | --- |
| V2 Onion layout + roots | `PRODUCTION_ONION_DB_PROOF_V2_PINS` | browser / WASM; local `db-proof verify` |
| V2 ORAM + producer identity | `PRODUCTION_ORAM_DB_PROOF_V2_PINS` + `verification/locks/generated-proofs.json` | same local v2 path; not `verify-live` |
| Builder SNP report | `web/public/proofs/oram-source/` | `pir-attested-builder verify-build-evidence` |
| DPF / Harmony roots | same V2 `bucket_super_root` | bound in this run's evidence; BitcoinPIR still *transports* them on the v1 opcode |

`proof_dir` vs `proof_v2_dir` is a BitcoinPIR packaging split, not a
second producer. The production UKI emits one V2 sidecar set. It does
not emit a parallel `BUILD_EVIDENCE_VERSION=1` directory. Live DPF and
Harmony clients still fetch `REQ_GET_DB_PROOF` and pin
`PRODUCTION_DB_PROOF_PINS` (no `proofVersion`); that table currently
names the retained mixed-provenance v1 sidecars. A new height therefore
has attested DPF/Harmony *bytes* in the V2 evidence, but no UKI-produced
v1 sidecar for that opcode. Do not invent a second producer to close
that packaging gap, and do not pair a `server-db` from one run with
evidence from another.

## Layout

| Path | Role |
| --- | --- |
| `coremuhash/` | Bitcoin Core MuHash3072 |
| `utxosnapshot/` | Core v2 `dumptxoutset` parser + MuHash gate |
| `dbpipeline/` | Deterministic INDEX/CHUNK/Onion/Merkle stages |
| `onionffi/` | Optional C++ OnionPIR preprocess (`--features ffi`) |
| `rootbundle/` | Canonical payload + optional Ed25519 wrapper |
| `builder/` | `pir-attested-builder` CLI |
| `scripts/build-snapshot-database.sh` | Snapshot orchestration |
| `scripts/build-delta-database.sh` | Delta orchestration |
| `scripts/local-regtest-e2e.sh` | Committed-fixture smoke |
| `scripts/local-mainnet-build.sh` | Owner-host wrapper; not a production authorization |
| `fixtures/` | Golden parser/MuHash vectors |

## Commands

```bash
cargo test --workspace
scripts/local-regtest-e2e.sh
```

Inspect or verify a finished output:

```bash
pir-attested-builder inspect-build-evidence OUT/build-evidence.bin
pir-attested-builder verify-build-evidence OUT/build-evidence.bin \
--snapshot SNAPSHOT --builder-bin BIN \
--payload OUT/root-bundle-payload.bin \
--database-manifest OUT/database.manifest.sha256 \
--all-artifacts-manifest OUT/all-artifacts.manifest.sha256 \
--server-db-manifest OUT/server-db/MANIFEST.toml \
--expected-muhash MUHASH \
--expected-anchor-height HEIGHT \
--sev-snp-report OUT/build-evidence.sev-snp-report.bin
```

`--expect-*` values come from the independently accepted generation
record, never from a live PIR server.

Wire-format changes to `rootbundle` follow
`rootbundle/COMPATIBILITY.md`.
2 changes: 1 addition & 1 deletion coremuhash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! `gettxoutsetinfo muhash` (`src/crypto/muhash.{h,cpp}`), reimplemented
//! bit-compatibly in Rust.
//!
//! The attested builder (see ../PLAN.md) ingests a `dumptxoutset`
//! The attested builder (see ../README.md) ingests a `dumptxoutset`
//! snapshot, recomputes this hash over every coin, and refuses to build
//! the PIR database unless it matches the muhash pinned for the chain
//! anchor. Bit-compatibility with Core is the entire point: the pinned
Expand Down
24 changes: 14 additions & 10 deletions fixtures/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# attested-builder fixtures

Golden data for Phase 1 (`utxosnapshot` parser + muhash verification).
Produced 2026-06-12 against the owner's Bitcoin node. All values below
are exact strings copied from `bitcoin-cli` output — the end-to-end
golden test must reproduce the muhash **display hex** byte-for-byte.
Golden data for `utxosnapshot` parser + muhash verification. Produced
2026-06-12 against the owner's Bitcoin node. All values below are exact
strings copied from `bitcoin-cli` output — the end-to-end golden test
must reproduce the muhash **display hex** byte-for-byte.

Current producer scope is the repo [README](../README.md). Live
BitcoinPIR pins stay in that repository's `web/src/attest-pin.ts`; the
mainnet tables below are snapshot metadata, not a pin catalog.

Core version for both fixtures: **Bitcoin Core v31.0.0**
(`getnetworkinfo` version `310000`, subversion `/Satoshi:31.0.0/`;
Expand Down Expand Up @@ -66,19 +70,19 @@ case 1 (p2sh), and the raw-script fallback (p2wpkh, p2tr), plus
amount compression across many magnitudes and VARINT heights/coinbase
flags. NOT covered: P2PK cases 2–5 (no P2PK outputs here) — the
`utxosnapshot` unit tests should take those from Core's
`compress_tests.cpp` vectors as PLAN.md Phase 1 step 1 already calls
for.
`compress_tests.cpp` vectors.

Note: the fixture is **recipe-reproducible, not byte-reproducible** —
wallet keys, txids and the muhash differ on every regeneration. The
committed `.dat` + the strings above are the canonical golden pair.

---

## 2. Mainnet production snapshots (metadata only — files stay on SSD)
## 2. Mainnet snapshots captured 2026-06 (metadata only — files stay on SSD)

These are the full and delta anchors used by the deployed production
databases:
These are the `940611` / `948454` Core snapshot records used by the
retained BitcoinPIR lineage. They are not an instruction to rebuild
that lineage.

- full snapshot: height `948454`
- delta snapshot range: `940611 -> 948454`
Expand Down Expand Up @@ -156,7 +160,7 @@ plus/minus delta -> Merkle roots/root bundle".

---

## 3. gen_1_onion dust/whale counts (PLAN.md node-task 4)
## 3. gen_1_onion dust/whale counts (historical sizing, 2026-06-12)

Re-run 2026-06-12 with `gen_1_onion --data-dir <fresh dir>` (binary
from this branch; OnionPIR entry size 3328 B, 4 partitions) against
Expand Down
2 changes: 1 addition & 1 deletion rootbundle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "rootbundle"
version = "0.1.0"
edition.workspace = true
license.workspace = true
description = "Canonical signed root bundle: binds PIR database Merkle roots to a chain anchor + muhash, with k-of-n Ed25519 verification"
description = "Canonical root-bundle payload: binds PIR Merkle roots to a chain anchor + muhash (optional Ed25519 wrapper)"
publish = false

[dependencies]
Expand Down
16 changes: 8 additions & 8 deletions rootbundle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! Canonical signed root bundle.
//!
//! The bundle is the single client-facing trust artifact of the attested
//! builder design (see ../PLAN.md): it binds the PIR database Merkle
//! roots to a chain anchor (block hash + height), the Bitcoin Core
//! `muhash` of the UTXO set the database was built from, and every
//! build parameter that affects the output bytes. Builders (plain
//! hosts, Nitro enclaves, SEV guests) each sign the identical canonical
//! payload; clients accept a database root iff at least `threshold`
//! signatures from distinct pinned builder keys verify.
//! Canonical payload that binds PIR Merkle roots to a chain anchor,
//! the Bitcoin Core `muhash` of the source UTXO set, and every
//! build parameter that affects output bytes.
//!
//! Production trust is BuildEvidence v2 plus an optional SEV-SNP
//! report (see the repo README). The Ed25519 k-of-n wrapper remains
//! available; BitcoinPIR clients pin evidence hashes rather than a
//! builder-key quorum. The 2026-06 design note is PLAN.md.
//!
//! Encoding follows the same hand-rolled, length-prefixed, canonical
//! style as `pir-identity` (no serde): one and only one byte string per
Expand Down
8 changes: 4 additions & 4 deletions scripts/local-regtest-e2e.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# Deterministic local end-to-end smoke for the tiny committed regtest fixture.
#
# This is intentionally a plain-host test. It exercises the same trust chain
# the TEE builder must run later:
# snapshot -> muhash gate -> flat UTXO set -> deterministic DB artifacts
# -> root bundle payload -> fixed-key signature -> quorum verify -> receipt.
# This is intentionally a plain-host smoke. It exercises the same
# snapshot -> muhash gate -> deterministic DB artifacts -> root payload
# chain as a native full-build, then a test-only Ed25519 wrap. Production
# TEE trust is BuildEvidence v2 + SEV-SNP, not this test key.

set -euo pipefail

Expand Down
Loading