reproducibility
← Back to app Bitcoin-PIR/Bitcoin-PIR

Reproducing runtime and database attestation

Verify four connected claims: weikeng2.bitcoinpir.org is running the pinned SEV-SNP runtime, the served database roots bind to a Bitcoin Core MuHash, the direct ORAM rebuild is source-bound to the attested database inputs, and the block anchor is checked by the blockhash-to-muhash proof.

Four proofs, four failure modes

  • Runtime attestation checks the live server binary, launch MEASUREMENT, channel binding, and AMD VCEK chain. A red measurement mismatch in the app belongs to this layer.
  • Database build attestation checks the attested-builder evidence, Bitcoin Core MuHash, and PIR Merkle roots. A blue verified DB proof badge belongs to this layer.
  • Bitcoin/MuHash anchor proof checks that both database endpoint block hashes and the latest MuHash appear as separate blockhash-to-muhash Merkle leaves under one SEV-SNP-attested chunk root. A green Bitcoin anchor badge belongs to this layer.
  • ORAM source binding checks that oramctl build-direct --strict-source-binding consumed the preserved roots-only direct inputs from the attested builder and emitted the pinned direct ORAM image hashes and controller authentication roots.

The non-collusion argument

The two-server PIR security model needs two non-colluding servers to keep query content private. weikeng1.bitcoinpir.org and weikeng2.bitcoinpir.org run on different physical machines, but they share one operator.

SEV-SNP attestation is the deployment's answer to that operator-trust gap. The two hosts play asymmetric roles:

  • pir1 (Hetzner, no SEV) serves the HarmonyPIR hint phase plus DPF server-0 and OnionPIR queries. Its binary hash is pinned, but there is no hardware-backed proof that the running code matches.
  • pir2 (VPSBG, SEV-SNP, Tier 3 UKI) serves the HarmonyPIR query phase, DPF server-1, and the direct ORAM lookup path. AMD's PSP signs a MEASUREMENT over the loaded image and the client's pre-negotiated channel pubkey via REPORT_DATA binding.

Wire-level enforcement keeps the roles explicit: --serve-hints and --serve-queries are checked by runtime/src/bin/unified_server.rs. A client asking pir2 for hints gets a clean wire-level rejection rather than a silent fall-through.

The runtime trust chain

git commit ──build──▶ unified_server binary │ │ dracut + ukify ▼ │ pinned VPSBG OVMF ────┘ │ └──┐ ┌── UKI bytes (kernel + initramfs + cmdline) ▼ ▼ sev-snp-measure │ ▼ predicted MEASUREMENT │ ═══ compare to ═══ │ ▼ chip-signed MEASUREMENT (from bpir-admin attest)

If your computed value matches the chip-signed value, the runtime claim is anchored down to the AMD ARK.

Frontend-expected runtime pins ORAM UKI — 2026-06-27

These are the values the browser bundle expects for pir2. They are not a live-status feed. If the app shows a measurement mismatch, first confirm which VPSBG UKI or boot slice is actually running; only rotate these pins after intentionally deploying and verifying a new UKI.

MEASUREMENT f0d449e04c27ba2bf5b96790d58d9b1d5b789c7c560f16bc9d3f8bb26c78391ae7d3bb55deeea1bf7ef07c1671ad8da0
UKI sha256 3ef8249b673efc96ea5cdc74671871558b35948beeb6411186226b367fb40a60
binary sha256 233541886714f1eec9ca90cf876c33774b9fd07cae2d6e3a2c9d555ef5e53fb3
server git rev f402466af1ee21d02e0a65b457ad338ceb1216c0
OVMF sha256 e4ac90be71f3b455922ebc7106c5630536bf67027de585e34319b0a42fcd716e
AMD ARK fingerprint 1f084161a44bb6d93778a904877d4819cafa5d05ef4193b2ded9dd9c73dd3f6a

Source of truth: web/src/attest-pin.ts::PIR2_TIER3_PIN.

What a mismatch means

A red runtime badge with MEASUREMENT pin mismatch means the server returned a valid SEV-SNP report, but the launch MEASUREMENT does not equal the frontend pin. That is different from noSevHost, and also different from DB proof failure.

  1. Check the VPSBG measured-boot selection and active UKI.
  2. Run bpir-admin attest to capture the live measurement and binary hash.
  3. Only update PIR2_TIER3_PIN if the new UKI is intended and externally reproducible.

