noir-lang / noir

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

Solidity on-chain verification fails even though verification ass with bb.js #2294

Closed tomoima525 closed 1 year ago

tomoima525 commented 1 year ago

Aim

Expected Behavior

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

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

Savio-Sou commented 1 year ago

@critesjosh could you help boil the example code down into a minimally reproducible example?

Suspecting constraint count might not be the actual underlying reason here. Would be good to verify that.

critesjosh commented 1 year ago

Installing the latest noir nightly generates a new, different Solidity verifier contract for the same noir program. in order to verify the same program, I have to generate a new proof using this version (proofs generated with the stable 0.9.0 release dont work).

additionally, it seems like this new verifier contract is not compatible with proofs generated with the latest version of bb.js (0.3.6). Hopefully resolving this will fix the issue

tomoima525 commented 1 year ago

Updated the solidity file with Noir 0.10.3 but the result was the same

tomoima525 commented 1 year ago

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

I tested other patterns.

Assertion 1 & 3 => Fails Assertion 2 & 3 => Fails

So when the merkle root check is combined with other assertions, it fails... 🤔

tomoima525 commented 1 year ago

Some interesting experiments:

I changed my noir circuit a bit and saw how many circuit sizes could cause this issue.

Experiment 1: Assertion 1 3 = 7225 3 = 21675 circuit size Result: PASS (Solidity works)

Experiment 2: Assersion 1 3 + Custom assertion = 7225 3 + 361 = 22036 circuit size

    for i in 0..90 {
    assert(age == 18);
    }

Result: PASS

Experiment 3: Assertion 2 + Assertion 3 = 22092 circuit size Result: FAIL

Experiment 4: Assertion 1 3 + Assertion 2 = 7225 3 + 2776 = 24451 circuit size Result: FAIL

Result

If the circuit size passes the value between 22036 and 22092 Solidity file starts to fail.

critesjosh commented 1 year ago

did you try any circuits above 22092 with different logic? or just modifications of your circuit?

tomoima525 commented 1 year ago

Just modifications

image
critesjosh commented 1 year ago

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?

critesjosh commented 1 year ago

After modifying the web component, I was able to get a circuit of size 65413 verified on chain. The verification using bb.js is what is failing in the error i describe above.

So I don't think the size is what is causing your circuit verification to fail on-chain. Here is the code that is working for me.

Savio-Sou commented 1 year ago

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

This is the best tracking issue atm afaik.

The verification using bb.js is what is failing in the error i describe above.

Not sure if I follow if this is a Solidity verifier bug or a bb.js verification bug, but either way that means this is more likely a barretenberg problem.

@critesjosh would you like to start an Issue on https://github.com/AztecProtocol/aztec-packages/issues with your latest findings (cc @rahul-kothari).

If it turns out to be Solidity verifier specific, we can also source help from @LHerskind.

critesjosh commented 1 year ago

Solidity verifier is working fine, its just bb.js.

I created an issue here https://github.com/AztecProtocol/aztec-packages/issues/1845

tomoima525 commented 1 year ago

Thanks for the update @critesjosh !

I tried the above circuit on ts-node using https://github.com/tomoima525/noir-starter/pull/1 but it failed with the same error. Do you know any difference between the ts-node version and the browser version? I think it's okay as long as it works on the browser but the inconsistency between platforms can become a big issue later on

I changed the code like this and the verifier contract is working now. So yeah I guess it's not related to the circuit size ... 🤔

fn main(x : pub u32) {
    let mut z = x; 
    for i in 0..5000{
        z = z + 1;
        assert(z > x);
    }
}
tomoima525 commented 1 year ago

Here is the code that is working for me.

Also I wonder how the circuit worked as it doesn't provide public inputs in the circuit, but in this code, you provided the first 32bits of the public inputs which I believe should fail?

tomoima525 commented 1 year ago

Let's hope that bb.js update will resolve the issue with my original circuit 🙏

jat9292 commented 1 year ago

Hello @tomoima525 I stumbled on a very similar issue, I also thought at first that this was caused by bb.js but I am not sure anymore. I noticed that the verifier smart contract code (for a same fixed circuit) changed between nargo 0.10.3 and nargo 0.10.5 and unexpectedly, as I thought this was a problem in bb.js, upgrading to nargo 0.10.5 solved this very same issue. See similar issue

