Hazync v0.6.0 — round-8 audit: anchor-bound chain proofs + gated witness commitment
Round-8 soundness audit — a five-reviewer completeness + verifier pass over the guest, the C++ VerifyScript boundary, the Utreexo accumulator, enforcement gating, and the end-to-end trust scope. Four dimensions came back sound; one verifier-hole and five completeness deviations were found and fixed (bar the one rule that is mathematically unprovable in a zkVM). Full write-up: AUDIT_2026-07.md.
The guest changed, so METHOD_ID is re-pinned c029cee4… → 601d7ca298f32c54137fdb395d0debd31e95e4f084615fa710e5db5c785f05e6. Proofs made against the old id no longer verify and are being re-proven from genesis. The reproducible-build mechanism is unchanged (pinned toolchain, Bitcoin Core v28.0, secp256k1 v0.5.1, Cargo.lock, reproduce/Dockerfile) — the id is simply a new value. NB: the guest ELF embeds assert!/panic! line numbers, so its exact (compact) formatting is load-bearing for the id — do not cargo fmt the guest.
What changed
- Anchor-bound chain proofs (S5) +
verify-chain.ChainStatenow commitsanchor_id(the double-SHA256 of the base anchor), set in the base step and carried forward, and the newverify-chaincommand pins it to the genesis anchor. A bare mode-2/5 chain receipt is now self-authenticating — a receipt built on a fabricated anchor is rejected — closing a verifier-side foot-gun (RangeStatealready had this via its genesis in-boundary pin). - Witness-commitment activation gate (G3) +
unexpected-witnessincl. coinbase (G2). The BIP141 commitment is now enforced only from segwit height 481824, matching Core; below activation any witness data is rejected. This removes a reject-valid stall on canonical pre-activation blocks (433k–481823). - Block-level
MoneyRange(nFees)(G5). Explicit fee-total range check plus an i128-safecoinbase ≤ subsidy + feesbound. - BIP30 as a documented, gated, bounded invariant (G1). A Utreexo Stump cannot prove non-membership, so Core's general
HaveCoinlookup is replaced by an in-code structural argument (BIP34 uniqueness ≥227931 + the two grandfathered overwrites), sound to ~height 1,983,702. - Hardening (N1/N2/N3). Removed the dead host-supplied
BlockInput.flags(flags are guest-derived); length-prefixed thescriptPubKeyin the UTXO-leaf commitment;tx_full_sigopsnow fails closed on a short prevouts blob.
Per-file breakdown
prover/methods/guest/src/main.rs—ChainState.anchor_id+ carry logic inchain_step/aggregate; witness-commitment activation gate + coinbase-inclusivehas_witness; block-levelMoneyRange; BIP30 bounded-invariant documentation; removed deadBlockInput.flags.prover/methods/guest/verify_input.cpp— length-prefixedscriptPubKeyincoin_leafandtx_out_leaves(N2, changes every leaf hash);tx_full_sigopsreturns a poison cost on a short prevouts blob (N3).prover/host/src/main.rs—verify-chaincommand;ChainState.anchor_idmirror + all anchor constructors; hostcoin_leaflength-prefix (kept byte-identical to the guest); removedBlockInput.flags/Spend.flags.reproduce/METHOD_ID— re-pinned to601d7ca2…with a note not tocargo fmtthe guest.AUDIT_2026-07.md(new),SECURITY.md(round-8 section + status table),docs/SOUNDNESS.md(§3c + completeness matrix),docs/PROVING.md(verify-chain),README.md— audit record and docs.
Verification
Verified on a 2×L40S box against real mainnet data: regress, the adversarial soundness suite (all holes reject), check-bip30, check-full 741000 (byte-exact tip f0e89160…), and a genesis-anchored range proof — all green on this guest.
Assets
hazync-host-x86_64-linux-gnu— CPU host (verify + prove on CPU).hazync-host-x86_64-linux-gnu-cuda— CUDA host (GPU proving).
Both are the 601d7ca2… guest. SHA256SUMS.txt is PGP-signed (maintainer key 852C2B3190F5B928); verify per SECURITY.md.