Unit 8: the commitment scheme, spec and record - #67
Merged
Conversation
Phase 3 unit 8. The architecture document goes from stub to normative: the leaf version (0xd0, provisional until deployment), what a leaf commits to (the program's tree hash as a 32-byte leaf script, the serialized program a witness element the validator checks against it), the tree (any BIP341 arrangement, one leaf revealed, the execution identity triple read from the control block as base consensus reads it), the digest domains (tree hashes and tagged hashes disjoint by first byte, every tag in use tabulated), the witness (exactly four elements, no annex, strict at the element boundary and the program's to check inside the solution), the budget (derived from the input's own witness weight, the function left to COSTS.md section 9), and the six-stage pipeline with every failure mode named. Two errors are new: bad_witness for the shape rules and leaf_mismatch for a program whose tree hash is not the leaf script. The rest of the pipeline is the existing VM, condition, and validation documents, cited by section. The tree-hash commitment follows Chia's puzzle-hash identity model, corroborated by CHIP-0049. The leaf version pool is BIP341's own footnote, and the byte was chosen clear of the known claims (tapscript 0xc0, bll's floated 0xc2, Elements' 0xc4 and 0xbe). Rationale and the measurements behind the design are in the commitment record, landing in the next commit.
The rationale behind spec/SPEC.md, the counterpart of the VM and condition records: reference provenance (BIP341's leaf-version footnote, the vendored BIP341 vectors as the tagged-hash oracle, the known leaf-version claims, Chia's puzzle hashes and CHIP-0049), the vault measurements the design rests on (2,562 curried bytes whole, 1,066 to 1,508 per path, 499 for the curry library, 440 for a follower that asserts a solution-supplied root), and eleven decisions: the leaf byte, tree-hash commitment, stated domain separation, four elements and no annex, surplus tolerated inside the solution element only, the derived budget, per-path leaves as BIP341's own, guess-and-assert for self identity with reconstruction for successors, libraries revealed per spend, the singleton's workaround standing, and the whole document written. Three glossary rows (leaf version, leaf script, per-path leaf), the README entry, and the ground rule 1 pointer to the record.
Objection register: O14 answered (surplus solution data, decision 5), O17 answered with its vector owed to the witness layer (decision 3), O21 answered for the budget's shape with the mapping still Phase 4 (decision 6), and the owed list updated to match. VM record: entry 9 closed by decision 5, the D9 addendum's owed statement marked written. The vault and singleton identity paragraphs say what the stand-in now stands in for and when the sources move, and the currying doc names the commitment its tree hash builds.
From an independent hostile read against BIP341 and BIP342. The annex rule names the witness it examines, the serialized one before base consensus strips an annex, with BIP341's two-element condition. The control block's checks move out of the ordered rule list, since they precede it. Element position 1 is defined as the first element of the serialized witness. The m = 0 case is stated, which is what makes ASSERT_MY_TAPTREE's never-empty root true. The digest-domain section leads with the structural fact, a tree hash is never a merkle node, scopes its table to every tag a BitLisp validator hashes under, and gains BIP340's challenge tag. The budget section is marked PROVISIONAL until COSTS.md section 9 exists, vectors stating their budget until then. Section 3.3 names the two programs the rules single out, the atom 1 as the anyone-can-spend leaf and nil as unspendable by script path. The stage cross-reference to VALIDATION.md is corrected.
The tapscript analogy in decision 5 and objection O14 is corrected: tapscript's boundary is strict and a dropped element is an opt-in the author writes, where CLVM's tolerance of a solution tail is the default, so the standard-layer shape check is the opt-in. Decision 4's annex rationale becomes the readability asymmetry, a program can commit to any solution byte and nothing can commit to an annex, and records the 520-byte and 1,000-element tapscript bounds the scheme drops. Decision 6 and O21 cite BIP342's sigops budget as the deployed precedent for a witness-derived budget and name the two parameters COSTS.md section 9 must fix. Decision 7 records program-level Merkleization as the alternative and why taproot-level leaves won. Decision 2 counts the saved bytes as 33 and states serialization as a cost, not an impossibility. Decision 3 matches the spec's rescoped table. Provenance pins the Elements commit and says plainly that the bll leaf-version float is our synthesis's reading, unpinned. The owed vectors gain the two named programs.
A soft fork only tightens, so an annex use for BitLisp inputs later needs a new leaf version, where tapscript's commit-and-reserve idiom keeps it under one. Decision 4 states the trade and why rejection was still taken.
Two review decisions (decision by Evan, 2026-09-06). The annex is no longer rejected: it is set aside as BIP341 defines it and admitted exactly when the input's condition list carries ASSERT_MY_ANNEX (0x39, one 32-byte operand, generic cost) over the BIP341 sha_annex digest of it, an annex without the assert being unasserted_annex and the assert without a matching annex being unsatisfied_annex_assert. The transaction view's BitLisp input gains an optional annexHash the self assert family reads and no specifier does. Keyless paths stay protected by default, a program that wants an annex commits to it, and the upgrade door stays open under this leaf version, where outright rejection would have needed a new one. The solution, the program, and the annex are each bounded at MAX_WITNESS_ELEMENT_SIZE = 10,000 bytes, Bitcoin's legacy script cap and the condition layer's existing scriptPubKey operand bound, else bad_witness. The stage table and the digest-domain paragraph name the annex hash beside the txid and outputs hash. The gap vector pinning 0x39 invalid stays as the implementation has it and flips with the reference witness layer.
Condition record: decision 30 with the three annex shapes weighed (reject, bind into signature digests, admit under a self assert) and divergence row C25. Commitment record: decision 4 rewritten to the revised outcome with the plan's rejection and its priced upgrade cost kept as history, decision 5 gains the compiler default for solution shape checks and the note that a seal reads no witness byte, decision 12 records the 10,000-byte bound and the singleton lineage-proof limit it creates, and the owed vectors gain both. Glossary rows for the assert and the annex, a comparison row, the singleton doc's bound paragraph, and the O14 row naming the compiler default.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 unit 8, the first of its two PRs:
spec/SPEC.mdwritten as a normative design with the vault as the workload, plus the record behind it. Spec only, no code: the reference witness layer, its vectors, and the commitment-hash utility follow in the second PR, and unit 9 re-pins the vault under the scheme and measures every path.What changed
spec/SPEC.mdgoes from stub to normative in four sections: overview, leaf version and commitment, witness structure, validation pipeline.docs/commitment-record.mdis new: provenance, the measurements, eleven decisions, and what stays with Phase 4.The decisions, one line each
0xd0, provisional until deployment.0xc2was the plan's pick until Evan asked whether Liquid or bll had it: bll's author floated0xc2, Elements uses0xc4and0xbe.0x01or0x02, every tag digest in use begins with something else. The vector is owed to the witness layer.Review order
4f64700spec. Readspec/SPEC.mdtop to bottom. Check it against BIP341 for the fold and the tweak check, and againstspec/VALIDATION.md's transaction view for the identity triple.259f78brecord. Decisions 1, 5, 6, and 8 are the ones with real other sides.f09c259pointers. Confirm each closed objection row cites the section that closes it.Verify
Lint clean, 861 tests green locally. The measurements in the record's section 2 reproduce from
puzzles/vault/vault.blby keeping one dispatch arm and compiling withbitlisp-compile -I puzzles/lib -I puzzles/vault.After merge
The execution plan bullet for unit 8 wants its one-line decisions and the library exception, direct to main.
Review round
An independent hostile read against BIP341 and BIP342 found 14 points, folded in as
7ad9e12(spec) andb876acd(record). The BIP341 restatements and the digest-table bytes checked out. The fixes: the annex rule names the pre-strip witness, the m = 0 case is stated, the digest domains lead with the structural fact and add BIP340's challenge tag, the budget is marked PROVISIONAL, the atom1and nil programs are named, the tapscript analogy for surplus data is corrected (its tolerance is opt-in, CLVM's is the default), the annex rationale becomes the readability asymmetry, BIP342's sigops budget is cited as the precedent for a witness-derived budget, and program-level Merkleization is recorded as the declined alternative to per-path leaves. Read the two fold-in commits last.Review decisions, second round
Three calls by Evan at review, landed as the last two commits (spec, then docs):
sha_annexdigest, so keyless paths stay protected by default and the upgrade door stays open under this leaf version. Condition-record decision 30 weighs the three shapes, divergence row C25. The existing gap vector pinning 0x39 invalid still passes against the unchanged implementation and flips in the witness-layer PR.Owed to the witness-layer PR: the annex rule vectors in both directions, the bound at and above 10,000 bytes, and the 0x39 implementation.