Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiling plonk_vk.sol throws YulException: too deep in the stack & then fails to verify proof format #1140

Closed
1 task
Jovonni opened this issue Apr 12, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@Jovonni
Copy link

Jovonni commented Apr 12, 2023

Aim

I run the following commands successfully:

nargo compile p
nargo check
nargo prove p
nargo verify p
nargo codegen-verifier

The noir program is:

use dep::std;

fn main(
    // Public inputs
    pubkey_x: pub Field,
    pubkey_y: pub Field,

    // Private inputs
    beneficiary_priv_key: Field,
) -> pub Field {
    let pubkey = std::scalar_mul::fixed_base(beneficiary_priv_key);
    let computed_pubkey_x = pubkey[0];
    let computed_pubkey_y = pubkey[1];

    let x_match = if computed_pubkey_x == pubkey_x { 1 } else { 0 };
    let y_match = if computed_pubkey_y == pubkey_y { 1 } else { 0 };

    let success = x_match * y_match;
    // constrain x_match == 1;
    // constrain y_match == 1;
    success
}

The smart contract generated is:

// SPDX-License-Identifier: GPL-2.0-only
// Copyright 2020 Spilsbury Holdings Ltd

pragma solidity >=0.6.0;
pragma experimental ABIEncoderV2;

/**
 * @title Turbo Plonk proof verification contract
 * @dev Top level Plonk proof verification contract, which allows Plonk proof to be verified
 *
 * Copyright 2020 Spilsbury Holdings Ltd
 *
 * Licensed under the GNU General Public License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
contract TurboVerifier {
    using Bn254Crypto for Types.G1Point;
    using Bn254Crypto for Types.G2Point;
    using Transcript for Transcript.TranscriptData;

    /**
        Calldata formatting:

        0x00 - 0x04 : function signature
        0x04 - 0x24 : proof_data pointer (location in calldata that contains the proof_data array)
        0x44 - 0x64 : length of `proof_data` array
        0x64 - ???? : array containing our zk proof data
    **/
    /**
     * @dev Verify a Plonk proof
     * @param - array of serialized proof data
     */
    function verify(bytes calldata)
        external
        view
        returns (bool result)
    {

/// rest of contract ............ can paste more of generated contract if needed
........
 
    

Expected behavior

I expect the plonk_vk.sol contract that is generated by nargo to compile.

Bug

When I simply import the plonk_vk.sol:

import "../circuits/contract/plonk_vk.sol";

contract into an existing contract, I see the following error:

Compiler run failed
YulException: Cannot swap Variable var_public_input_delta with Slot TMP[addmod, 0]: too deep in the stack by 3 slots in [ RET var_public_input_delta var_lagrange_start _8 _1 _3 _11 _9 _5 _4 _2 _10 _6 _4 _7 _4 _4 _1 var_lagrange_end _3 TMP[addmod, 0] ]
No memoryguard was present. Consider using memory-safe assembly only and annotating it via 'assembly ("memory-safe") { ... }'.

I am confused why I would get this from a contract noir created if the nargo compilation process succeeded. Thoughts?

To reproduce

See the above. I am compiling the plonk_vk.sol contract via forge:

forge test --via-ir --optimize -vv

using --via-ir is typically how you resolve this issue without refactoring. I hope i don't have to refactor the generated plonk_vk.sol contract.

version

nargo --version
nargo 0.3.2 (git version hash: 29b1f7df4d563849a62e64c533cb62932188135b, is dirty: false)

Installation method

None

Nargo version

nargo 0.3.2 (git version hash: 29b1f7d, is dirty: false)

@noir-lang/noir_wasm version

no

@noir-lang/barretenberg version

no

@noir-lang/aztec_backend version

no

Additional context

See above

Submission Checklist

  • Once I hit submit, I will assign this issue to the Project Board with the appropriate tags.
@Jovonni Jovonni added the bug Something isn't working label Apr 12, 2023
@github-project-automation github-project-automation bot moved this to 📋 Backlog in Noir Apr 12, 2023
@Jovonni
Copy link
Author

Jovonni commented Apr 15, 2023

I changed some compilation errors, and it eventually compiled in solidity. Now i am having am issue passing the proof string to the plonk_vk.sol verify function...

I have tried both prepending the public inputs to the proof string, and passing just the proof string as well. Both fail.

the weird thing is noir verifies the contract properly, and I am using the correct pub inputs, prepended to the proof string itself...

strange. I even tried abi.encode for both pub fields, and the proof string..

I either get:
G1 point not on curve, or is malformed]

