-
Couldn't load subscription status.
- Fork 253
Description
Currently, FpGadget::inverse would complain when the inverse does not exist.
#[inline]
fn inverse<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<Self, SynthesisError> {
let inverse = Self::alloc(cs.ns(|| "inverse"), || {
let result = self.value.get()?;
let inv = result.inverse().expect("Inverse doesn't exist!");
Ok(inv)
})?;
let one = CS::one();
cs.enforce(
|| "inv_constraint",
|lc| &self.variable + lc,
|lc| &inverse.variable + lc,
|lc| lc + one,
);
Ok(inverse)
}
This, however, creates significant challenges during the indexing phase, in which all inputs and witnesses are fake, and many of them could be zero.
For example, in Zexe there is a NIZK verifier that checks the proof in the constraint system, which does some inverse operations. To make the indexing works, Zexe has to generate a proof for a blank circuit.
A similar challenge exists for other recursive proof systems, in which a real proof or a carefully crafted fake proof is needed.
Proposed solution:
Consider this line:
let inv = result.inverse().expect("Inverse doesn't exist!");
What if we set inv to zero when the inverse does not exist? This can be done with a unwrap_or(...).
Setting it to zero would not cause a soundness issue since the constraint would be unsatisfied, which would not affect the indexing phase.