noir: Unreachable Error when calling std::verify_proof() multiple times in recursion circuit

Aim

I am trying to write a rollup circuit that can verify proofs from many sub circuits. Then, the rollup circuit needs to call std::verify_proof() multiple times to verify proofs from sub circuits. However, I got the Unreachble Runtime Error when generating the proof of the rollup circuit.

Moreover, I tried to generate the solidity verifier of the rollup circuit and deploy it using Remix (Default network). However, I got the error PUBLIC_INPUT_COUNT_INVALID.

I executed the repositories in macOS Sonoma 14.3.1 with Apple M3 Pro (12 cores).

Expected Behavior

The rollup circuit must be able to generate the rollup proof.

Bug

Generating proof from the rollup circuit in NoirJS raises the RuntimeError: unreachable.

To Reproduce

To reproduce the error, you can use the following two repositories:

Project Impact

Blocker

Impact Context

This feature is required in my project since the rollup circuit must verify more than one proof to reduce the verification cost.

Workaround

None

Workaround Description

No response

Additional Context

No response

Installation Method

Binary (noirup default)

Nargo Version

nargo version = 0.23.0 noirc version = 0.23.0+5be9f9d7e2f39ca228df10e5a530474af0331704 (git version hash: 5be9f9d7e2f39ca228df10e5a530474af0331704, is dirty: false)

NoirJS Version

0.23.0

Would you like to submit a PR for this Issue?

Maybe

Support Needs

No response

About this issue

  • Original URL
  • State: open
  • Created 4 months ago
  • Comments: 16 (6 by maintainers)

Most upvoted comments

After spending the majority of my day debugging this, I’m no longer convinced Nargo has any issues, but I cannot even get one verify_proof to run on the latest version of NoirJS, even when compiling with noir_wasm.

However, the noir-examples recursion repo DOES work with a single verify_proof, and gives unreachable with two.

I’m at a loss here and have nearly lost track of my test cases. I’ve tried just about every combination of #[recursive], one verify, two verifies, compiling with Nargo, compiling with noir_wasm, and even though it obviously works in some cases (like the noir-examples), I cannot figure out what is causing it to fail in others. Since nargo succeeds with identical input (as far as I can tell) and NoirJS still throw unreachable when done twice in a row on the same proof, I assume there is a real issue with NoirJS somewhere.

Could it be related to circuit size? I vaguely recall someone else mentioning a similar issue with bigger circuits in NoirJS, even though they were below the maximum wasm constraint size, but it wouldn’t explain why one verify would fail in one case and succeed in the other, since the inner circuit size shouldn’t be relevant when verifying a single inner proof (?).

😮‍💨

Hey we’re on it, hold on my friend!