Skip to content

Commit

Permalink
chore: add example for recursion on the CLI (#6389)
Browse files Browse the repository at this point in the history
This PR adds an example script which does recursive verification using
`nargo` and the `bb` binary as based on @jzaki's javascript example
noir-lang/noir#4969.
  • Loading branch information
TomAFrench authored and Maddiaa0 committed Jun 5, 2024
1 parent c76c4a6 commit 72f648b
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions noir/noir-repo/examples/recursion/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
recurse_leaf/Prover.toml
recurse_node/Prover.toml
2 changes: 2 additions & 0 deletions noir/noir-repo/examples/recursion/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["recurse_leaf", "recurse_node", "sum"]
61 changes: 61 additions & 0 deletions noir/noir-repo/examples/recursion/generate_recursive_proof.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash
set -eu

BACKEND=${BACKEND:-bb}

nargo execute sum_witness --package sum
$BACKEND prove -b ./target/sum.json -w ./target/sum_witness.gz -o ./target/sum_proof

# Once we have generated our inner proof, we must use this to generate inputs to `recurse_leaf``

$BACKEND write_vk -b ./target/sum.json -o ./target/sum_key
$BACKEND vk_as_fields -k ./target/sum_key -o ./target/sum_vk_as_fields
VK_HASH=$(jq -r '.[0]' ./target/sum_vk_as_fields)
VK_AS_FIELDS=$(jq -r '.[1:]' ./target/sum_vk_as_fields)

FULL_PROOF_AS_FIELDS="$($BACKEND proof_as_fields -p ./target/sum_proof -k ./target/sum_key -o -)"
# sum has 3 public inputs
PUBLIC_INPUTS=$(echo $FULL_PROOF_AS_FIELDS | jq -r '.[:3]')
PROOF_AS_FIELDS=$(echo $FULL_PROOF_AS_FIELDS | jq -r '.[3:]')

RECURSE_LEAF_PROVER_TOML=./recurse_leaf/Prover.toml
echo "num = 2" > $RECURSE_LEAF_PROVER_TOML
echo "key_hash = \"$VK_HASH\"" >> $RECURSE_LEAF_PROVER_TOML
echo "verification_key = $VK_AS_FIELDS" >> $RECURSE_LEAF_PROVER_TOML
echo "proof = $PROOF_AS_FIELDS" >> $RECURSE_LEAF_PROVER_TOML
echo "public_inputs = $PUBLIC_INPUTS" >> $RECURSE_LEAF_PROVER_TOML

# We can now execute and prove `recurse_leaf`

nargo execute recurse_leaf_witness --package recurse_leaf
$BACKEND prove -b ./target/recurse_leaf.json -w ./target/recurse_leaf_witness.gz -o ./target/recurse_leaf_proof

# Let's do a sanity check that the proof we've generated so far is valid.
$BACKEND write_vk -b ./target/recurse_leaf.json -o ./target/recurse_leaf_key
$BACKEND verify -p ./target/recurse_leaf_proof -k ./target/recurse_leaf_key

# Now we generate the final `recurse_node` proof similarly to how we did for `recurse_leaf`.

$BACKEND vk_as_fields -k ./target/recurse_leaf_key -o ./target/recurse_leaf_vk_as_fields
VK_HASH=$(jq -r '.[0]' ./target/recurse_leaf_vk_as_fields)
VK_AS_FIELDS=$(jq -r '.[1:]' ./target/recurse_leaf_vk_as_fields)

FULL_PROOF_AS_FIELDS="$($BACKEND proof_as_fields -p ./target/recurse_leaf_proof -k ./target/recurse_leaf_key -o -)"
# recurse_leaf has 4 public inputs (excluding aggregation object)
PUBLIC_INPUTS=$(echo $FULL_PROOF_AS_FIELDS | jq -r '.[:4]')
PROOF_AS_FIELDS=$(echo $FULL_PROOF_AS_FIELDS | jq -r '.[4:]')

RECURSE_NODE_PROVER_TOML=./recurse_node/Prover.toml
echo "key_hash = \"$VK_HASH\"" > $RECURSE_NODE_PROVER_TOML
echo "verification_key = $VK_AS_FIELDS" >> $RECURSE_NODE_PROVER_TOML
echo "proof = $PROOF_AS_FIELDS" >> $RECURSE_NODE_PROVER_TOML
echo "public_inputs = $PUBLIC_INPUTS" >> $RECURSE_NODE_PROVER_TOML

# We can now execute and prove `recurse_node`

nargo execute recurse_node_witness --package recurse_node
$BACKEND prove -b ./target/recurse_node.json -w ./target/recurse_node_witness.gz -o ./target/recurse_node_proof

# We finally verify that the generated recursive proof is valid.
$BACKEND write_vk -b ./target/recurse_node.json -o ./target/recurse_node_key
$BACKEND verify -p ./target/recurse_node_proof -k ./target/recurse_node_key
7 changes: 7 additions & 0 deletions noir/noir-repo/examples/recursion/recurse_leaf/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "recurse_leaf"
type = "bin"
authors = [""]
compiler_version = ">=0.26.0"

[dependencies]
20 changes: 20 additions & 0 deletions noir/noir-repo/examples/recursion/recurse_leaf/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use dep::std;

#[recursive]
fn main(
verification_key: [Field; 114],
public_inputs: pub [Field; 3],
key_hash: Field,
proof: [Field; 93],
num: u64
) -> pub u64 {
// verify sum so far was computed correctly
std::verify_proof(
verification_key.as_slice(),
proof.as_slice(),
public_inputs.as_slice(),
key_hash
);
// Take output of previous proof and add another number to it.
public_inputs[2] as u64 + num
}
7 changes: 7 additions & 0 deletions noir/noir-repo/examples/recursion/recurse_node/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "recurse_node"
type = "bin"
authors = [""]
compiler_version = ">=0.26.0"

[dependencies]
17 changes: 17 additions & 0 deletions noir/noir-repo/examples/recursion/recurse_node/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use dep::std;

fn main(
verification_key: [Field; 114],
public_inputs: pub [Field; 4],
key_hash: Field,
proof: [Field; 109]
) -> pub u64 {
// verify sum was computed correctly
std::verify_proof(
verification_key.as_slice(),
proof.as_slice(),
public_inputs.as_slice(),
key_hash
);
public_inputs[3] as u64
}
7 changes: 7 additions & 0 deletions noir/noir-repo/examples/recursion/sum/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "sum"
type = "bin"
authors = [""]
compiler_version = ">=0.26.0"

[dependencies]
2 changes: 2 additions & 0 deletions noir/noir-repo/examples/recursion/sum/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a = 1
b = 2
4 changes: 4 additions & 0 deletions noir/noir-repo/examples/recursion/sum/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[recursive]
fn main(a: pub u64, b: pub u64) -> pub u64 {
a + b
}
8 changes: 8 additions & 0 deletions noir/noir-repo/examples/recursion/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -eu

# This file is used for Noir CI and is not required.

BACKEND=${BACKEND:-bb}

./generate_recursive_proof.sh

0 comments on commit 72f648b

Please sign in to comment.