-
Notifications
You must be signed in to change notification settings - Fork 0
Panic when evaluating s(X, Y) with x = 0 or y = 0 #53
Copy link
Copy link
Open
Labels
Description
Crate
ragu_circuits
Severity
Repo commit
Description
If x = 0 or y = 0, many linear constraint terms vanish, meaning the corresponding constraints are no longer enforced in the aggregated polynomial check. This can weaken soundness by allowing invalid witnesses to pass verification.
Since these values are expected to be non-zero verifier challenges, evaluating the polynomial at zero should be explicitly disallowed.
Code
File name: ragu_circuits/src/sx.rs
pub fn eval<F: Field, C: Circuit<F>, R: Rank>(
circuit: &C,
x: F,
key: F,
) -> Result<unstructured::Polynomial<F, R>> {
if x == F::ZERO {
// The polynomial is zero if x is zero.
return Ok(Polynomial::new());
}
let multiplication_constraints = 0;
let linear_constraints = 0;
let x_inv = x.invert().expect("x is not zero");
let xn = x.pow_vartime([R::n() as u64]);
let xn2 = xn.square();
let current_u_x = xn2 * x_inv;
let current_v_x = xn2;
let xn4 = xn2.square();
let current_w_x = xn4 * x_inv;
let mut collector = Collector::<F, R> {
result: unstructured::Polynomial::new(),
multiplication_constraints,
linear_constraints,
x,
x_inv,
current_u_x,
current_v_x,
current_w_x,
one: current_w_x,
available_b: None,
_marker: core::marker::PhantomData,
};
let (key_wire, _, one) = collector.mul(|| unreachable!())?;
// Enforce linear constraint key_wire = key to randomize non-trivial
// evaluations of this circuit polynomial.
collector.enforce_zero(|lc| {
lc.add(&key_wire)
.add_term(&one, Coeff::NegativeArbitrary(key))
})?;
let mut outputs = vec![];
let (io, _) = circuit.witness(&mut collector, Empty)?;
io.write(&mut collector, &mut outputs)?;
for output in outputs {
collector.enforce_zero(|lc| lc.add(output.wire()))?;
}
collector.enforce_zero(|lc| lc.add(&one))?;
collector.result[0..collector.linear_constraints].reverse();
assert_eq!(collector.result[0], collector.one);
Ok(collector.result)
}Recommendations
Return an error or panic when x == 0 or y == 0, and document that verifier challenges must be sampled from F \ {0}.
pub fn eval<F: Field, C: Circuit<F>, R: Rank>(
circuit: &C,
x: F,
key: F,
) -> Result<unstructured::Polynomial<F, R>> {
// In the ZKP setting, x is a verifier challenge and must be non-zero.
// If x == 0, linear constraints encoded in s(X, Y) may vanish,
// weakening soundness of the aggregated check.
assert_ne!(x, F::ZERO, "challenge x must be non-zero");
let multiplication_constraints = 0;
let linear_constraints = 0;
let x_inv = x.invert().expect("x is not zero");
let xn = x.pow_vartime([R::n() as u64]);
let xn2 = xn.square();
let current_u_x = xn2 * x_inv;
let current_v_x = xn2;
let xn4 = xn2.square();
let current_w_x = xn4 * x_inv;
...
}Also affected
The same change should be applied to:
- the
evalfunction inragu_circuits/src/s/sxy.rs - the
evalfunction inragu_circuits/src/s/sy.rs - the
StageObject::sxyfunction inragu_circuits/src/staging/object.rs - the
StageObject::sxfunction inragu_circuits/src/staging/object.rs - the
StageObject::syfunction inragu_circuits/src/staging/object.rs
Reactions are currently unavailable