Skip to main content
Version: dev

Recursive Proofs

Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof.

Noir cannot check internally whether a recursive proof is valid or not as this can only be checked by the proving backend. This means that witness execution can still succeed in the case where an invalid proof is used, however an invalid proof is expected to cause the proving backend to fail to generate a valid proof.

In order to verify recursive proofs from Barretenberg, it's recommended to use the bb_proof_verification library which is published by the Barretenberg team.

Verifying Recursive Proofs

pub fn verify_proof_with_type<let N: u32, let M: u32, let K: u32>(
verification_key: [Field; N],
proof: [Field; M],
public_inputs: [Field; K],
key_hash: Field,
proof_type: u32,
) {}

verify_proof_with_type is the backend-agnostic way to verify a recursive proof. The proof_type argument identifies the proving scheme used to generate the proof, which allows a single backend to support verifying multiple proving schemes. It must be known at compile time.

This is a black box function. Read this section to learn more about black box functions in Noir.

Arguments

  • verification_key: The verification key of the circuit to be verified.
  • proof: The proof to be verified.
  • public_inputs: The public inputs associated with proof.
  • key_hash: The hash of verification_key of the form expected by the backend.
  • proof_type: An identifier for the proving scheme used to generate the proof to be verified.

Noir cannot by itself constrain that key_hash is a valid hash of verification_key, since different backends hash their verification keys differently. It is the responsibility of either the developer (by explicitly hashing the verification key in the correct manner) or the proving system itself (by internally asserting the correctness of key_hash) to ensure this holds.

If you are not developing your own proving backend, you should not need to call verify_proof_with_type directly. Prefer a verification library published by the backend developers — for Barretenberg, the bb_proof_verification library wraps this function, sets the correct proof_type for you, and documents the backend's safety requirements. Calling verify_proof_with_type directly without these guarantees can introduce underconstrainedness bugs and make your circuit insecure.

Read the explainer on recursion to know more about this function and the guide on how to use it.

You can see a full example of recursive proofs in this example recursion demo repo.