noir: Solidity on-chain verification fails even though verification ass with bb.js

Aim

  • We are trying to verify our zkp smart contract on-chain.
  • However, even though the proof verification passes using api.acirVerifyProof from bb.js, on-chain verification fails

Expected Behavior

  • On-chain verification should pass

Bug

image

Command and Error message

$  forge script script/Starter.s.sol:StarterScript --rpc-url http://127.0.0.1:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast -vvvv
$ pnpm ts-node --esm node-script/verifyProofOnChain.ts 0x8A791620dd6260079BF849Dc5567aDC3F2FdC318
VerifierContract: 0x8A791620dd6260079BF849Dc5567aDC3F2FdC318
env local
{
  walletPubKey: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  provider: 'http://127.0.0.1:8545'
}
Instantiating...
Generating inputs...
{ ccTobigint: 16978n }
{
  leaf: '9085282287955611025852103847033223553299672593909661339088018600613152307921',
  root: '4376485518484728565083006278613774608474257183702418234236934724788569188631',
  pathIndices: [
    1, 0, 1, 1,
    1, 0, 0, 0
  ],
  siblings: [
    '11752557305846564995419635702637388329824873040488976863271743293402468007613',
    '7163806489970069248027858684803666247509627789903524841019428770680611244236',
    '8052471871190071024590520090990652253996244381976695186225489824603455299324',
    '9973666284734535987847047307473694538192618488651454404613063129721244055711',
    '12553528803585799650198297445377912390680378736360090355845152159395343506690',
    '13845000498301242585584591222933663374902444583541563442470198430055666212205',
    '5319182605362636011959743237107249310133514183919241553434250327842425835405',
    '11483660179254614699774828842586182979768384209824455350234917632354184479553'
  ]
}
witness input 0: 627662350134793187224942827526618393967084608563228109339165368344744831975
witness input 1: 15061847289015107671233677668779070455496166783773065974896603868472984069880
witness input 2: 6339449204472228899849180718373396797859415662732609545325465987213125464911
witness input 3: 18n
witness input 4: 1243458046809013647717n
witness input 5: 20n
witness input 6: 16978n
witness input 7: 892745528n
witness input 8: 892745528n
witness input 9: 892745528n
witness input 10: 9085282287955611025852103847033223553299672593909661339088018600613152307921
witness input 11: 4376485518484728565083006278613774608474257183702418234236934724788569188631
witness input 12: 1
witness input 13: 0
witness input 14: 1
witness input 15: 1
witness input 16: 1
witness input 17: 0
witness input 18: 0
witness input 19: 0
witness input 20: 11752557305846564995419635702637388329824873040488976863271743293402468007613
witness input 21: 7163806489970069248027858684803666247509627789903524841019428770680611244236
witness input 22: 8052471871190071024590520090990652253996244381976695186225489824603455299324
witness input 23: 9973666284734535987847047307473694538192618488651454404613063129721244055711
witness input 24: 12553528803585799650198297445377912390680378736360090355845152159395343506690
witness input 25: 13845000498301242585584591222933663374902444583541563442470198430055666212205
witness input 26: 5319182605362636011959743237107249310133514183919241553434250327842425835405
witness input 27: 11483660179254614699774828842586182979768384209824455350234917632354184479553
witness inputs: Map(28) {
  1 => '0x01633e8a7f2af0b95ee3aeea580087d212b3fb03369a12e5e5a3abee35282be7',
  2 => '0x214cb4160d21ab6bc0b5cb32ebc46299a0a7d50e14798fce0b4417804b05e6f8',
  3 => '0x0e040047cfde7e20ac531992e783a730211841fa9a9dbd21397b40d419cbb34f',
  4 => '0x0000000000000000000000000000000000000000000000000000000000000012',
  5 => '0x00000000000000000000000000000000000000000000004368726973204e7965',
  6 => '0x0000000000000000000000000000000000000000000000000000000000000014',
  7 => '0x0000000000000000000000000000000000000000000000000000000000004252',
  8 => '0x0000000000000000000000000000000000000000000000000000000035363738',
  9 => '0x0000000000000000000000000000000000000000000000000000000035363738',
  10 => '0x0000000000000000000000000000000000000000000000000000000035363738',
  11 => '0x141616696ea25399e23bf7e53133a6fe97428ccb6bb87d0d99306dd2d0cc3ad1',
  12 => '0x09ad00c6091bc298a31ce5b4e974fb4775f76cf69e95d85d89bf39dcc9db2917',
  13 => '0x0000000000000000000000000000000000000000000000000000000000000001',
  14 => '0x0000000000000000000000000000000000000000000000000000000000000000',
  15 => '0x0000000000000000000000000000000000000000000000000000000000000001',
  16 => '0x0000000000000000000000000000000000000000000000000000000000000001',
  17 => '0x0000000000000000000000000000000000000000000000000000000000000001',
  18 => '0x0000000000000000000000000000000000000000000000000000000000000000',
  19 => '0x0000000000000000000000000000000000000000000000000000000000000000',
  20 => '0x0000000000000000000000000000000000000000000000000000000000000000',
  21 => '0x19fbb63273971f43bdb5d077ab53802df59f4691a1db6f318d192165123b3ebd',
  22 => '0x0fd6921ef30646134b1b38e669f329638bec4f54ba0c6b902174850877fb88cc',
  23 => '0x11cd899dedb5e2c0c8b94ba2a03d09c1ca0d095b92704928ef4bedc969571efc',
  24 => '0x160ce523484c16ef6e82813aaed8d7b001183e3280adfc701f80a2944679789f',
  25 => '0x1bc10ba682cbc11532b0de6ae83cc0e7ce190b7dcafc796a0c37957a0ba41d02',
  26 => '0x1e9bfe1a0bb2974094b9468f9ac3f1720d53c3f4ce098c7974893f0c6196dd6d',
  27 => '0x0bc28cf85d49bb9a07c222167213f126bac3d6a20ffe502ad0be9e0985568f8d',
  28 => '0x19638575b1657472b33a978250926154881216e1fc340d157043c7a330ba4341'
}
Generating proof...
Verify proof...
Verified: true
publicInputs 128
/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+logger@5.6.0/node_modules/@ethersproject/logger/src.ts/index.ts:261
        const error: any = new Error(message);
                           ^
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="verifyEqual(bytes,bytes32[])", data="0x0711fcec", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.4)
    at Logger.makeError (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+logger@5.6.0/node_modules/@ethersproject/logger/src.ts/index.ts:261:28)
    at Logger.throwError (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+logger@5.6.0/node_modules/@ethersproject/logger/src.ts/index.ts:273:20)
    at Interface.decodeFunctionResult (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+abi@5.6.4/node_modules/@ethersproject/abi/src.ts/interface.ts:427:23)
    at Contract.<anonymous> (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+contracts@5.6.2/node_modules/@ethersproject/contracts/src.ts/index.ts:400:44)
    at step (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+contracts@5.6.2/node_modules/@ethersproject/contracts/lib/index.js:48:23)
    at Object.next (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+contracts@5.6.2/node_modules/@ethersproject/contracts/lib/index.js:29:53)
    at fulfilled (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@ethersproject+contracts@5.6.2/node_modules/@ethersproject/contracts/lib/index.js:20:58)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  reason: null,
  code: 'CALL_EXCEPTION',
  method: 'verifyEqual(bytes,bytes32[])',
  data: '0x0711fcec',
  errorArgs: null,
  errorName: null,
  errorSignature: null,
  address: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
  args: [
    Uint8Array(2144) [
       21,  18, 211, 172,  81, 102, 202, 107,  72,  83,  16,  32,
      144,  14, 178,  17,  77,  78,  85, 141,  74,  16,  42,  36,
      179, 111,  37, 141, 105, 160,  65,  84,  48,  11, 195, 140,
       78,   4, 192,  59, 140,  23,  71, 140, 245,  30, 103,  36,
       47,  65, 133,  97, 159, 250, 176, 166,  68, 112,  61,  86,
       56, 188,  36, 137,   2, 117, 214, 217,  92, 148, 249,  92,
      129, 112,  25, 167, 100, 108, 175,  61,  43,  57,  64,  21,
       81, 199, 241,   8, 191, 162, 226,  46, 206, 227,  87, 254,
       45,  59, 153, 207,
      ... 2044 more items
    ],
    [ [Uint8Array], [Uint8Array], [Uint8Array], [Uint8Array] ]
  ],
  transaction: {
    data: '0x7d08867e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008c000000000000000000000000000000000000000000000000000000000000008601512d3ac5166ca6b48531020900eb2114d4e558d4a102a24b36f258d69a04154300bc38c4e04c03b8c17478cf51e67242f4185619ffab0a644703d5638bc24890275d6d95c94f95c817019a7646caf3d2b39401551c7f108bfa2e22ecee357fe2d3b99cfb0457a7cac72559d486efd1123b2e95e8343120665e007f223cdc53a179fff5e65d6cf2c6ab3ce1f5c328769c29c795d8e4faf2ec6076895f5dd17f305d0009b788b633656a29408828e91258cf81f4758314ce9c185f61136a40de5101808b9357d41023eb0fede8f2faf5cf75bda05b6bdcaa4f5cf4efed69a3ac31229efde8f7e1b630df2709c707ad2e014b5295331ede9dca52a6ef8417434aa1649a77c955e087424519772b0e3f921c28167ff6798b2872241c09b2c9a95800902021bd0b626c1987c0157bd24910f0ccd11938290b3e4879898e90730f0fb04d2d85ef5ff992e307dd488f8e973c9dd0019335763c787a576fcdf2dbcc5851dde51d516d7f6ed620e9cc28f9b7f22e1e00711cfc83da2461a393e18ae88f72e423a7f2d20280bc931b0e76b0d189dd20744be8b55877aa2a3d5200dcc198f0c2ffd243d44f20a79657cc5e643d68c0be8cdff8004972822ddf684e0c5d3e70552ada9923f56f38105263bb799ada43f5b374b465971561cdf8802d1c96a53164e32a081b1888eb2960645ee146f221a2026ce1e09cd2870eadeb7f47699751aa2d5479adf6106c0932cd8bc3fa7d4531a37e8d4fb876c9a92f51d5a9de8392dc1c3dff4906de0601b329a87969b94b111e9a87c573f5ca97a91cf85658c850f8cbe1e056d5ba7c10dd66016d91c38a75fb6de084edda15c6bb7cf2ab0ecb828a97e992c726913fc82de138ba0b946260fdb08c2dc3e039c06fecd36c68e341b247a0e1b70afa430f9df411a094fa334ae52c35fc3efbd50eba7f53b1346a129bb48c45b4aeeba387cf0cd451e3d75ff4b30c59721c0a915af78f5c46a49971cc57ff730303f52964f1550f08a4c0a6f92c46a2befa8c6361002c84ca339b01222914ac436e2b5d0d84d8c30ed4ceb0401e31fde8ea5ea0825212557bb6bd62cf9bbc15fb795f5ed91e3d5253adc9c5c4befd5adaade5557fa58174e68af8c0f231fa26b5355eeb7b7c4ef0e73a59314ac4a615df15aea072ffa75d4d7b5d414af28c9b07a88ac2850fe10c90dbe516dc83a8dbc0a56cd5ecb8638967db1c72ed2e5afabfbe0e0cd0bf246847aa88c256e2f1610fc2e3a71f2fabb94874c9619376e35a4681443117a83afa901e7fa507ebada2bf6a469ef3ff79bcd2419342021ae117ec7e45c984a86d1b488af022ed3db7fce1560151569ca85e641ff2c298c5d3828e13601122913572437e04a030e88225cb1f07314c902732d8abba105003fbefa0d9fc3ab58583865169120ffd6496bc836fa2029557408ecc448d202a92657913821fb680b78e49e7a47686e90fc5f6df5bad42bfff577fbeea5ee1a41972949b70b50fc9937c2edb1aeae787f8a8eb56fe4555f7d7a2bbd0678db14282f3188a99a152dc778568dc5147ca57f1887cea4be2e3228117dfd3c42ce16edc814ecd74bf952d29a244501df1574a0d7822f608d5b6c3e7141d2d278f90bbeee46353db39c2f9a750b6e98b5fcbab918c5377c985495f99c1b1f4791282815795bf5feb961568616cccbe4e3d594bb9ae609a46975cad300dbde1c6e112c89a349bbfe9516d1ea5238e28c8b5f170956c6b56158bbc4ea72bb68915dda1ae468d030f7e07867d9af1f22aff0384348fa2c2bf82c23dce13b6931aae0fb1d5de6e9f6da33740df14008f1be7fba3d7216cb4f7754ea74092389c992bd400c442e3973e7b1ad91f2321703ffce56e1fd6e0985cf2c48239b70a9eb64e14913fd0d183845b1c0de1dbd9b4aae60ab8ec23964ae6495082ffe2b75eed35e3d050da8b266ccac581062835a8e5a8214f370e63f9321c6b6753760e68d7b3d6b0981d2a02ccc880d8bc6bec6a502299e75bea2203edeb5fc6f4ed2c617f02d340df5fc8df2cc63c3072afa32bba9d127f80c5e00ea9ba542696644a5a2651cfd126a267bb8cc3f78828f359ed25178b17a5a19e196589488637db6852cda0cc600997ec4a0ccd0a294fe47ee77b2da8b71232a5ee764d7707b1fef0703064da21a2a7e580ffad3607c76d5a02afdcf50bfc38fb70365d3d1872613641fdf94930dc1a19334d3413a71cdb83e3db0d0aaca68112e8d2a41968374fcda603cb39702a7e893acf99b419334e7d0072a8c64bc938de4d9851c5198a1f484723f37431ba4dc52f34e908f2f49fc784a23b99e79f127c27fb6cbe84d6362cb4b7c5dd51332ee92192d85753a35c78dac83877cda60e572da7b02483364f9c3c2e575e72827e642af5ca26cdd6284073241cfb05e9fad3c26fe72ace79b4e03e1dbcb882136e4e496a4166ae4e9ab23352b64a155ae92b95340037ea704483726da1e7704306c4ebfe99adb899a31a0605eb36166fb96f128765a1e62280b7ad884112c03be3a107747bde9b456ca086a658f5bbd4b61eb566b9753765648e02838a3a922b71c20b427810b636615553ffded1e8f8c2e3e82a59ffa81f48697b65945fa28b4b7284a43a4fe775e550e28722c80858971c41a3e111ca832d034594184871a7b455b17a9760ee0e84ace657514bc646375d8eb75c37a5600f836436574041cb035cd59a23fe573a6510a433ed676c2166a55a9bf93c487d6623ac9033daf1ee5263f9b9b09bc06645746210898311fc95ed26809640eb9abcc3f4ea1075a211a16b1dd93d39299225d81fed259eb7d7c534f26533458eb813643d43ed1050bb1f87f0a25f9f5ecf0527073b859f1629b94f25e0946fb4a9763bec9d2848b15ff639014b616df3c45aaf63a478a8514c9292ee8a59a85e7d4635ae5c9198221093c4a569823530d7a172f512f39db4958477c1f6d70c5671a66b1646a668c0ebc52d559bd5d45c251e01b692720328de04a7b505ecad9785218c99ce09044000000000000000000000000000000000000000000000000000000000000000401633e8a7f2af0b95ee3aeea580087d212b3fb03369a12e5e5a3abee35282be7214cb4160d21ab6bc0b5cb32ebc46299a0a7d50e14798fce0b4417804b05e6f80e040047cfde7e20ac531992e783a730211841fa9a9dbd21397b40d419cbb34f0000000000000000000000000000000000000000000000000000000000000012',
    to: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
    from: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'
  }
}

