Skip to content

Validate Taproot primitives against pinned Bitcoin Core - #1

Open
adrienlacombe wants to merge 5 commits into
solving-bitcoin:mainfrom
adrienlacombe:codex/core-validation-harness
Open

Validate Taproot primitives against pinned Bitcoin Core#1
adrienlacombe wants to merge 5 commits into
solving-bitcoin:mainfrom
adrienlacombe:codex/core-validation-harness

Conversation

@adrienlacombe

@adrienlacombe adrienlacombe commented Sep 10, 2026

Copy link
Copy Markdown

Local fragment success did not establish complete Taproot validity: resource checks were incomplete, some signatures were misclassified or panicked, and PRINCEv2 assumed caller-validated plaintext nibbles. This adds explicit consensus/policy fragment profiles, narrowly tested interpreter repairs, a checked PRINCEv2 computation leaf, and complete funded transactions validated against hash-pinned Bitcoin Core v30.3 (49faec4f87f5cd19c88db01a82e5c68b087c8227).

Three independent experiment harnesses now cover 84 fixtures:

  • 44 resource/policy fixtures: entry and transient stack limits, minimal encoding, mandatory MINIMALIF, OP_SUCCESS ordering and a complete constant-composition Winternitz spend. All 86 applicable local profile/Core comparisons pass. A control-block mutation preserves local leaf acceptance while Core rejects the commitment, keeping the local API boundary explicit.
  • 20 signature fixtures: CODESEPARATOR opcode positions, unknown-key empty signatures, invalid x-only keys and executed/skipped Tapscript multisig. The historical resource-repaired interpreter had 13 disagreements including six panics; the adopted integration has none. Every local verdict and rejection diagnostic matches Core, with 11 consensus accepts and six policy accepts. Baseline and final transaction inputs are identical; two fresh final reports match byte for byte.
  • 20 checked PRINCEv2 fixtures: prince_verify(key, ciphertext) requires exactly 16 canonical nibbles, performs encryption, compares all 16 ciphertext nibbles and leaves one true item. Three independent upstream-C vectors pass consensus and default policy; 17 invalid count/encoding/range/ciphertext cases reject. All 40 local profile/Core comparisons match. Two fresh-node reports are identical; a separate optimized-host reproduction is identical too.

The checked PRINCE leaves measure 6,426 bytes for the zero key and 6,582 for the published key. Complete Taproot witnesses are 6,480 / 6,496 / 6,651 bytes; combined stack peaks are 633 / 633 / 685; transaction weights are 6,858 / 6,874 / 7,029 WU. Every honest invocation has 16 simultaneous entry data items, zero hint items and 18 complete witness items. The whole leaf is compiled once through repository policy for execution, metrics and commitment. Static opcode counts are recorded separately; executed counts remain unavailable because validation has branches. These public-key computation predicates provide no transaction authorization or plaintext secrecy. Deployment evidence applies only to the exact recorded spends.

The original 6,136-byte PRINCE fragment and every historical metric/report remain unchanged. The Winternitz complete fixture remains 1,599 leaf bytes, 2,432 witness bytes and 2,810 WU, with 70 entry data items, zero hints and peak 119. Signature fixtures retain explicit data/full-witness counts and zero hints; two ordinary padding items keep them away from incomplete local full-witness budget framing. Complete local commitment/annex validation and budget initialization remain open. Missing SIGHASH_SINGLE output ordering has local regression coverage and pinned Core source inspection, outside the funded signature corpus.

Fresh Rust reports now derive dependency identities from the binary's embedded Cargo.lock through support::provenance. The utility rejects missing, ambiguous, malformed or non-Git identities. It replaces copied interpreter pins and the signature generator's duplicate parser; an old binary retains its embedded identity after the on-disk lock changes. This identifies resolved Git source, not local edits in a Cargo checkout. Existing fixture JSON is byte-identical after the refactor.

CI now separates formatting/knowledge/Python, non-field Rust, and the three Core experiments. It runs fixture example tests explicitly, preserves --skip fields::, pins action commits, verifies cached Core archives and uploads fresh reports as artifacts. Host dev/test optimization preserves assertions and Script compilation policy. The setup action preserves Cargo warning behavior rather than applying its default -D warnings to existing research warnings.

The immutable Cargo patch uses integration 702544c9 for both the lab and bitcoin-script-stack. It combines resource/index/minimal-push PRs #18, #19, #20, Sander Bosma's existing CODESEPARATOR fix #16 with additional tests, and empty-signature #21 / signature-error #22 repairs. These contributions remain unmerged. Compiler and other dependency pins are unchanged; the independently submitted compiler performance experiment remains separate.

Local validation on macOS ARM64:

  • CARGO_PROFILE_TEST_OPT_LEVEL=1 CARGO_TARGET_DIR=target/nonfield-opt1 cargo test --locked -- --skip fields::: 460 passed, 24 existing ignored, 143 field tests filtered.
  • Six active primitive metric tests pass: five historical baselines unchanged and three new checked-leaf rows with 15 measurements.
  • Three fixture example tests, 30 Python tests, rustfmt, actionlint and whitespace checks pass; knowledge validates 43 records / 132 configurations.
  • All three Core harnesses pass. Original resource/signature reports and C fixtures are preserved; the new PRINCE report is deterministic across fresh nodes and host optimization settings.
  • Integrated interpreter: 57 upstream tests passed at the adopted pin.

Reproduction and scope: knowledge/prince-core-validation.md, knowledge/tapscript-signature-validation.md, knowledge/core-validation.md, src/support/README.md, and the separate raw reports under tests/data/. Remote CI results should be assessed from the PR checks; the validation above was run locally.

GitHub created upstream run 34459059905 for head 396c6f5e9d28c266c41318c93f420062fed33158 with conclusion action_required and no jobs. This account has read-only upstream permissions; remote CI has not executed.

@adrienlacombe adrienlacombe changed the title Validate Taproot execution profiles against pinned Bitcoin Core Validate Taproot execution and signature semantics against pinned Bitcoin Core Sep 10, 2026
@adrienlacombe adrienlacombe changed the title Validate Taproot execution and signature semantics against pinned Bitcoin Core Validate Taproot primitives against pinned Bitcoin Core Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant