Circuit Architecture
All circuits follow a common pattern:Batch Append Circuit
Appends new leaves to state Merkle trees, used for processing output queues.Circuit Structure
Circuit Logic
Hash Public Inputs
Compute
PublicInputHash = Poseidon(OldRoot, NewRoot, LeavesHashchainHash, StartIndex)Process Each Leaf
For each leaf in the batch:
- If
OldLeaves[i] == 0: Insert new leaf - If
OldLeaves[i] != 0: Keep old leaf (already nullified)
Input Format
Old Leaves Semantics: The
oldLeaves array indicates whether a leaf slot is empty (0) or contains a nullifier. This handles the case where leaves are nullified before being appended.Batch Update Circuit
Nullifies existing leaves in state Merkle trees by computing nullifier hashes.Circuit Structure
Circuit Logic
Verify Nullifier Hash
Confirm
LeavesHashchainHash = Poseidon(Nullifier[0], Nullifier[1], ..., Nullifier[n])Input Format
Batch Address Append Circuit
Appends new addresses to indexed Merkle trees for address uniqueness.Circuit Structure
Similar to batch append but operates on indexed Merkle trees with low-value and high-value tracking.Input Format
Public Input Hash Calculation
The public input hash combines all public circuit inputs using Poseidon hash:Hash Chain Algorithm
Example: Batch Append
Example: Batch Update
The public input hash is the single public input that the on-chain verifier checks. All other circuit parameters are private witness data.
Circuit Parameters
Supported Configurations
| Circuit Type | Tree Heights | Batch Sizes | Use Case |
|---|---|---|---|
| Batch Append | 26, 32 | 10, 100, 500 | State tree append |
| Batch Update | 26, 32 | 10, 100, 500 | State tree nullify |
| Address Append | 26, 32 | 10, 100, 500 | Address tree append |
| Inclusion | 26 | 1-8 accounts | Merkle proofs |
| Non-Inclusion | 26 | 1-8 accounts | Address proofs |
Circuit Naming Convention
Proving key files follow this naming pattern:batch_update_26_100.key- Update circuit, height 26, batch size 100batch_append_32_500.key- Append circuit, height 32, batch size 500batch_address_append_26_100.key- Address append, height 26, batch 100
Test Circuits
Smaller test circuits for development:batch_update_26_10.key- Small update batchesbatch_append_26_10.key- Small append batchesbatch_address_append_26_10.key- Small address batches
Constraint System
Complexity
| Circuit | Batch Size | Constraints | Proof Size |
|---|---|---|---|
| Batch Append 26 | 100 | ~2.8M | 128 bytes |
| Batch Append 26 | 500 | ~14M | 128 bytes |
| Batch Update 26 | 100 | ~2.8M | 128 bytes |
| Batch Update 26 | 500 | ~14M | 128 bytes |
| Address Append 26 | 100 | ~3.2M | 128 bytes |
All Groth16 proofs are 128 bytes (2 G1 points + 1 G2 point) regardless of circuit complexity. This makes on-chain verification extremely efficient.
Verification Cost
On-chain verification costs (Solana compute units):- Proof Verification: ~30,000 CU per proof
- Public Input Validation: ~5,000 CU
- Total per Proof: ~35,000 CU
Poseidon Hash Function
Light Protocol uses the Poseidon hash function optimized for zero-knowledge circuits.Parameters
- Field: BN254 scalar field
- Width: 3 (for most operations)
- Full Rounds: 8
- Partial Rounds: 57
- Optimization: Circuit-friendly (low R1CS constraints)
Usage in Circuits
Circuit Setup
Circuit setup is performed once during trusted setup:Manual Setup Commands
Proof Compression
Proofs are compressed before transmission:G1/G2 Point Encoding
Compression Process
Best Practices
Input Validation
Always validate circuit inputs before proof generation:
- Merkle proof length matches tree height
- All BigInt values are within field bounds
- Array lengths match batch size
Error Handling
Handle constraint errors gracefully:
- Invalid Merkle proofs
- Incorrect root transitions
- Public input hash mismatches
Performance
Optimize proof generation:
- Batch multiple operations together
- Use appropriate batch sizes
- Preload proving keys at startup
Testing
Test circuits thoroughly:
- Use test circuits (batch size 10)
- Verify edge cases (empty slots, max batch)
- Check constraint satisfaction
Next Steps
Server Configuration
Learn how to configure and run the prover server
Forester Integration
See how circuits are used in the Forester service