feat(MerkleTree): add batch openings with completeness and uniqueness for inductive Merkle trees#473
Conversation
🤖 PR Summary
#1 MerkleTree: batch openings (completeness + uniqueness)Adds batch (multi-leaf) opening support to the inductive Merkle tree construction and proves completeness and uniqueness. A batch opening authenticates several leaves against a single root with a single, deduplicated proof. This is the missing piece for the vector-commitment operation used in IOP query phases (FRI / STIR / WHIR) and the BCS transform; it addresses the next open checkbox of Verified-zkEVM/ArkLib#4. New modules (under
Existing files modified:
New test file:
Scope honesty: Completeness and deterministic uniqueness are proved; batch extractability (ROM game) is not attempted in this PR. No Statistics
Lean Declarations ✏️ Added: 60 declaration(s)
Lean Quality Signals
📋 **Additional Analysis**The diff passes all style, documentation, and workflow checks. No violations or blocking issues. 📄 **Per-File Summaries**
Last updated: 2026-07-15 12:19 UTC. |
4f87597 to
c5c23d2
Compare
|
Fixed the file headers to follow this repo's CONTRIBUTING convention (copyright holder = credited author/organization rather than the ArkLib-style collective holder I had copied over): holder is now The Institute for Ontological Mathematics / Equation Capital dba Apoth3osis, author Abraxas1010. |
c5c23d2 to
126ac62
Compare
|
Pushed a second commit delivering the extractability direction promised in the PR body:
Contributed by The Institute for Ontological Mathematics (IAOM) / Equation Capital dba Apoth3osis. |
|
Thanks for the submission, I'll leave a review with more comments. Looks like this is failing CI due to an extra import in VCVio.lean. I think if all the file names will start with |
BoltonBailey
left a comment
There was a problem hiding this comment.
Thanks, seems like an overall good contribution.
|
|
||
| /-- A batch proof exists only for selectors that select at least one leaf: the `BatchProof` | ||
| family is uninhabited on selectors with `anySelected = false`. -/ | ||
| theorem BatchProof.anySelected_of_batchProof {s : Skeleton} {sel : LeafData Bool s} |
There was a problem hiding this comment.
Seems this isn't used in this file, could it be moved to Uniqueness?
There was a problem hiding this comment.
Done — moved to its only consumer, now Inductive/Batch/Uniqueness.lean (post folder-move).
|
|
||
| /-- Does a selector select any leaf of the tree? -/ | ||
| @[simp, grind] | ||
| def _root_.BinaryTree.LeafData.anySelected {s : Skeleton} : LeafData Bool s → Bool |
There was a problem hiding this comment.
if this is _root_ could it be moved to a file where the namespace is appropriate, maybe the file or folder where LeafData is defined?
There was a problem hiding this comment.
Done — LeafData.anySelected now lives in ToMathlib/Data/IndexedBinaryTree/Basic.lean next to LeafData.get, without the _root_ prefix.
|
|
||
| /-- A selector selects some leaf as soon as it selects a particular one: `get idx = true` | ||
| implies `anySelected = true`. -/ | ||
| theorem _root_.BinaryTree.LeafData.anySelected_of_get {s : Skeleton} {sel : LeafData Bool s} |
There was a problem hiding this comment.
could this theorem be moved to the file where anySelected is defined, wherever that ends up being?
There was a problem hiding this comment.
Done — anySelected_of_get moved to ToMathlib/Data/IndexedBinaryTree/Basic.lean, directly after the anySelected definition.
|
Thanks for the review! All three suggestions made sense — done in the latest push:
While rebuilding I also noticed the branch had accidentally picked up an |
|
Thanks for this contribution. I did a deeper semantic pass and the core claims look sound and appropriately scoped: the pruned I agree with Bolton's folder suggestion: please use That will scale better when game-level batch extractability and any later batch-specific query-bound files arrive. A few final integration points before landing:
Subject to the folder move, current-main CI, and Bolton's re-review, I think this should land. |
… for inductive Merkle trees
…h cross-selector batch binding
…files per review - LeafData.anySelected and LeafData.anySelected_of_get move to ToMathlib/Data/IndexedBinaryTree/Basic.lean, where LeafData is defined (dropping the _root_ prefixes). - BatchProof.anySelected_of_batchProof moves from BatchCompleteness to BatchUniqueness, its only consumer; BatchUniqueness now imports only BatchDefs. - Drop a stray 'import ...MerkleTree.Tweaked.Basic' from VCVio.lean that leaked in from a sibling branch and broke the root build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pen scope wording per review
- Batch{Defs,Completeness,ToSingle,Uniqueness}.lean -> Batch/{Defs,
Completeness,ToSingle,Uniqueness}.lean (imports updated)
- Batch/ToSingle.lean: module doc now states it is a deterministic kernel
for a future game-level extractability transfer, not a proof of batch
extractability, and names the remaining game-level obligations
- Batch/Uniqueness.lean: Function.Injective2 framed as a structural sanity
assumption; constructive collision theorems named as the real binding
- Batch/Defs.lean: sparse-selector conversion API tracked as follow-up
- rebased onto current main (post-Verified-zkEVM#477)
a8face6 to
b583055
Compare
|
All review points are now addressed on the updated branch:
@BoltonBailey — could you take a fresh look when you get a chance? Your earlier inline threads should all be resolved on this head. |
BoltonBailey
left a comment
There was a problem hiding this comment.
All of this looks good to me.
I agree with Quang that Injective2 is not ideal, but it's also used in the non-batch version of that file. Perhaps one way that could be turned into something more useful is switching to some kind of "Option Injective2" which treats the function of interest as possibly none-valued to represent non-queried pairs and proves that there is a collision in the queried values. But probably that should not be done in this PR, we could file an issue to address both files in a later PR.
|
Thanks for the re-review! Filed the With that, all three landing conditions from the earlier review are met: folder move done, full CI green on the current- |
|
Maintainer follow-up completed on this branch. What changed:
Validation:
The sparse-selector conversion API, batch query-cost theorem, queried-domain uniqueness refinement, and game-level batch extractability remain appropriate follow-up work rather than blockers for this PR. |
Summary
This PR adds batch openings for the inductive Merkle tree construction — opening several leaves of one tree against a single root with one deduplicated piece of authentication data — together with completeness and (injective-hash) uniqueness theorems. It addresses the next open checkbox of Verified-zkEVM/ArkLib#4 ("Prove completeness of Merkle commitments — Batch-index"), and is the vector-commitment operation used by the query phase of IOP-based systems (FRI/STIR/WHIR) and the BCS transform.
Design
sel : LeafData Bool s(reusing the existing tree vocabulary; no new index machinery).BatchProof α selis an inductive family that mirrors the tree but is pruned at unselected subtrees: a subtree with no selected leaf contributes exactly one hash (its root); a node with selected leaves on both sides contributes none. Malformed proofs are unrepresentable by typing, in the same spirit as the depth-indexedList.VectorofgenerateProof; the family is provably uninhabited on selectors that open nothing (BatchProof.anySelected_of_batchProof).getPutativeBatchRootWithHash) + monadic layer (getPutativeBatchRoot,verifyBatchProof) connected by asimulateQreduction lemma.Main results
#print axiomsfunctional_batch_completeness[propext, Quot.sound]batch_completenessPr[verify = true] = 1under the random oracle (reduces throughsimulateQ, exactly like the single-indexcompleteness)[propext, Classical.choice, Quot.sound]getPutativeBatchRootWithHash_uniqueFunction.Injective2 h, same selector + same putative root ⟹ identical claimed values and identical authentication data (batch analogue ofUniqueness.lean)[propext]Scope honesty
This PR proves completeness and deterministic uniqueness only. Batch extractability (the ROM game, next checkbox of ArkLib#4) is deliberately not attempted here — happy to discuss whether the
Extractability.leanmachinery should be generalized to batch selectors as a follow-up, and to work on it.Validation performed (not in the diff)
lake build VCViogreen at24fe01d(this branch's base).2a+3b+1): batch root equals tree root on a depth-2 tree opening leaves {0,3}; single-leaf batch agrees with the single-indexgetPutativeRootWithHash; all-leaves batch proof is hash-free by construction; nothing-selected selector is uninhabited.simulateQlemma still holds) makesfunctional_batch_completenessfail to compile — the completeness theorem is genuinely sensitive to tree order.Naming and style are happy to move wherever the maintainers prefer.
Contributed by The Institute for Ontological Mathematics (IAOM) / Equation Capital dba Apoth3osis.