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

Reproducing the SEV-SNP MEASUREMENT

Independently verify that pir2.chenweikeng.com's attestation report — signed by the AMD chip — actually corresponds to the source code published in this repo. No need to trust the operator's claimed MEASUREMENT.

Why this matters

When a client connects to pir2, the server returns an SEV-SNP attestation report. AMD's PSP signs a MEASUREMENT field that's a hash over the host's launch context (firmware + kernel + initramfs + cmdline). The client matches that signed value against a hardcoded pin (web/src/attest-pin.ts::PIR2_TIER3_PIN) — if they don't match, the encrypted channel won't come up.

That alone establishes "the chip is running what the operator pinned." But how do you know the pinned value corresponds to the source you can read on GitHub? You compute it yourself from the published artifacts, and check against what the chip signs.

The 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)

Each step has a published, verifiable input. If your computed value matches the chip-signed value, the entire chain is trustworthy down to the AMD ARK.

Currently pinned values v11 — 2026-05-05

MEASUREMENT 0662adca3ef25ead88ae763684b6a7261e6d71e75e0a197f26c2439a3b6511c86019968bbd4a44c049ea8e6eb636c346
UKI sha256 bd243f817d463114dea187630fa8b0911ccd99cb7b37d39177b9f22e27cc7330
binary sha256 f9daecb103104c58c40440738557785febdfe2c9724de5b3506bca22a5265c9c
OVMF sha256 e4ac90be71f3b455922ebc7106c5630536bf67027de585e34319b0a42fcd716e
AMD ARK fingerprint 1f084161a44bb6d93778a904877d4819cafa5d05ef4193b2ded9dd9c73dd3f6a

Source of truth: web/src/attest-pin.ts. These values change with every Tier 3 UKI redeploy; this page tracks the current pin.

Verify via published artifacts

The fast path: download the UKI bytes the operator published, download the OVMF VPSBG provided, run sev-snp-measure, compare the result to the chip's signed value via bpir-admin attest.

  1. Get the OVMF

    VPSBG's custom EDK2 build, used when "Measured Boot" is enabled in the portal. Same binary across all VPSBG SEV-SNP customers; sha-pinned.

    OVMF_SEV_MEASUREDBOOT_4M.fd (4.0 MB)

    Verify: sha256sum OVMF_SEV_MEASUREDBOOT_4M.fde4ac90be71f3b455922ebc7106c5630536bf67027de585e34319b0a42fcd716e

  2. Get the UKI

    The operator-built unified kernel image — kernel + initramfs (with unified_server baked in) + cmdline, packaged as a single PE/EFI file.

    bpir-tier3-v11.efi (287 MB, GitHub release)

    Verify: sha256sum bpir-tier3-v11.efibd243f817d463114dea187630fa8b0911ccd99cb7b37d39177b9f22e27cc7330

    Or rebuild from source — see the recipe. scripts/build_unified_server.sh + sudo KERNEL=/boot/vmlinuz-7.0.0-15-generic scripts/build_uki_tier3.sh from a clone at the canonical path /home/pir/BitcoinPIR. Requires kernel 7.0.0-15, kmod 34.2, dracut 110 (backported from Ubuntu 25.04 plucky).

  3. Predict the MEASUREMENT

    Install sev-snp-measure (pipx install sev-snp-measure), then:

    sev-snp-measure \
    	    --mode snp \
    	    --vcpus 2 \
    	    --vcpu-sig 0x00B10F10 \
    	    --ovmf OVMF_SEV_MEASUREDBOOT_4M.fd \
    	    --kernel bpir-tier3-v11.efi \
    	    --guest-features 0x1

    Output should be the same hex as the MEASUREMENT in the pinned-values table above. The launch parameters (vcpus=2, vcpu-sig=0x00B10F10 for AMD Turin, guest-features=0x1) come from VPSBG's confirmed Proxmox QEMU command line.

  4. Verify against the live chip

    Build bpir-admin (in this repo) and ask pir2 for a fresh attestation report. The chip's signed Launch MEASUREMENT field should equal what you computed in step 3:

    cargo build --release --bin bpir-admin -p bpir-admin
    	./target/release/bpir-admin attest wss://pir2.chenweikeng.com \
    	    --expect-measurement 0662adca3ef25ead88ae763684b6a7261e6d71e75e0a197f26c2439a3b6511c86019968bbd4a44c049ea8e6eb636c346 \
    	    --expect-binary      f9daecb103104c58c40440738557785febdfe2c9724de5b3506bca22a5265c9c

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

pir1 verification (Hetzner, no SEV)

pir1.chenweikeng.com runs the same unified_server binary as pir2, on a Hetzner i7-8700 (Intel, no SEV-SNP). Without a hardware root of trust, the client verifies the server's self-reported binary_sha256 against a pinned value. This detects accidental drift between what the operator claims is deployed and what's actually running.

The binary pin is in web/src/attest-pin.ts::PIR1_PIN:

binary sha256 f9daecb103104c58c40440738557785febdfe2c9724de5b3506bca22a5265c9c

Verify with:

cargo build --release --bin bpir-admin -p bpir-admin
	./target/release/bpir-admin attest wss://pir1.chenweikeng.com \
	    --expect-binary f9daecb103104c58c40440738557785febdfe2c9724de5b3506bca22a5265c9c

Or directly: sha256sum /home/pir/BitcoinPIR/target/release/unified_server on the Hetzner host should return the same hash.

What this proves

Out of scope