Signal Aliasing
Detects redundant equality constraints that create signal aliases without adding security, potentially masking missing constraints.
Signal Aliasing
Overview
Remediation Guide: How to Fix Signal Aliasing
The signal aliasing detector flags equality constraints of the form a === b (or a <== b) where a and b are both plain signal references and neither side is independently bound to a meaningful value. The constraint forces the two signals to share a value, but the shared value remains free.
Aliasing is not a vulnerability on its own. Many circuits legitimately forward an input to an output via out <== in. The detector only fires when the alias is between two signals that are otherwise unconstrained, so the equality cannot inherit a binding from either side.
Why This Is an Issue
Developers sometimes introduce an alias as a form of in-code documentation: claimed_root === computed_root. If computed_root is itself derived from <-- assignments without backing constraints, the equality propagates the lack of constraint to claimed_root rather than fixing it. The reviewer sees a === and concludes the signal is checked, but no field element is excluded by the constraint.
Aliases can also accumulate during refactoring, when intermediate signals are kept around even though their original purpose was removed. The redundant constraint then survives in the circuit, contributing to proving cost without adding soundness.
How to Resolve
Identify which signal in the pair is supposed to carry the binding and add a real constraint to it. Then either keep the alias (if both names are needed for clarity) or delete one signal entirely.
// Vulnerable: alias between two unconstrained signals
template Processor() {
signal input data;
signal temp;
signal output result;
temp <-- transform(data); // unconstrained witness
result === temp; // alias does not add a constraint
}
// Fixed: temp is constrained, alias inherits the binding
template Processor() {
signal input data;
signal temp;
signal output result;
component t = Transform();
t.in <== data;
temp <== t.out; // temp is now constrained
result <== temp; // result inherits the binding
}
If the alias was a leftover, prefer removing it:
template Processor() {
signal input data;
signal output result;
component t = Transform();
t.in <== data;
result <== t.out;
}
Sample Sigvex Output
{
"detector": "signal-aliasing",
"severity": "medium",
"confidence": 0.72,
"title": "Signal alias in template `Processor`",
"template": "Processor",
"line": 9,
"description": "Signals `temp` and `result` are aliased via `result === temp`, but neither is independently constrained. The alias does not add security — both signals remain effectively unconstrained.",
"recommendation": "Add a constraining assignment to one side of the alias, or remove the redundant signal."
}
Detection Methodology
For each template, the detector walks every constraint and assignment and isolates equalities whose right-hand side is a single bare signal name (no arithmetic operators). It records the pair of signals involved and the line. It then determines, for each pair, whether either signal participates in any other meaningful constraint. Pairs where both signals lack independent constraints are reported.
Input-to-output forwarding (out === in where in is a template input and out is a template output) is treated as a valid pattern and excluded, because inputs are externally constrained by the caller.
Limitations
- The detector only matches direct signal-to-signal equality. Aliases hidden inside arithmetic expressions (such as
a + 0 === b) are reported by the trivial constraint detector instead. - Aliases that span template boundaries through component wiring are not tracked. If
parent.x === child.outandchild.outis unconstrained inside the child template, the parent template only sees the wiring and treats the alias as benign. - Confidence is medium because some legitimate aliases between intermediate signals exist for code clarity even when both endpoints are constrained transitively.
Related Detectors
- Trivial Constraint — tautological constraints providing no binding
- Under-Constrained Signal — signals lacking any constraint
- Signal Reuse — multiple assignments to the same signal