noir-lang / noir

Noir is a domain specific language for zero knowledge proofs
https://noir-lang.org
Apache License 2.0
884 stars 195 forks source link

Error: `thread 'main' has overflowed its stack` for unknown reason as circuit complexity increases #3786

Closed willemolding closed 1 month ago

willemolding commented 10 months ago

Aim

I'm building a toy project in Noir that implements the ZkShuffle protocol. My implementation can be found here https://github.com/willemolding/noir_shuffle

The main circuit has the form

// number of cards in a deck
global N: Field = 6;

fn main(
    apk: pub Gaffine,
    preshuffle: pub [(Gaffine,Gaffine); N],
    postshuffle: pub [(Gaffine,Gaffine); N],
    shuffle: [Field; N],
    rand: [Field; N],
) {
    assert_valid_permutation(shuffle);
    for i in 0..N {
        let result = exp_elgamal_remask(apk, preshuffle[shuffle[i]], rand[i]);
        assert_points_equal(result.0, postshuffle[i].0);
        assert_points_equal(result.1, postshuffle[i].1);
    }
}

The exp_elgamal_remask function is doing some scalar multiplications and point additions on the baby jubjub curve.

As I increase the number of cards the circuit complexity increases. For N=6 cards the output of nargo info is:

+--------------+------------------------+--------------+----------------------+
| Package      | Language               | ACIR Opcodes | Backend Circuit Size |
+--------------+------------------------+--------------+----------------------+
| noir_shuffle | PLONKCSat { width: 3 } | 114399       | 118097               |
+--------------+------------------------+--------------+----------------------+

Expected Behavior

I expect a more useful error message that might direct my as to how I could get the circuit to compile

Bug

Increasing it any higher (e.g. N=7) results in a compiler crash

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
[1]    11951 abort      nargo info

To Reproduce

  1. Clone the repo https://github.com/willemolding/noir_shuffle
  2. cd noir_shuffle/shuffle_encrypt
  3. change line 7 of main.nr to anything greater than 6
  4. nargo info

Installation Method

Binary

Nargo Version

nargo version = 0.19.4 noirc version = 0.19.4+4d133c50a50f21ca23861a9d1987207bd8783d36 (git version hash: 4d133c50a50f21ca23861a9d1987207bd8783d36, is dirty: false)

Additional Context

No response

Would you like to submit a PR for this Issue?

No

Support Needs

Can anyone shed light on what might be causing this error? It seems to appear as the circuit complexity increases along with the number of cards being shuffled but as I understand it circuit size at N=6 isn't particularly large.

Any suggestions on how I could successfully implement this for N=52? E.g. using recursive proofs or some other kind of restructuring.

Furthermore it would be great to have the compiler produce more useful error messages in these cases.

Many thanks

TomAFrench commented 10 months ago

Potentially related to #3525.

Hey, looks like this is failing inside the flattening SSA pass. We're aware of some issues related to some of the SSA passes which we're currently looking into.

TomAFrench commented 1 month ago

This now compiles without a stack overflow with N = 52.