Hi, I'm writing a zkSNARK with Groth16 using crypto primitives and other features from Arkworks (arkworks · GitHub). I have this weird issue where, when I manually prove the circuit using cs.generate_constraints()
it shows that all constraints are satisfied (code below):
circuit.generate_constraints(cs.clone()).unwrap();
let result = cs.is_satisfied().unwrap();
if !result {
println!("{:?}", cs.which_is_unsatisfied());
} else {
println!("EVERYTHING WORKED"); // EVERYTHING WORKS
}
However, when I prove and verify the circuit using Groth16 prove()
and verify()
functions, verify always fails because the verification equation isn't true.
let (pk, vk) = Groth16::<E>::circuit_specific_setup(insert_circuit_for_setup, rng).unwrap(); let pvk: ark_groth16::PreparedVerifyingKey<E> = Groth16::<E>::process_vk(&vk).unwrap();
let proof = Groth16::<E>::prove(
&pk,
returning_user_circuit,
rng
).unwrap();
let verified = Groth16::<E>::verify(
&pvk,
&public_inputs,
&proof,
);
I checked that the public inputs are correctly supplied. I also checked that all ingredients to pvk (verifying key) stay the same from generation to right before verification. My circuit is complicated and involves multiple different elliptic curves, which I thought might be the issue at first, but it seems like using multiple curves in one circuit is an okay practice.
I have no idea why verification is failing... Happy to post more things if needed.