Verify via published artifacts

Download the OVMF, obtain or rebuild the ORAM Tier 3 UKI bytes, run sev-snp-measure, then compare the predicted value to the chip-signed value from bpir-admin attest.

  1. Get the OVMF

    VPSBG's custom EDK2 build is used when measured boot is enabled in the portal.

    OVMF_SEV_MEASUREDBOOT_4M.fd (4.0 MB)

    Verify: sha256sum OVMF_SEV_MEASUREDBOOT_4M.fde4ac90be71f3b455922ebc7106c5630536bf67027de585e34319b0a42fcd716e

  2. Get or rebuild the UKI

    The current operator-published artifact is bpir-tier3-oram-f402466a.efi, the ORAM-enabled Tier 3 UKI that serves the database proof sidecar and direct ORAM lookups for db_id 0/1. It is a large runtime artifact, so this page pins the exact bytes by hash and records the rebuild route rather than inlining the UKI into the static proof bundle.

    Verify: sha256sum bpir-tier3-oram-f402466a.efi3ef8249b673efc96ea5cdc74671871558b35948beeb6411186226b367fb40a60

    scp pir-hetzner:/home/pir/uki-archive/tier3/oram-f402466a/bpir-oram-runtime-f402466.bundle .
    git clone https://github.com/Bitcoin-PIR/Bitcoin-PIR.git BitcoinPIR-oram-repro
    cd BitcoinPIR-oram-repro
    git checkout a8863f82cd880d911fe49a7186b0ad4c0b6139d7
    git fetch ../bpir-oram-runtime-f402466.bundle \
        refs/heads/codex/oram-runtime-5f36649:refs/heads/codex/oram-runtime-5f36649
    git checkout f402466af1ee21d02e0a65b457ad338ceb1216c0
    RUSTFLAGS="--remap-path-prefix=$PWD=/build/repo --remap-path-prefix=$HOME=/build" \
    SOURCE_DATE_EPOCH=0 cargo build --locked --release -p runtime --features cuckoo-oram --bin unified_server
    strip --strip-debug target/release/unified_server
    
    OUT=/tmp/bpir-tier3-oram-f402466a.efi \
    BINARY="$PWD/target/release/unified_server" \
    BPIR_UNIFIED_SERVER_BIN="$PWD/target/release/unified_server" \
    ./scripts/build_uki_tier3.sh

    The operator-side recipe, build-host archive paths, and validation gates are recorded in docs/ORAM_TIER3_PRODUCTION_HANDOFF.md.

  3. Predict the MEASUREMENT

    sev-snp-measure \
    	    --mode snp \
    	    --vcpus 2 \
    	    --vcpu-sig 0x00B10F10 \
    	    --ovmf OVMF_SEV_MEASUREDBOOT_4M.fd \
    	    --kernel bpir-tier3-oram-f402466a.efi \
    	    --guest-features 0x1
  4. Verify against the live chip

    cargo build --release --bin bpir-admin -p bpir-admin
    ./target/release/bpir-admin attest wss://weikeng2.bitcoinpir.org \
        --expect-measurement f0d449e04c27ba2bf5b96790d58d9b1d5b789c7c560f16bc9d3f8bb26c78391ae7d3bb55deeea1bf7ef07c1671ad8da0 \
        --expect-binary      233541886714f1eec9ca90cf876c33774b9fd07cae2d6e3a2c9d555ef5e53fb3

    Expected checkmarks: SEV-SNP REPORT_DATA binding verified, binary_sha256 matches expected, and Launch MEASUREMENT matches expected.

  5. Smoke the ORAM path

    HASH=4242424242424242424242424242424242424242
    	cargo run --locked -p pir-sdk-client --example oram_local_smoke -- \
    	    --server wss://weikeng2.bitcoinpir.org --db-id 0 --padded-slots 25 "$HASH"
    	cargo run --locked -p pir-sdk-client --example oram_local_smoke -- \
    	    --server wss://weikeng2.bitcoinpir.org --db-id 1 --padded-slots 25 "$HASH"

    Expected runtime signal: sev_status=ReportDataMatch, secure_channel=established, and found=false for the all-42 smoke hash.

Pinned database proof delta 940611 to 948454

Runtime attestation proves which server binary is running. Database build attestation proves that the served PIR Merkle roots were produced by the SEV-SNP attested builder from the claimed Bitcoin Core UTXO snapshots.

