To verify a Groth16 proof inside another circuit, implement or use the Groth16VerifierGadget. This gadget implements the SNARKGadget trait, allowing it to be integrated into a larger constraint system.
Workflow
- Allocate Variables: Use the
AllocVar implementation for ProofVar, VerifyingKeyVar, and PreparedVerifyingKeyVar to bring the proof and keys into the circuit. - Prepare the Key: If using
VerifyingKeyVar, call .prepare() to create a PreparedVerifyingKeyVar. - Verify: Call
verify (which uses the prepared key internally) or verify_with_processed_vk (if you already have a PreparedVerifyingKeyVar) to obtain a Boolean variable representing the validity of the proof.
// Assuming TestSNARKGadget is an instance of Groth16VerifierGadget
// and you have allocated input_gadget, proof_gadget, and vk_gadget
// Option 1: Using the standard verify method
<TestSNARKGadget as SNARKGadget<...>>::verify(
&vk_gadget,
&input_gadget,
&proof_gadget
)?
.enforce_equal(&Boolean::constant(true))
.unwrap();
// Option 2: Using the optimized verify_with_processed_vk method
let pvk = TestSNARK::process_vk(&vk).unwrap();
let pvk_gadget = <TestSNARKGadget as SNARKGadget<...>>::ProcessedVerifyingKeyVar::new_constant(
ns!(cs, "alloc_pvk"),
pvk.clone()
).unwrap();
<TestSNARKGadget as SNARKGadget<...>>::verify_with_processed_vk(
&pvk_gadget,
&input_gadget,
&proof_gadget
)?
.enforce_equal(&Boolean::constant(true))
.unwrap();