To Reproduce

You can find the reproducible code in https://github.com/tomoima525/noir-starter/pull/1

Installation Method

Binary

Nargo Version

nargo 0.9.0 (git version hash: 3d1b2522c8d9a0acebff102f9f877c44178c5db5, is dirty: false)

Additional Context

I see that when the number of gates hits a certain amount, on-chain(Solidity) verification fails

We have three assertions in the circuit.

  1. Poseidon hash assertion
  2. age range assertion
  3. merkle root assertion

I tested the patterns below and found that on-chain verification fails when everything is checked at once

  • Assertion 1 & 2 => Succeeds
  • Assertion 3 only => Succeeds
  • Assertion 1 & 2 & 3 => Fails

This is the number of gates in each assertion.

1. Poseidon hash  assertion
[main] Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 7232
[main] Backend circuit size: 7225

2. age range assertion
[main] Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 19
[main] Backend circuit size: 2776

3. merkle root assertion
[main] Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 19329
[main] Backend circuit size: 19316

Total
[main] Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 26570
[main] Backend circuit size: 29315

Would you like to submit a PR for this Issue?

No

Support Needs

Just pinging @critesjosh as we’ve been discussing this issue

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 21 (7 by maintainers)

Most upvoted comments

Was able to resolve import issue by adding @ts-ignore