db_id 1
build kind delta
from block 940611 · 000000000000000000002c41243b3d74d135942031ef15f547bca1ce8f85eb99
to block 948454 · 00000000000000000001ef683c02c383315db7e917c69d20f79e05985560a4e4
MuHash cf4fc1f1dd400622a5b6f39eca7f764a30570c30cc668e04f00e8a3356c2a2ee
bucket root e2ba2eee6788424309a95f771893d5401cc8e3ceec6188dc2708900e211a910a
onion root f86baa3966a61cdcd70d8c0ad9bed233f591806eb351db2ae35ac0192a3fe997
builder binary 34a677847b9be6580385c73f163279c81561772f8d3ad782d0ca08f1c01fad4a
builder commit 01e8db91d76037cd5562fce85c40e832ad156431
params hash 2b3e488c04433ed8bd293fd3adab72b49bf52346b81160365486d76f9b4d4e39

Source of truth: web/src/attest-pin.ts::PRODUCTION_DB_PROOF_PINS and docs/DB_BUILD_ATTESTATION_PLAN.md.

Verify the live database proof

cargo build --release --bin bpir-admin -p bpir-admin
	./target/release/bpir-admin db-proof verify-live \
	    --server wss://weikeng2.bitcoinpir.org \
	    --db-id 1 \
	    --expect-build-kind delta \
	    --expect-from-height 940611 \
	    --expect-height 948454 \
	    --expect-from-block-hash 000000000000000000002c41243b3d74d135942031ef15f547bca1ce8f85eb99 \
	    --expect-block-hash 00000000000000000001ef683c02c383315db7e917c69d20f79e05985560a4e4 \
	    --expect-muhash cf4fc1f1dd400622a5b6f39eca7f764a30570c30cc668e04f00e8a3356c2a2ee \
	    --expect-bucket-root e2ba2eee6788424309a95f771893d5401cc8e3ceec6188dc2708900e211a910a \
	    --expect-onion-root f86baa3966a61cdcd70d8c0ad9bed233f591806eb351db2ae35ac0192a3fe997 \
	    --expect-builder-binary-sha256 34a677847b9be6580385c73f163279c81561772f8d3ad782d0ca08f1c01fad4a \
	    --expect-builder-git-commit 01e8db91d76037cd5562fce85c40e832ad156431 \
	    --expect-network-magic f9beb4d9 \
	    --expect-params-hash 2b3e488c04433ed8bd293fd3adab72b49bf52346b81160365486d76f9b4d4e39

Repeat with --server wss://weikeng1.bitcoinpir.org to confirm both hosts serve the same self-verifying proof bundle.

ORAM source binding snapshot 948454

The ORAM client that builds and uses the direct ORAM image runs in the TEE. The remaining public question is whether it used the right source database files. This proof binds the direct ORAM build to the preserved roots-only inputs emitted by the SEV-SNP attested builder for Bitcoin Core snapshot 948454.

manifest /proofs/oram-source/mainnet_948454.json
builder UKI sha256 49f452c9b95f1562002ad74364cf43f68244a5dd2a9073bf32279cb2f83d9d3b
builder MEASUREMENT 69ca84b97943370dab01c673da7e2a06e4e8ded5125aac91cba0749c4e967fe6677e7b5471d4db2d058bc02abce93b21
builder commit b692aec18b9c20ac92cb9fe22588e96ff96ad27d
builder binary d4da29807e806c8a16eec94b86119bd16df7805a66fa4ff1c187a26832a36427
snapshot MuHash cf4fc1f1dd400622a5b6f39eca7f764a30570c30cc668e04f00e8a3356c2a2ee
index source d0b9573488abdda8e17dc52bb52bf5ff11520b4511683020f5f1a22bc8d8d26c · 1,345,875,975 bytes
chunk source 9a81a02bf82af49414b5f2ae6380c97c1f231fcac6890b605f6cde22b0adc521 · 3,239,380,480 bytes
ORAM repo commit 5f366492504d8e853cbd60d25a6adbf021a78746
oramctl sha256 d3958944592d2bf425f54dd6fcae7f542f6ac54a93dc4d1df8f11483dfaf96ef
index seed 8030603977422561841 · 0x6f726fc4fe1c6231
large image archive /home/pir/data/oram-builds/mainnet_948454_direct-pack16-z2-div2-stash128-auth-strict

