Skip to main content
Version: v0.30.0

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.

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

The #[recursive] Attribute

In Noir, the #[recursive] attribute is used to indicate that a circuit is designed for recursive proof generation. When applied, it informs the compiler and the tooling that the circuit should be compiled in a way that makes its proofs suitable for recursive verification. This attribute eliminates the need for manual flagging of recursion at the tooling level, streamlining the proof generation process for recursive circuits.

Example usage with #[recursive]

fn main(x: Field, y: pub Field) {
assert(x == y, "x and y are not equal");

// This marks the circuit as recursion-friendly and indicates that proofs generated from this circuit
// are intended for recursive verification.

By incorporating this attribute directly in the circuit's definition, tooling like Nargo and NoirJS can automatically execute recursive-specific duties for Noir programs (e.g. recursive-friendly proof artifact generation) without additional flags or configurations.

Verifying Recursive Proofs

pub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {}

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

Example usage

use dep::std;

fn main(
verification_key : [Field; 114],
proof : [Field; 93],
public_inputs : [Field; 1],
key_hash : Field,
proof_b : [Field; 93],
) {


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



The verification key for the zk program that is being verified.


The proof for the zk program that is being verified.


These represent the public inputs of the proof we are verifying.


A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator.