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 AMD-signed BuildEvidence V2 commits the exact server manifest whose typed [direct_oram] table supplies the regenerate-on-boot inputs used by the measured runtime.

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 apps/server/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 (verified by attest with an ARK pin)

If your computed value matches the reported value and attest --expect-ark-fingerprint validates the certificate chain and that same report's signature, the runtime claim is anchored down to the AMD ARK.

Frontend-expected runtime pins ORAM UKI — 2026-07-24

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 d7ae6fb895380b1408b5ba7640a2eaa091754fc6279b62eb96f4bd1eee5532e95bc1df3b1485a06b3f43d648d05d3245
UKI sha256 34b04d1bfc0501c0cc222aff446a55de0a74d4e5218a21a05bf8756f8293b681
binary sha256 cc4ec24b9ecf54c962d20843a374a8235d9b71954adf05bdb4d6bb3155e16b1e
server git rev 81dd96d442d39200fee7e6c97f5c308f38126756
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 --expect-ark-fingerprint so the live measurement, binary hash, AMD chain, and report signature are verified on one response; use channel-test separately to exercise the encrypted channel.
  3. Only update PIR2_TIER3_PIN after the new UKI is intentionally deployed, its exact bytes are archived, and all validation gates pass.

Verify from pinned inputs

Download the published OVMF, obtain the operator-archived ORAM Tier 3 UKI if you have host access or rebuild it on a matching build host, then run sev-snp-measure. Finally, compare the predicted value with the live report and validate that report through the pinned AMD ARK.

  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-archived artifact is main-81dd96d4-db-proof-v2-20260724T112036Z-34b04d1bfc05.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. The archive path below is operator-only; it is not a public download URL.

    Verify: sha256sum main-81dd96d4-db-proof-v2-20260724T112036Z-34b04d1bfc05.efi34b04d1bfc0501c0cc222aff446a55de0a74d4e5218a21a05bf8756f8293b681

    # Operator-only shortcut: retrieve the exact deployed bytes.
    scp pir-hetzner:/home/pir/uki-archive/tier3/main-81dd96d4-db-proof-v2-20260724T112036Z-34b04d1bfc05.efi .

    Or perform a functional source rebuild. This is not a byte-identical reproduction of the production artifact: the production C++ objects embed their checkout path, and exact output also depends on Rust 1.94.1, GCC 13.3, GNU ld 2.42, and the host's UKI inputs.

    git clone https://github.com/Bitcoin-PIR/Bitcoin-PIR.git BitcoinPIR-runtime-repro
    cd BitcoinPIR-runtime-repro
    git checkout 81dd96d442d39200fee7e6c97f5c308f38126756
    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
    
    sudo env KERNEL=/boot/vmlinuz-7.0.0-28-generic \
    OUT="$PWD/bpir-tier3-functional-rebuild-81dd96d4.efi" \
    BINARY="$PWD/target/release/unified_server" \
    BPIR_UNIFIED_SERVER_BIN="$PWD/target/release/unified_server" \
    ./scripts/build_uki_tier3.sh

    Exact UKI bytes also depend on the documented build-host kernel, dracut, cloudflared, and initramfs inputs. The current deployment pins and validation gates are recorded in docs/history/PHASE3_ROADMAP.md.

  3. Predict the MEASUREMENT

    The command below uses the exact operator archive. For a functional rebuild, substitute its filename and expect a different SHA-256 and MEASUREMENT unless every path and toolchain input is reproduced exactly.

    sev-snp-measure \
    	    --mode snp \
    	    --vcpus 2 \
    	    --vcpu-sig 0x00B10F10 \
    	    --ovmf OVMF_SEV_MEASUREDBOOT_4M.fd \
    	    --kernel main-81dd96d4-db-proof-v2-20260724T112036Z-34b04d1bfc05.efi \
    	    --guest-features 0x1
  4. Verify the live report and AMD chain

    cargo build --locked --release --bin bpir-admin -p bpir-admin
    ./target/release/bpir-admin attest wss://weikeng2.bitcoinpir.org \
        --expect-measurement d7ae6fb895380b1408b5ba7640a2eaa091754fc6279b62eb96f4bd1eee5532e95bc1df3b1485a06b3f43d648d05d3245 \
        --expect-binary      cc4ec24b9ecf54c962d20843a374a8235d9b71954adf05bdb4d6bb3155e16b1e \
        --expect-ark-fingerprint 1f084161a44bb6d93778a904877d4819cafa5d05ef4193b2ded9dd9c73dd3f6a
    ./target/release/bpir-admin channel-test wss://weikeng2.bitcoinpir.org \
        --expect-ark-fingerprint 1f084161a44bb6d93778a904877d4819cafa5d05ef4193b2ded9dd9c73dd3f6a

    With the ARK pin, attest checks REPORT_DATA, binary, MEASUREMENT, AMD chain, and report signature on one response. channel-test then exercises a fresh attested encrypted session. Expected checkmarks: SEV-SNP REPORT_DATA binding verified, binary_sha256 matches expected, and Launch MEASUREMENT matches expected, followed by AMD ARK→ASK→VCEK chain and this attestation report's signature verified, then a successful encrypted handshake.

  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/history/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 BuildEvidence v2