image

And successfully verify the contract onchain with 0.10.5

Referencing the update https://github.com/knot-inc/noxx-contract/pull/40#issuecomment-1710512956

In trying to replicate this error, I wrote my own circuit of varying sizes.

I wrote this circuit

fn main(x : u52) {
    let mut z = x; 
    for i in 0..5000{
        z = z + 1;
        assert(z > x);
    }
}

nargo info prints

+-------------+------------------------+--------------+----------------------+
| Package     | Language               | ACIR Opcodes | Backend Circuit Size |
+-------------+------------------------+--------------+----------------------+
| noirstarter | PLONKCSat { width: 3 } | 50001        | 65413                |
+-------------+------------------------+--------------+----------------------+

proving and verify works with nargo.

Verifying fails when building the solidity verifier, deploying to anvil, and running in the browser. This is the error:

RuntimeError: null function or function signature mismatch
    at std::__2::shared_ptr<proof_system::plonk::proving_key> proof_system::plonk::initialize_proving_key<proof_system::UltraCircuitBuilder_<barretenberg::field<barretenberg::Bn254FrParams>>>(proof_system::UltraCircuitBuilder_<barretenberg::field<barretenberg::Bn254FrParams>> const&, barretenberg::srs::factories::CrsFactory<curve::BN254>*, unsigned long, unsigned long, proof_system::CircuitType) (02646f1a)
    at proof_system::plonk::UltraComposer::compute_proving_key(proof_system::UltraCircuitBuilder_<barretenberg::field<barretenberg::Bn254FrParams>>&) (02646f1a)
    at proof_system::plonk::UltraComposer::compute_verification_key(proof_system::UltraCircuitBuilder_<barretenberg::field<barretenberg::Bn254FrParams>>&) (02646f1a)
    at acir_proofs::AcirComposer::verify_proof(std::__2::vector<unsigned char, std::__2::allocator<unsigned char>> const&, bool) (02646f1a)
    at acir_verify_proof (02646f1a)
    at BarretenbergWasm.call (432.60f9453cd29313c1.js:189:40)
    at callback (432.60f9453cd29313c1.js:359:48)

I created this branch on the noir-starter so anyone can replicate.

@Savio-Sou do you know if this issue being tracked elsewhere?