Skip to content

Commit 223dc8b

Browse files
authored
Merge pull request #207 from AztecProtocol/jz/recursive-proofs-how-to
Example code using nested recursive proof verification
2 parents 7334015 + 17805da commit 223dc8b

File tree

14 files changed

+882
-0
lines changed

14 files changed

+882
-0
lines changed

how-to/recursive-proofs/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
build
3+
codegen
4+
circuits/*/export

how-to/recursive-proofs/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# A minimal example of nested recursion
2+
3+
## About
4+
5+
The code in this project shows recursive verification of Noir functions.
6+
7+
The primary function is simply addition, and verifies the re-calculation of one path up a binary tree from two leaf nodes.
8+
A more useful application of this design would be proving the hash of data in a merkle tree (leaf nodes), up to the merkle root. Amortizing the cost of proving each hash per nested call.
9+
10+
## The circuits
11+
The function doing the calculation, in this case addition, is in the sumLib. It is used in both recursive circuits: `sum` and `recursiveLeaf`.
12+
13+
## Verification
14+
Results of a call to `sum` are verified in `recursiveLeaf`, which itself also calls `sum` again. The results of the `recursiveLeaf` call are then verified in `recursiveNode`.
15+
16+
That is:
17+
- `recursiveNode` verifies `recursiveLeaf` artifacts
18+
- `recursiveLeaf` verifies `sum` artifacts
19+
20+
## Using this project
21+
- Install dependencies: `yarn`
22+
- Compile all the things: `yarn compile:all`
23+
- Run main typescript: `yarn start`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "recurse"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.26.0"
6+
7+
[dependencies]
8+
sumLib = { path = "../sumLib" }
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use dep::std;
2+
use dep::sumLib::secretSum;
3+
4+
#[recursive]
5+
fn main(
6+
verification_key: [Field; 114],
7+
public_inputs: pub [Field; 3],
8+
key_hash: Field,
9+
proof: [Field; 93],
10+
num: u64
11+
) -> pub u64 {
12+
// verify sum so far was computed correctly
13+
std::verify_proof(
14+
verification_key.as_slice(),
15+
proof.as_slice(),
16+
public_inputs.as_slice(),
17+
key_hash
18+
);
19+
secretSum((public_inputs[2] as u64), num)
20+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "recurse"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.26.0"
6+
7+
[dependencies]
8+
sumLib = { path = "../sumLib" }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use dep::std;
2+
3+
fn main(
4+
verification_key: [Field; 114],
5+
public_inputs: pub [Field; 5],
6+
key_hash: Field,
7+
proof: [Field; 93] // 109 bytes were supposed to be required to verify recursive proofs (WIP)
8+
) -> pub u64 {
9+
// verify sum was computed correctly
10+
std::verify_proof(
11+
verification_key.as_slice(),
12+
proof.as_slice(),
13+
public_inputs.as_slice(),
14+
key_hash
15+
);
16+
public_inputs[4] as u64
17+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "sum"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.26.0"
6+
7+
[dependencies]
8+
sumLib = { path = "../sumLib" }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use dep::sumLib::secretSum;
2+
3+
#[recursive]
4+
fn main(a: pub u64, b: pub u64) -> pub u64 {
5+
secretSum(a, b)
6+
}
7+
8+
#[test]
9+
fn test_not_equal() {
10+
assert(main(1, 3) == 4);
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "sumLib"
3+
type = "lib"
4+
authors = [""]
5+
compiler_version = ">=0.26.0"
6+
7+
[dependencies]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub fn secretSum(a: u64, b: u64) -> u64 {
2+
a + b
3+
}
4+
5+
#[test]
6+
fn test_sum() {
7+
assert(secretSum(1, 2) == 3);
8+
// Uncomment to make test fail
9+
// assert(secretSum(1, 1) == 3);
10+
}

0 commit comments

Comments
 (0)