Repository navigation
feat(unpacker): add Merkle commitment unpacker circuit - #612
ilyalesokhin-starkware wants to merge 1 commit into
Conversation
PR SummaryMedium Risk Overview
Tests cover valid/invalid commitments (wrong root, shape, tampered leaves, slack capacity, caterpillars, duplicates) and assert the emitted circuit is identical across leaf count Reviewed by Cursor Bugbot for commit 888b225. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Add the tree and unpacker modules to the circuits-unpacker crate: a
generic BinaryTree<T> { Leaf, Node } describing an arbitrary, possibly
unbalanced full binary tree, and verify_merkle_commitment, proving a
Merkle root commits to an entire ordered leaf set via a fixed,
depth-independent topology (wiring-by-multiset).
The tree shape lives entirely in the witness: the gate structure is a
fixed L leaf slots + (L-1) node slots, with cost O(L) regardless of n or
depth. Each node resolves its output with a copy-up rule
(out = is_zero(right) ? left : hash_node(left, right)), and a single
strict multiset identity (permute_hash_values) ties every produced hash
to its single consumption.
To make the emitted circuit — gates and variable wiring — byte-identical
for every tree of a given capacity, verify_merkle_commitment is the sole
allocator: it takes leaves as concrete HashValue<QM31> and guesses every
value internally, including the padding zeros (guessed, not the canonical
zero constant, so nothing constant-folds away). It returns a
VerifiedMerkleTree { root, leaves }, holding the resolved root out of the
multiset so the caller binds it to the claimed commitment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cf5f244 to
888b225
Compare
f587251 to
1f44a92
Compare

Add the tree and unpacker modules to the circuits-unpacker crate: a
generic BinaryTree { Leaf, Node } describing an arbitrary, possibly
unbalanced full binary tree, and verify_merkle_commitment, proving a
Merkle root commits to an entire ordered leaf set via a fixed,
depth-independent topology (wiring-by-multiset).
The tree shape lives entirely in the witness: the gate structure is a
fixed L leaf slots + (L-1) node slots, with cost O(L) regardless of n or
depth. Each node resolves its output with a copy-up rule
(out = is_zero(right) ? left : hash_node(left, right)), and a single
strict multiset identity (permute_hash_values) ties every produced hash
to its single consumption.
To make the emitted circuit — gates and variable wiring — byte-identical
for every tree of a given capacity, verify_merkle_commitment is the sole
allocator: it takes leaves as concrete HashValue and guesses every
value internally, including the padding zeros (guessed, not the canonical
zero constant, so nothing constant-folds away). It returns a
VerifiedMerkleTree { root, leaves }, holding the resolved root out of the
multiset so the caller binds it to the claimed commitment.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com