Inverse
template Inverse() {
signal input in;
signal output out;
assert(in != 0);
signal inv <-- in != 0 ? 1 / in : 0;
signal isZero <== 1 - (in * inv);
// if isZero, since in = 0 this holds
// otherwise, it holds due to in * 0 == 0
in * isZero === 0;
inv * isZero === 0;
out <== inv;
}
The (multiplicative) inverse of an element within a prime field is denoted as such that . An additive inverse of is shown as and it holds that . Inverting an element within the circuit is inefficient, so the inverse is computed off-circuit and a constraint is added to make sure their multiplications result in 1.
Zero does not have a multiplicative inverse though, and we can have a run-time assertion assert(in != 0)
as shown above to prevent that. However, a run-time assertion does not prevent a malicious prover to provide an altered witness that has a zero value for in
. We must handle that case as well, to output a certain value fo inv
when the input is zero. In the circuit above, we set inv
to be zero as well, and the constraint inv * isZero === 0
holds when the input is non-zero but inv
is zero.
There are two ways to find an inverse outside the circuit:
- Use Extended Euclidean Algorithm
- Use Fermat's Little Theorem
Interested reader can check them out on the web!