LHerskind commented 1 year ago

I noticed that the verifier smart contract code (for a same fixed circuit) changed between nargo 0.10.3 and nargo 0.10.5

Do you have the verifier code lying around for this, I don't think much should have changed on those in months so would be interested in seeing the diff if other than just vk.

jat9292 commented 1 year ago

I noticed that the verifier smart contract code (for a same fixed circuit) changed between nargo 0.10.3 and nargo 0.10.5

Do you have the verifier code lying around for this, I don't think much should have changed on those in months so would be interested in seeing the diff if other than just vk.

I just pushed it on a new branch here : https://github.com/jat9292/bbjs-bug-minimal-example/tree/compare-nargo-10-3-vs-10-5/contract/bbjs you can see both versions, one generated via nargo 0.10.3 and the other with nargo 0.10.5

Output of the diff :

1c1
< // Verification Key Hash: 56c0033c7b88d37f038f03eed5ece7197e6c56da0c770906b5ca146219f4e362
---
> // Verification Key Hash: 2b951f2ad8c30e9c6fd1df64cf0c26a662589d7c8cd9cfa5066de177b8dddd99
8c8
<         return 0x56c0033c7b88d37f038f03eed5ece7197e6c56da0c770906b5ca146219f4e362;
---
>         return 0x2b951f2ad8c30e9c6fd1df64cf0c26a662589d7c8cd9cfa5066de177b8dddd99;
17,32c17,32
<             mstore(add(_vk, 0x80), 0x058d2d96844efd71d1ea79dc01cf5794bfa80a7666be31f8f3b504eb0f9c1b9e) // vk.Q1.x
<             mstore(add(_vk, 0xa0), 0x21522d2c085a459b9fa71435489397f907f75252e400c9a3a975b2074558e382) // vk.Q1.y
<             mstore(add(_vk, 0xc0), 0x26ae7d13e55a1917f7aca910c36e48e15c3c35879f351a3fc001de83603994b4) // vk.Q2.x
<             mstore(add(_vk, 0xe0), 0x10bfa8463b6359772e9d1918c28f37146e05125f522a3751eb490351c4bdd1b0) // vk.Q2.y
<             mstore(add(_vk, 0x100), 0x27ffe3fa9dc1949a99b4619ae2026266213829ebbeaa026dc2055d1a99322d36) // vk.Q3.x
<             mstore(add(_vk, 0x120), 0x0a125f3e228005f1944ce6c3bf014bfaa5b3463614534d4d8cc4cbf5236a0429) // vk.Q3.y
<             mstore(add(_vk, 0x140), 0x1998e4bbdb2bfc7e4a1d41dd70d44543385bcccf1e8779176ff0322d88a04398) // vk.Q4.x
<             mstore(add(_vk, 0x160), 0x28701822301d544f74c69f01ef1bd3812dda8505172bad4ea0588c8d26a94e74) // vk.Q4.y
<             mstore(add(_vk, 0x180), 0x2911326f874fd6f495eff81c9d2b9c98097fd27da0fb8e66135ec73f6d987b4f) // vk.Q_M.x
<             mstore(add(_vk, 0x1a0), 0x0fe7e7c1012c7dc6c5bb1d5e0166110064cf2ac98eb5ab3a0d27b47b3daa2c33) // vk.Q_M.y
<             mstore(add(_vk, 0x1c0), 0x01991a8a75f79b9a8ade5d6d7220732e287893ff974ba903d1e5f085909ab3f0) // vk.Q_C.x
<             mstore(add(_vk, 0x1e0), 0x2a54ef87c8dc13619f43381f9b7be2f177019e7c403ad3a156f1ce50de1b5c08) // vk.Q_C.y
<             mstore(add(_vk, 0x200), 0x06957128f5ef3e69a11aadb549f5c5184fb6cf8c127c29a746603784d74597d8) // vk.Q_ARITHMETIC.x
<             mstore(add(_vk, 0x220), 0x076af2ef4420a18f36f5239ba998419484505032ce532e3fb6ecf6b2f32b2aaf) // vk.Q_ARITHMETIC.y
<             mstore(add(_vk, 0x240), 0x02051bb8f4b013b3a885871e9dd0fe11a26004e5463e906d863c8a2ca27c256e) // vk.QSORT.x
<             mstore(add(_vk, 0x260), 0x1211d58150ea2fc83d924b60eb7df99321071620bd1e6ab422f671fa5f38af51) // vk.QSORT.y
---
>             mstore(add(_vk, 0x80), 0x0fe0cf1b541c14fc5349c8c822d4c7b5e872dec36ce9c752d08fc784e92df9af) // vk.Q1.x
>             mstore(add(_vk, 0xa0), 0x2b10d6a43ae32cb93ef903f8c2162db59ab562c41173e37b88b6ad4e5327fd21) // vk.Q1.y
>             mstore(add(_vk, 0xc0), 0x0221404bff9920f6f6b3cb8da1583fab51db8600f08f0c6070f4f697e9c19f48) // vk.Q2.x
>             mstore(add(_vk, 0xe0), 0x2dde1ab639bd4feeb8caae1e136aec34545be591181bb27506e98e90a4cd0cf7) // vk.Q2.y
>             mstore(add(_vk, 0x100), 0x16f8b651166eba8bfca6f8fe9567af685321f54bcf975c1ac7d343861126cdaf) // vk.Q3.x
>             mstore(add(_vk, 0x120), 0x1f376c5475d7c9fc0a70bde6ac0d03dc52b10e9872e7f40725a1852962a7dee6) // vk.Q3.y
>             mstore(add(_vk, 0x140), 0x2cfd195398c36559e8a8a9cc66fcaa66a324360f1a426f40f4616e64b3c3c4cf) // vk.Q4.x
>             mstore(add(_vk, 0x160), 0x0f501ba520a88956d9b194d94b75d359c08191cebdf44dd835bf7c0b5ea5e0d6) // vk.Q4.y
>             mstore(add(_vk, 0x180), 0x1f99ab321383bab6bcd6066e1d4a7b95459d2747117405e196ccaebcba1baf91) // vk.Q_M.x
>             mstore(add(_vk, 0x1a0), 0x0d7d83510f2b89a66cddb5443badfd9edc0e50d1edf99b7fa6fb114cd078a3b0) // vk.Q_M.y
>             mstore(add(_vk, 0x1c0), 0x0a2c5ca9d72218a88ba274ee2ebe5e3ee2f09cd909c2db7f171b5438a888c667) // vk.Q_C.x
>             mstore(add(_vk, 0x1e0), 0x218c5c7b9b1cf92825bcb2cac55d93688393d549b69c5d59708c63007915dc76) // vk.Q_C.y
>             mstore(add(_vk, 0x200), 0x1c9a04bb37dfffa6cf5416dcaae3ae6480cfe936b454c02bbbb2dbff0136cee2) // vk.Q_ARITHMETIC.x
>             mstore(add(_vk, 0x220), 0x2bb51262ccf024b2177b780d29f951d1180eb509504fad9d08da2c0e276d06e9) // vk.Q_ARITHMETIC.y
>             mstore(add(_vk, 0x240), 0x2bdd55cdf544f4551ae8989c4eae79d8f0c9a06c1f2004441c85d95224b8cd6e) // vk.QSORT.x
>             mstore(add(_vk, 0x260), 0x026f3f477fd783ce6d5881c40de0f94021667d13497483023739942384115e33) // vk.QSORT.y
37,44c37,44
<             mstore(add(_vk, 0x300), 0x2a5fb4aca0d954dd8def70e6c829c0f5be3cbb710b97a5dd24d773589e57ee2d) // vk.SIGMA1.x
<             mstore(add(_vk, 0x320), 0x05ce27117bcb0139d51b9c0dcfa707fd36933f87478aaba14e5f5f1df9870e9f) // vk.SIGMA1.y
<             mstore(add(_vk, 0x340), 0x09bb09e35142de5d4c9b8c9581b3431dbeefbd4e85baea07e2070ed3d4f1970b) // vk.SIGMA2.x
<             mstore(add(_vk, 0x360), 0x2015a519f73e3d74d2d3c60f5ebb721ccd1c42a860806f6886af681b257637b9) // vk.SIGMA2.y
<             mstore(add(_vk, 0x380), 0x0edbf7a493e782fbbb7d9e4377cad4206016e327d1ca7ceba9a1b1165e069f72) // vk.SIGMA3.x
<             mstore(add(_vk, 0x3a0), 0x234593aeb40273c0c5d0cf8c65b38392b5b8efaa2685963d6b901b79ed2dc2c8) // vk.SIGMA3.y
<             mstore(add(_vk, 0x3c0), 0x1805e0d3fa123cb706690c421a1557cd72c48463590a2dc0e63656f1bdf26106) // vk.SIGMA4.x
<             mstore(add(_vk, 0x3e0), 0x0a3e5dbd9c627ff26f91d2aff915dd2832c16ea3456527edf6c912a0f9a0edcc) // vk.SIGMA4.y
---
>             mstore(add(_vk, 0x300), 0x0468df4907d56f150ae8d8008841bca19acca9669e2af225fb92874f5da29230) // vk.SIGMA1.x
>             mstore(add(_vk, 0x320), 0x200b5ebe358975ba33dcc1b4cbf186fdff23b1a88cabca21258a5332361e54c9) // vk.SIGMA1.y
>             mstore(add(_vk, 0x340), 0x0ab414db5b312392f89c89372d6a98e674cb0daaa467a2749456b83f8385b7ea) // vk.SIGMA2.x
>             mstore(add(_vk, 0x360), 0x231bb22c3fd064230b06a3b16088ec29d4da4d913c140cc2a0a69c534cd0ecd8) // vk.SIGMA2.y
>             mstore(add(_vk, 0x380), 0x00636bbca64afea046eb7954008fe140ad9d0a061cf560c09699cb508dcb4145) // vk.SIGMA3.x
>             mstore(add(_vk, 0x3a0), 0x07f6e3a33bfba310d75dfbc498e6745ed75e59a00656b99172835bda96d05ee6) // vk.SIGMA3.y
>             mstore(add(_vk, 0x3c0), 0x2b60590dd8d5eac39051f83bff9b5c4d4c7093609a724b4c9f398f89a99f4510) // vk.SIGMA4.x
>             mstore(add(_vk, 0x3e0), 0x15f170f7f028ff73fdc73022ca685f967b13d450128ddc5a62ec0c0926bcf472) // vk.SIGMA4.y
55,62c55,62
<             mstore(add(_vk, 0x540), 0x030bdc5ddd5d329c901a2249effa8866f5b4c6f06e7b9e213e4c7e3851c0090a) // vk.ID1.x
<             mstore(add(_vk, 0x560), 0x22297c47e82c9ea7e1ec9374969337556968244c17223441dfe8753c1f83930e) // vk.ID1.y
<             mstore(add(_vk, 0x580), 0x2f194668067fda5f01e74870f2474082e65796799a6d1f45557c9a5fd3f2df31) // vk.ID2.x
<             mstore(add(_vk, 0x5a0), 0x2c7716dfdd83ab421cb94504eac9467738401b718aea745f910e96b5ad3212bf) // vk.ID2.y
<             mstore(add(_vk, 0x5c0), 0x0567f0d5420bacfa17b34998ddff21d91d4539e53ba2c9c7a3f6b071e88c3585) // vk.ID3.x
<             mstore(add(_vk, 0x5e0), 0x2f5471417429570f6268565f2733bce5dd900a4a7962d54412c632727aa1edb8) // vk.ID3.y
<             mstore(add(_vk, 0x600), 0x1853b45ca80f3abf163f764d5bfc2ed297b4ecd53a4abed3f018fd944d70acef) // vk.ID4.x
<             mstore(add(_vk, 0x620), 0x1b06a4b9eb80f545d5f4b6491787ff10e27e674a3dae2a91faa286932347653e) // vk.ID4.y
---
>             mstore(add(_vk, 0x540), 0x02536b4e5b114885afc7a7548e53f8346671257b7c1d1855f4fdbdf5aed3b1b2) // vk.ID1.x
>             mstore(add(_vk, 0x560), 0x10adfe7f93b3b1e067bef6f26b2751325d62c64f36b6f20ec48588ec4abce80b) // vk.ID1.y
>             mstore(add(_vk, 0x580), 0x13bf791ca08dc98dff61eb9cdaac4c60a75f2edf0c11591bb6f5cdfab93d7fe2) // vk.ID2.x
>             mstore(add(_vk, 0x5a0), 0x1d03866028d293ebb9ae096d6d08d89a0ec5c8c4182314a8bb41cf25515cc098) // vk.ID2.y
>             mstore(add(_vk, 0x5c0), 0x0793018304f71b55dfbd2b3c87b2e5449c824045add3e943e03e81a2f64a2f26) // vk.ID3.x
>             mstore(add(_vk, 0x5e0), 0x0b21b74df7b13754d38662b7295a7b5296b613b3c6ec85e211d951e3429a31fa) // vk.ID3.y
>             mstore(add(_vk, 0x600), 0x0209afacf58ea1f4b626d4a2eff2298d3042c727fac5fd6cec724ba0aecc522a) // vk.ID4.x
>             mstore(add(_vk, 0x620), 0x2f94cb9eaee45486acdbbfe36c28ef26438c4abba89b8408034c7cd676a215a8) // vk.ID4.y
LHerskind commented 1 year ago

