Repository navigation
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
The zero-knowledge circuit and verifier-data changes require expert validation and coordinated deployment with downstream verifiers.
1 open finding
What changed in this PR
Enforces distinct transaction inputs by constraining their Merkle-tree positions pairwise.
Changes:
- Adds inverse-based uniqueness constraints and regression tests for 2–4 inputs.
- Regenerates affected verifier data while preserving the 1-input circuit.
- Updates public documentation and changelog.
| File | Description |
|---|---|
circuits/src/circuit_impl.rs |
Implements position uniqueness constraints. |
circuits/src/lib.rs |
Documents the new input invariant. |
circuits/tests/distinct_inputs.rs |
Tests rejection of duplicate inputs. |
circuits/tests/verifier_data.rs |
References regenerated verifier data. |
circuits/README.md |
Documents input uniqueness. |
circuits/CHANGELOG.md |
Records the behavior change. |
circuits/tests/assets/4e5a…e6b.vd |
Removes superseded 2-input verifier data. |
circuits/tests/assets/3331…997.vd |
Removes superseded 3-input verifier data. |
circuits/tests/assets/a7ff…902.vd |
Removes superseded 4-input verifier data. |
circuits/tests/assets/bc91…a47.vd |
Adds regenerated 2-input verifier data. |
circuits/tests/assets/b19b…df9.vd |
Adds regenerated 3-input verifier data. |
circuits/tests/assets/d3a6…e23.vd |
Adds regenerated 4-input verifier data. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
e2d9c7a to
fb6a2d5
Compare
|
Force-pushed: rebased on #322 with the verifier-data assets and gate counts updated, and the comment Copilot flagged reworded. |
fb6a2d5 to
875f374
Compare
|
Force-pushed: rebased on the amended #322, with the verifier data regenerated. |
moCello
left a comment
There was a problem hiding this comment.
APPROVE — The inverse-witness constraint is sound for every pair, it binds the same position witness that the note hash and the nullifier use, and the regression test isolates it. Each copied input keeps a valid opening, signature and nullifier, and every test note holds the same value, so only the new constraint can reject the duplicate.
`TxCircuit` checks each input on its own, so nothing in the circuit required the inputs to be different notes. The transfer contract rejects repeated nullifiers. Constrain the input positions to be pairwise distinct. For every pair, the prover supplies the inverse of the difference of the two positions, and `(pos_i - pos_j)·inv = 1` holds only when they differ. The note hash and the nullifier of each input are both computed from its position witness, and the Merkle opening proves the note hash to be in the tree. The check takes two gates per pair, 0, 2, 6 and 12 for 1 to 4 inputs, and leaves the public inputs unchanged. The regression proves the honest transaction, then the same transaction with each input repeated in every later slot, which must be unsatisfiable. Without the constraint, the regression fails. The 2- to 4-input circuits change with these gates, and with them their verifier data, so the test assets are regenerated. The 1-input circuit has no pair of inputs and keeps its verifier data.
875f374 to
92393f0
Compare

Stacked on #322.
The transaction circuit now requires the tree positions of its inputs to be pairwise distinct. The check takes two gates per pair (0, 2, 6 and 12 for 1 to 4 inputs) and leaves the public inputs unchanged.
The 2- to 4-input circuits change, so their verifier-data test assets are updated. These are the final ones of the stack. The 1-input circuit and its verifier data are unchanged.
Resolves #315