The published proof binds the production Direct ORAM startup inputs to predecessor-free, AMD-attested full-build V2 database evidence. The historical v1 source proof disclosed its RNG seed and remains only as a negative forensic fixture.

db0 manifest /proofs/oram-source/current.json
db1 manifest /proofs/oram-source/current-db1.json
builder MEASUREMENT ca297ab31ed5077e66f2fbab4c89bf5f34c51fd14a0a6892b51cf5eb267af94904b63e7524a0b5137c44542f4e7b516f
builder commit 8d9d21a6be560236cb666269cf1f93a3de53bb1f
builder binary cf973a833f9b892743e451da4c2937c82865b12d8901c48ac4483b5e0696ba6f
db0 index source d0b9573488abdda8e17dc52bb52bf5ff11520b4511683020f5f1a22bc8d8d26c · 1,345,875,975 bytes
db0 chunk source 9a81a02bf82af49414b5f2ae6380c97c1f231fcac6890b605f6cde22b0adc521 · 3,239,380,480 bytes
db0 server manifest 91421138ba94e44665bef2617af296b1c1847dea13c4df29b565012d1e0b74a6
db1 index source e06fc3dedf30096124888acef3024f21a9c049d59fd8c7d518aaf8a58ac6aa16 · 125,867,300 bytes
db1 chunk source 536acb605396056118c7c0836988f369c5abbfc3f7e90732ad93e819d5188e0a · 340,230,840 bytes
db1 delta anchors 940,611 → 948,454
db1 server manifest 047a5b6713bf0df29d9de308fb47ff757243e365a9818cf746f399bea457d00c

What the browser verifies

  • AMD ARK/ASK/VCEK verifies the builder SNP report signature, policy and pinned measurement.
  • The report's REPORT_DATA is recomputed from the exact full-build V2 BuildEvidence; V1, reattestation and predecessor hashes are rejected.
  • BuildEvidence binds the root payload, database/all-artifacts manifests and exact server MANIFEST.toml.
  • The narrow typed [direct_oram] table supplies the exact input hashes, lengths, record counts and lookup layout.
  • The current live proof for the selected db0 or db1 entry and the AMD-verified, production-pinned runtime both bind that same server-manifest root.

Published minimum artifacts

Capability boundary

This is an input/source proof for the regenerate-on-boot design. It intentionally does not publish or compare ORAM output hashes, build logs, RNG seeds, controller state or controller authentication roots. Those outputs are mutable or runtime-local and do not strengthen the user's source claim.

The measured runtime remains responsible for generating and maintaining authenticated ORAM state, rejecting page or controller-state substitutions, and binding queries to the attested encrypted session. This source badge does not claim byte-for-byte identity for the current mutable ORAM files.

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.

trust-chain manifest

BHTM 940611 leaf proof JSON

BHTM 948454 leaf proof JSON

BHTM SEV-SNP report

DB build evidence

Direct ORAM db0 source-input manifest

Direct ORAM db1 source-input manifest

The ORAM verifier selects the manifest by exact db ID and runs only after receiving that matching live database proof and strict runtime attestation. Every referenced artifact is individually pinned by SHA-256 and size.

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 cc4ec24b9ecf54c962d20843a374a8235d9b71954adf05bdb4d6bb3155e16b1e

Verify pir1

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

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 the measured regenerate-on-boot path to exact Direct ORAM inputs in AMD-attested BuildEvidence V2 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.
  • DPF, HarmonyPIR, and standalone OnionPIR verify each database proof in Rust/WASM, compare it with the production pin, install the verified bucket or Onion root, and bind the fetched tree-tops before issuing an address query.
  • 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 exact production UKI is currently retained in an operator-only archive, not a public download. Publishing the 311,033,344-byte artifact or a fully pinned public build environment remains necessary for independent byte-for-byte reproduction.
  • The functional UKI rebuild depends on the checkout path, Rust/C++ toolchains, validated kernel, dracut, cloudflared, and initramfs inputs; the Git source checkout alone is insufficient to reproduce the complete UKI bytes.
  • 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 intentionally not a live-image byte-match claim. The measured runtime is trusted to generate and maintain authenticated mutable ORAM state from the verified inputs.
  • The v1 database proof does not commit the complete standalone OnionPIR query layout. The production web client therefore checks a separate, explicit layout pin and fails closed on mismatch; a future v2 proof can absorb those fields.