What the browser verifier checks

  • The ORAM source manifest and every compact artifact match their pinned SHA-256 and size.
  • The raw SNP report's REPORT_DATA and MEASUREMENT match the attested builder proof.
  • oram-build-evidence.json has strict_source_binding=true and cites the same DB evidence and root bundle payload.
  • direct-inputs.sha256 matches the index and chunk source hashes embedded in the ORAM evidence.
  • The exact 64-bit index_seed is compared as text, not as a rounded JavaScript number.
  • The output image hashes in SHA256SUMS match the output hashes embedded in the ORAM evidence.
  • The controller authentication roots for index and chunk metadata/payload match the pinned manifest roots.

Strict rebuild command

On a host with the archived direct inputs, the strict rebuild was produced with the command below. The static web bundle publishes the compact evidence and hashes; it does not publish the 4.3 GiB direct inputs or 15 GiB ORAM images.

oramctl build-direct \
	    --index-file /home/pir/data/attestations/mainnet_948454_oram_sev_snp/run/oram-direct-inputs/utxo_chunks_index_nodust.bin \
	    --chunks-file /home/pir/data/attestations/mainnet_948454_oram_sev_snp/run/oram-direct-inputs/utxo_chunks_nodust.bin \
	    --out-dir /home/pir/data/oram-builds/mainnet_948454_direct-pack16-z2-div2-stash128-auth-strict \
	    --level all \
	    --pack 16 \
	    --leaf-divisor 2 \
	    --bucket-size 2 \
	    --stash-capacity 128 \
	    --cache-levels 0 \
	    --index-slots-per-bin 4 \
	    --index-hash-fns 2 \
	    --index-load-factor 0.95 \
	    --index-seed 8030603977422561841 \
	    --auth-store \
	    --auth-trusted-levels 1 \
	    --auth-hash-page-size 4096 \
	    --db-build-evidence /home/pir/data/attestations/mainnet_948454_oram_sev_snp/run/build-evidence.bin \
	    --root-bundle-payload /home/pir/data/attestations/mainnet_948454_oram_sev_snp/run/root-bundle-payload.bin \
	    --expected-muhash cf4fc1f1dd400622a5b6f39eca7f764a30570c30cc668e04f00e8a3356c2a2ee \
	    --expected-index-sha256 d0b9573488abdda8e17dc52bb52bf5ff11520b4511683020f5f1a22bc8d8d26c \
	    --expected-chunks-sha256 9a81a02bf82af49414b5f2ae6380c97c1f231fcac6890b605f6cde22b0adc521 \
	    --strict-source-binding

Controller authentication roots

index meta de2a8cbca84776aa14c04d4227d72295f8effb85048e89cfaa76561899ebeaa7
index payload 1ddf087c995947d245f04c323b85a06e799981650227ef64dd649fbb7c83c37d
chunk meta 1bc1ed8a2b219ed06712db91b613704c26c474ea19182aaf3832efecaa9bc241
chunk payload 4f059feddacf0e5f9160e03e16ceb06293f55b656a151a4a851daaa36fdfc9d7

Deployment boundary

This page verifies the strict source-bound rebuild and records the live pir2 runtime that consumes it. The pinned pir2 runtime commit f402466af1ee21d02e0a65b457ad338ceb1216c0 vendors bitcoinpir-oram at 5f366492504d8e853cbd60d25a6adbf021a78746.

Live verification on the refreshed measured UKI passed bpir-admin attest, channel-test, and padded direct ORAM smoke requests for both db_id 0 and db_id 1. The UKI bytes are archived on Hetzner at /home/pir/uki-archive/tier3/oram-f402466a/.

Bitcoin/MuHash anchor proof 940611 → 948454

The delta database proof binds both endpoint block hashes and Bitcoin Core's MuHash at block 948454. The browser verifies a separate BHTM Merkle inclusion proof for each endpoint against the same SEV-SNP-attested mainnet-900000-954920 chunk root. The latest leaf also binds the database MuHash.