or

public inputs are greater than circuit modulus (IF I prepend with a "0x")

@Jovonni
Copy link
Author

Jovonni commented Apr 17, 2023

Update:

I've even tried complying with the following comment in the plonk_vk.sol file (above the verify function):

/
        Calldata formatting:

        0x00 - 0x04 : function signature
        0x04 - 0x24 : proof_data pointer (location in calldata that contains the proof_data array)
        0x44 - 0x64 : length of proof_data array
        0x64 - ???? : array containing our zk proof data
    /

Still to no avail. I've tried several variations of this as well.... not sure what the issue is.

I DID notice that within the verify function, this variable for

uint256 num_public_inputs = vk.num_inputs;

is wrong. My public input amount is 2, but when I log that variable in the contract it states the amount of public inputs is 3....

My TOTAL amount of inputs is 3... but public is only 2...

So that makes me wonder if something is wrong with the generation process for the plonk_vk.sol process...

@Jovonni Jovonni changed the title compiling plonk_vk.sol throws YulException: Cannot swap Variable var_public_input_delta with Slot TMP[addmod, 0]: too deep in the stack by 3 slots in [ RET var_public_input_delta var_lagrange_start compiling plonk_vk.sol throws YulException: too deep in the stack & then fails to verify proof format Apr 17, 2023
@Jovonni
Copy link
Author

Jovonni commented Apr 18, 2023

Update:

I still got the "proof failed" error. Here I am doing it again to show you the results.

I am passing the following format:

0x [function signature] + [proof data pointer] + [length of proof data] + [public input 1] + [public input 2] + [proof data array]

Details

Function Signature

0x8e760afe

Proof Data Pointer

0000000000000000000000000000000000000000000000000000000000000020

Length of proof data array

00000000000000000000000000000000000000000000000000000000000004e0

Public Input 1

0bff8247aa94b08d1c680d7a3e10831bd8c8cf2ea2c756b0d1d89acdcad877ad

Public Input 2

2a5d7253a6ed48462fedb2d350cc768d13956310f54e73a8a47914f34a34c5c4

Proof Data Array

2abfb...

Doing this, I no longer get the G1 point not on curve, or is malformed] error, but I get the proof failed error. This seems like it indicates the formatting is correct, but the proof input is wrong...

If I don't prepend my proof data with the two public inputs, then I get the G1 point not on curve, or is malformed] error again, so it seems like prepending the two public inputs works, but I cannot get past this proof failed error..

@Jovonni
Copy link
Author

Jovonni commented Apr 19, 2023

Here is the circuit

use dep::std;

fn main(
    // Private inputs
    priv_key: Field,

    // Public inputs
    pubkey_x: pub Field,
    pubkey_y: pub Field,
) -> pub Field {
    let pubkey = std::scalar_mul::fixed_base(priv_key);
    let computed_pubkey_x = pubkey[0];
    let computed_pubkey_y = pubkey[1];
    let x_match = if computed_pubkey_x == pubkey_x { 1 } else { 0 };
    let y_match = if computed_pubkey_y == pubkey_y { 1 } else { 0 };
    let success = x_match * y_match;
    constrain x_match == 1;
    constrain y_match == 1;
    success
}

Prover.toml (dummy values)

pubkey_x = "0x0bff8247aa94b08d1c680d7a3e10831bd8c8cf2ea2c756b0d1d89acdcad877ad"
pubkey_y = "0x2a5d7253a6ed48462fedb2d350cc768d13956310f54e73a8a47914f34a34c5c4"
priv_key = "0x000000000000000000000000000000000000000000000000000000616c696365"

Proof