I just pushed it on a new branch here

Ah cool. Its only the vk differing (which is based on the circuit and output from bb), so with the same circuit if that one is different that is due to noir compiler updates or bb, so makes sense if the issue came from bb.js

tomoima525 commented 1 year ago

@jat9292 this is awesome!

I updated Noir 0.10.5 then I see this error when calling api.acirGetCircuitSizes from barretenberg API (0.3.6). Did you change bb.js or any other related library version?

file:///Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@aztec+bb.js@0.3.6/node_modules/@aztec/bb.js/dest/node/barretenberg_wasm/barretenberg_wasm.js:169
            return this.exports()[name](...args) >>> 0;
                                       ^
Error [RuntimeError]: unreachable
    at abort (wasm://wasm/02646f1a:wasm-function[11571]:0x422819)
    at throw_or_abort(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) (wasm://wasm/02646f1a:wasm-function[94]:0x380e6)
    at Circuit::Circuit::bincodeDeserialize(std::__2::vector<unsigned char, std::__2::allocator<unsigned char>>) (wasm://wasm/02646f1a:wasm-function[2213]:0x12774b)
    at acir_format::circuit_buf_to_acir_format(std::__2::vector<unsigned char, std::__2::allocator<unsigned char>> const&) (wasm://wasm/02646f1a:wasm-function[2212]:0x12746a)
    at acir_get_circuit_sizes (wasm://wasm/02646f1a:wasm-function[2251]:0x12835f)
    at BarretenbergWasm.call (file:///Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@aztec+bb.js@0.3.6/node_modules/@aztec/bb.js/dest/node/barretenberg_wasm/barretenberg_wasm.js:169:40)
    at callback (/Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/comlink@4.4.1/node_modules/comlink/dist/umd/comlink.js:109:52)
    at MessagePort.l (file:///Users/tomoima525/workspace/zkp/noir-starter/with-foundry/node_modules/.pnpm/@aztec+bb.js@0.3.6/node_modules/@aztec/bb.js/dest/node/barretenberg_wasm/node/node_endpoint.js:11:21)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:737:20)
    at exports.emitMessage (node:internal/per_context/messageport:23:28)
jat9292 commented 1 year ago

I am able to use acirGetCircuitSizes without any issue for my circuits : https://github.com/jat9292/Private-token/blob/main/utils/proof_utils.js#L33 I am using @aztec/bb.js 0.3.6 and @noir-lang/acvm_jsgit+https://git@github.com/noir-lang/acvm-simulator-wasm.git#b9d9ca9dfc5140839f23998d9466307215607c42 , as per documentation Btw here is my most complex circuit : https://github.com/jat9292/Private-token/blob/main/circuits/transfer/src/main.nr I noticed it had 24 (Gaffine=2 Fields) inputs among which 20 are public, while yours had a total of 28 inputs but only 4 of which were public, so I do not now if this explains some added complexity which could explain the bug (?)

tomoima525 commented 1 year ago

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