from block 940611 · 000000000000000000002c41243b3d74d135942031ef15f547bca1ce8f85eb99 · ✓ BHTM inclusion proof verified
latest block 948454 · 00000000000000000001ef683c02c383315db7e917c69d20f79e05985560a4e4 ↗
MuHash cf4fc1f1dd400622a5b6f39eca7f764a30570c30cc668e04f00e8a3356c2a2ee
BHTM chunk mainnet-900000-954920
from leaf index 40611 · d36ee0c4a44b2a392993c7a6a8ffaa0c69225e2187a46fcbef64a79e67dcf856
latest leaf index 48454 · 0171a475dc43b97db594c7512039d12f5213d270b42e56babfa44d65359eeaaf
tree root babeea635812c3b1a2d5f352ab0a5d1ee8a4e9c668c43c05d6603ef3c3766ba6
BHTM UKI measurement 652f8c813382abb0c09a7bdc6528e6a3494f9f0833eb087349ad5dac76dec140532763fec8eeaf3fa52723b6a5de8279

What the browser checks

  • The verified live server proof matches the published manifest at both delta endpoints, the MuHash, and both PIR Merkle roots.
  • Separate BHTM proofs recompute both endpoint leaf hashes and Merkle paths to the same attested chunk tree root.
  • report-data.bin equals SHA512("BitcoinPIR/blockhash-to-muhash/report-data/v2" || attestation.bin).
  • The SNP report's raw REPORT_DATA field equals report-data.bin.
  • The SNP report's raw MEASUREMENT field equals the pinned BHTM UKI measurement.
  • The AMD VCEK chain and report signature verify through the same WASM verifier used for runtime attestation.
  • Both DB endpoint heights and block hashes equal their BHTM leaves; the latest leaf also equals the DB proof's Core-display MuHash.

The latest-block mempool.space link is an independent user cross-check, not an input to the cryptographic verifier. The earlier endpoint is checked by its own inclusion proof under the same attested root; the attested BHTM process also validates header linkage across the chunk.

Published proof artifacts

The production frontend loads the manifest below, verifies each artifact's SHA-256 and size, then verifies the DB/BHTM chain.

pir1 verification (Hetzner, no SEV)

weikeng1.bitcoinpir.org runs the db-proof unified_server binary on a Hetzner i7-8700. It is intentionally pinned independently from pir2's ORAM Tier 3 UKI. Without a hardware root of trust, the client verifies pir1's self-reported binary_sha256 against a pinned value.

binary sha256 d01e5b7aab2b3075eed4dd154ffc2079aae394b418a40155128166a50ace750a

Verify pir1

cargo build --release --bin bpir-admin -p bpir-admin
	./target/release/bpir-admin attest wss://weikeng1.bitcoinpir.org \
	    --expect-binary d01e5b7aab2b3075eed4dd154ffc2079aae394b418a40155128166a50ace750a

You can also check sha256sum /home/pir/BitcoinPIR/target/release/unified_server directly on the Hetzner host.

What this proves

  • pir1 and pir2 have independent binary pins; pir2 is additionally bound to the ORAM Tier 3 UKI MEASUREMENT.
  • For pir2, AMD signs the loaded confidential-VM runtime and channel binding.
  • For pir1, binary-hash pinning detects drift but does not provide a hardware root of trust.
  • The database proof binds delta_940611_948454's bucket and OnionPIR Merkle roots to Bitcoin Core's MuHash at block 948454.
  • The ORAM source-binding proof binds a strict direct ORAM rebuild to roots-only snapshot inputs preserved by the SEV-SNP attested builder for block 948454.
  • The Bitcoin anchor proof binds both delta endpoint block hashes and the latest MuHash to one blockhash-to-muhash chunk tree root signed by a separate SEV-SNP BHTM proof run.
  • The web client refuses to upgrade to the encrypted channel if runtime pins do not match what the server reports.
  • The ORAM smoke route confirms the live attested binary accepts padded direct ORAM requests for both production databases.

Out of scope

  • The custom OVMF binary is binary-pinned, not rebuilt from EDK2 source by this project.
  • The --impure Nix build sources VPSBG's validated kernel from the build host.
  • AMD's signing keys are trust roots; the project pins the AMD ARK fingerprint but cannot remove AMD from the trust base.
  • The BHTM proof is an attested MuHash transition from Core-style stripped deltas. It checks header linkage and txid Merkle commitments; it is not a full Bitcoin consensus validator inside the TEE.
  • The strict ORAM source-binding proof is not yet a live-image byte-match claim. The current pir2 runtime vendors an older ORAM commit, so a refreshed ORAM runtime/data deployment is still required for that stronger statement.
  • The web DB proof badge is advisory today for DPF and HarmonyPIR. Strict mode still needs to wire verified roots directly into query-path Merkle verification, and standalone OnionPIR still needs its browser-side DB proof verifier.