You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
retain every parent node produced while validating an Orchard Merkle path
reuse those nodes as untrusted output hints during Sinsemilla witness preparation
avoid recomputing the path root and avoid the affine conversion between consecutive layers
The hinted parents remain fully constrained by the existing Sinsemilla circuit. A negative test mutates a retained parent and confirms that witness synthesis or constraint verification fails.
Performance
Measurements against current main (bc708765), using Rust 1.97.1 and the
ignored benchmark_witness_assignment benchmark with 50 warmups and 1,000
samples:
Host
Actions
Baseline
This PR
Change
Apple M4, 10 workers
1
648.291 us
651.446 us
+0.49%
Apple M4, 10 workers
2
740.434 us
742.133 us
+0.23%
Apple M4, 10 workers
6
1.32207 ms
1.30698 ms
-1.14%
x86_64 Linux, 8 workers
1
1.36306 ms
1.37510 ms
+0.88%
x86_64 Linux, 8 workers
2
1.44261 ms
1.44633 ms
+0.26%
x86_64 Linux, 8 workers
6
2.42409 ms
2.31554 ms
-4.48%
The small-action changes are within cross-run noise; the useful end-to-end
gain appears when several Merkle preparations contend for the worker pool.
Each table entry is the mean of an interleaved ABBA run; the six-action rows
combine two ABBA runs per host.
The new generic prepare_merkle_path_witness_with_output_hints API deterministically rejects Orchard-domain paths with 33 or more layers, even when all additions are otherwise non-exceptional. merkle_message_words encodes the layer index as the first 10-bit Sinsemilla word, so layer 32 produces word value 32. Because Orchard's Merkle generator enables a first-word witness cache containing only indices 0..31, prepare_hash_witness_inner returns None on that layer instead of falling back to the ordinary projective computation. This violates the new API's documented rejection conditions, which mention only identity q and exceptional incomplete additions.
The PCZT updater installs the bundle anchor and each spend witness independently, but Bundle::create_proof never checks that a nonzero spend's witness derives the installed anchor before starting proof generation. The prover reconstructs SpendInfo, which now computes and retains the path's parent nodes, yet it does not call the existing has_matching_anchor comparison and instead supplies the bundle anchor separately through the public Instance. The circuit still enforces v_old * (root - anchor) = 0, so this does not permit forged membership, but Halo2 proof creation can complete for an unsatisfied witness and return Ok with an unusable proof. Existing test behavior confirms that an unsatisfied PCZT circuit may pass create_proof and only fail subsequent verification.
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
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.
Summary
The hinted parents remain fully constrained by the existing Sinsemilla circuit. A negative test mutates a retained parent and confirms that witness synthesis or constraint verification fails.
Performance
Measurements against current
main(bc708765), using Rust 1.97.1 and theignored
benchmark_witness_assignmentbenchmark with 50 warmups and 1,000samples:
The small-action changes are within cross-run noise; the useful end-to-end
gain appears when several Merkle preparations contend for the worker pool.
Each table entry is the mean of an interleaved ABBA run; the six-action rows
combine two ABBA runs per host.
Testing
cargo fmt --all -- --checkgit diff --checkcargo check -p zakura-orchard --no-default-featurescargo check -p zakura-orchard --all-featurescargo test -p zakura-halo2-gadgets sinsemilla::merkle::tests --libcargo test -p zakura-orchard --libcargo test -p zakura-orchard --test builder