Debug a failing witness
When a proof won't generate, the culprit is almost always the witness — a value out of range, a
broken relation, a wrong commitment. zerostyl-debug runs the MockProver and surfaces exactly which
constraint failed and where, far more readably than bare halo2. This tutorial walks a real failure
end to end.
You'll use: zerostyl-debug, zerostyl-prove. Time: ~10 minutes.
1. See what the circuit expects
zerostyl-prove info state_mask
Circuit: state_mask v1.0.0
Privacy-preserving state proof: Poseidon commitment + bounded range + balance comparison.
Default k: 10
Public inputs: 2
Private witnesses: 5
Witness fields:
- [private] state_value : u64 Secret value committed via Poseidon hash.
- [private] nonce : fp Commitment randomness (Poseidon input)
- [private] collateral_ratio : u64 Must lie in [150, 300].
- [private] hidden_balance : u64 Must be strictly greater than `threshold`.
- [public ] threshold : u64 Public minimum balance.
Witness template (copy, fill, save as <circuit>.json):
{
"collateral_ratio": "0",
"hidden_balance": "0",
"nonce": "0",
"state_value": "0",
"threshold": "0"
}
The constraints are stated inline: collateral_ratio ∈ [150, 300] and hidden_balance > threshold.
2. Inspect the circuit structure (optional)
zerostyl-debug inspect --circuit state_mask
Circuit: state_mask
k: 10 (2^k = 1024 rows)
Columns: 20 total
advice: 11
instance: 1
fixed: 8
Selectors: 16
Max degree: 6
3. Run a valid witness
{ "state_value": "42", "nonce": "7", "collateral_ratio": "200", "hidden_balance": "5000", "threshold": "1000" }
zerostyl-debug debug --circuit state_mask --witnesses good.json
=== Debug Report: state_mask ===
Circuit: state_mask k=10
Result: ALL CONSTRAINTS SATISFIED
4. Break it and read the diagnostics
Now set collateral_ratio to 999 — outside the required [150, 300]:
{ "state_value": "42", "nonce": "7", "collateral_ratio": "999", "hidden_balance": "5000", "threshold": "1000" }
zerostyl-debug debug --circuit state_mask --witnesses bad.json
=== Debug Report: state_mask ===
Circuit: state_mask k=10
Result: 2 FAILURE(S)
--- Failure 1 [permutation] ---
Region: in Region 17 ('range check 16 bits') at offset 16
Column: Column('Advice', 4)
Details: Equality constraint not satisfied by cell (..., in Region 17 ('range check 16 bits') at offset 16)
--- Failure 2 [permutation] ---
Region: in Region 17 ('range check 16 bits') at offset 16
Column: Column('Advice', 5)
Details: Equality constraint not satisfied by cell (..., in Region 17 ('range check 16 bits') at offset 16)
The failing region — range check 16 bits — names the problem: the bounded range proof on
collateral_ratio cannot decompose 999 into the expected range, so its recomposition equality
fails. The fix is to bring the value back into [150, 300].
5. Fix and confirm
Set collateral_ratio back to 200 and re-run:
zerostyl-debug debug --circuit state_mask --witnesses good.json
# → Result: ALL CONSTRAINTS SATISFIED
Now zerostyl-prove generate will succeed — see Prove & verify with the Rust SDK.
zerostyl-debug debug (and the SDK's mock_prove) run the constraint system without generating
a real proof or any keygen, so they return in milliseconds. Always debug the witness here before
paying for a full proof.
Related commands
zerostyl-debug schema --circuit <name>— the witness schema plus a copy-pastable template.zerostyl-debug witness --circuit <name> --witnesses w.json— pretty-print a witness against the schema.