2abfb6cbd23b3c5d995f1cb3a6be5d68f432ed2be3d14c64d6e5800a0f10ce4f1a240b6026ce6a33ae80d48ff429aa9e4bff781191f30518c51af617219bfc86217285d55081793455cd67daed62994bc6deaa414cf0643cc1df2388226c96a92b71b2be63e307fe1169a4164f4ee721e1adc1c9a397fced74d7c143eb40cdac108a578f28187f305ecb926956c0b66b84d7ac38e47ac4e46991e04e2eccf29f18d47a4fc15570b1225ee6e5c0035af9dfe01b1c4cbf7fe06dd3aa0790942c2613c8bb2371d16073dc8eff5f79cedf74fc0923df3678fdd8f3036b2b96fd3e080edf5b735965a12204eb4ffef8be64a2595327bdfa3ce85b022f8b4b4bbc0fc820469a25cf371648a7126ff8ab49e909875ff01bdeaceb065d226fbf2e1ecb4e2ff1e58d67360edfacf646895aabaafde77d5f19d5892c2e84fd9d59cbc123bf08f4d717b0da6a8e705c7308adfb4c914dca3cc2bce7a00f84093264532ff5e623a3d7566179e16b1fa324262ba92b6c15fc01dda01fb5e617bbb649aa4d9ada27043e2023fc8f871f2a5c580b7d0ababdecbbdd3cc1ceb9a8c28470c71349ee0d6838305d553580a4bddb0f8cbde820bf61da30ff7d9d9039169a0cef54b745080f2b114bbb66d533e8feda1bcac235255a3f046cc5f0eaab6c5b01b6f313d70e42aeca9420a2c0cf68244871efb97cbcf8c35850c9a445f644f6808c8aeed80784e0159c2bca5b3af811ce9ceaaf57d9c0b0ff248e99357d6577ac3eea4cd924e4de5a8c27ad347fd46c3f528d0049dd42c01181e41e1183d7f0e81bc5711b19c6013064b602aff1ebf89577be0f1e3df3b61b0c795ee893e867ae87a9300e055ccaf65063021bfdaea6439fd3f43ef20d061b5d41840417c3974a663ba2990e85cdae30d779a96d013307bf0e3b680aba4c939c8adc83c6d679da2cc4766616ebb8b26dd5719b6b19faaf6b22180e69e5e57178e39cb53979d0cdadfe638615f29f40e7393ab97adc43726bee2276e6ff4184544e6c8b62f6fb4c3c8a051e2978fde9b37ca0adc0fb17f94a0d1cbcf956d1bc2125a5a6bd480c0a51666072093ad0ea94854a7e31097e8e2b68595660aa05c9db6fb274de585fae136a45bb1369512c93909e91c0e55c112b3977356789223ff84129f1de31a798de5cdb1722800073c2198c5d80b099038068215a0e76cb75e8570676354deb4b0296e66117ab36b688d8cb06b1b0bb94fd7d3bdfa1b0b66188146b560b9ea66a5818373d2af41f5faec0d23bee35f4926ef17dbc51d2070e20c5398a00d3c83cc3a695f52d551810fb98ef797e3d84e5410ecfa2ebb06398cc6957ed5df4cd8da5d02e59080c4b5c730d101722f91e9ca155627a4d48c50ec5268bff4c67608e3eb428032790343282367822805f706c31e356911c3e4b95f4dd45eeba3402d3977c44ae0387082a97b16543f9dacec0e630ec439f85efefce85fd026dafc328603a5eb60d1afce7b55d5d93d63dd206be31ba2a4d45c7d5ed02fa0ce6d4100c776780462510bebf388189cbc6f5a22b873a2def9409847afb42af5892c78e6ba4181c721466e1069a2af3c170651a0c583dd8052700a6ed34057583f128c972079532e024a250fac6ff1f911d3d805298574fdd56bb7fb9568ef25ca38cdd2482889709

Data passed to the plonk_vk.sol verify function:

0x0bff8247aa94b08d1c680d7a3e10831bd8c8cf2ea2c756b0d1d89acdcad877ad2a5d7253a6ed48462fedb2d350cc768d13956310f54e73a8a47914f34a34c5c42abfb6cbd23b3c5d995f1cb3a6be5d68f432ed2be3d14c64d6e5800a0f10ce4f1a240b6026ce6a33ae80d48ff429aa9e4bff781191f30518c51af617219bfc86217285d55081793455cd67daed62994bc6deaa414cf0643cc1df2388226c96a92b71b2be63e307fe1169a4164f4ee721e1adc1c9a397fced74d7c143eb40cdac108a578f28187f305ecb926956c0b66b84d7ac38e47ac4e46991e04e2eccf29f18d47a4fc15570b1225ee6e5c0035af9dfe01b1c4cbf7fe06dd3aa0790942c2613c8bb2371d16073dc8eff5f79cedf74fc0923df3678fdd8f3036b2b96fd3e080edf5b735965a12204eb4ffef8be64a2595327bdfa3ce85b022f8b4b4bbc0fc820469a25cf371648a7126ff8ab49e909875ff01bdeaceb065d226fbf2e1ecb4e2ff1e58d67360edfacf646895aabaafde77d5f19d5892c2e84fd9d59cbc123bf08f4d717b0da6a8e705c7308adfb4c914dca3cc2bce7a00f84093264532ff5e623a3d7566179e16b1fa324262ba92b6c15fc01dda01fb5e617bbb649aa4d9ada27043e2023fc8f871f2a5c580b7d0ababdecbbdd3cc1ceb9a8c28470c71349ee0d6838305d553580a4bddb0f8cbde820bf61da30ff7d9d9039169a0cef54b745080f2b114bbb66d533e8feda1bcac235255a3f046cc5f0eaab6c5b01b6f313d70e42aeca9420a2c0cf68244871efb97cbcf8c35850c9a445f644f6808c8aeed80784e0159c2bca5b3af811ce9ceaaf57d9c0b0ff248e99357d6577ac3eea4cd924e4de5a8c27ad347fd46c3f528d0049dd42c01181e41e1183d7f0e81bc5711b19c6013064b602aff1ebf89577be0f1e3df3b61b0c795ee893e867ae87a9300e055ccaf65063021bfdaea6439fd3f43ef20d061b5d41840417c3974a663ba2990e85cdae30d779a96d013307bf0e3b680aba4c939c8adc83c6d679da2cc4766616ebb8b26dd5719b6b19faaf6b22180e69e5e57178e39cb53979d0cdadfe638615f29f40e7393ab97adc43726bee2276e6ff4184544e6c8b62f6fb4c3c8a051e2978fde9b37ca0adc0fb17f94a0d1cbcf956d1bc2125a5a6bd480c0a51666072093ad0ea94854a7e31097e8e2b68595660aa05c9db6fb274de585fae136a45bb1369512c93909e91c0e55c112b3977356789223ff84129f1de31a798de5cdb1722800073c2198c5d80b099038068215a0e76cb75e8570676354deb4b0296e66117ab36b688d8cb06b1b0bb94fd7d3bdfa1b0b66188146b560b9ea66a5818373d2af41f5faec0d23bee35f4926ef17dbc51d2070e20c5398a00d3c83cc3a695f52d551810fb98ef797e3d84e5410ecfa2ebb06398cc6957ed5df4cd8da5d02e59080c4b5c730d101722f91e9ca155627a4d48c50ec5268bff4c67608e3eb428032790343282367822805f706c31e356911c3e4b95f4dd45eeba3402d3977c44ae0387082a97b16543f9dacec0e630ec439f85efefce85fd026dafc328603a5eb60d1afce7b55d5d93d63dd206be31ba2a4d45c7d5ed02fa0ce6d4100c776780462510bebf388189cbc6f5a22b873a2def9409847afb42af5892c78e6ba4181c721466e1069a2af3c170651a0c583dd8052700a6ed34057583f128c972079532e024a250fac6ff1f911d3d805298574fdd56bb7fb9568ef25ca38cdd2482889709

@TomAFrench
Copy link
Member

Closing as proof format issue has been resolved and stack issue is being tracked in #2509

@github-project-automation github-project-automation bot moved this from 📋 Backlog to ✅ Done in Noir May 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

2 participants