o1-labs / o1js

TypeScript framework for zk-SNARKs and zkApps

Home Page:https://docs.minaprotocol.com/en/zkapps/how-to-write-a-zkapp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error `to_affine_exn: Got identity` when using public key retrieved from on-chain state

garethtdavies opened this issue · comments

I am using an on-chain public key variable in a zkApp for use in signature verification.

The public key is stored onchain and retrieved via let oraclePublicKey = this.oraclePublicKey.get();

However, when using oraclePublicKey it errors with:

/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:7565
         throw err;

Error: to_affine_exn: Got identity
    at failwith (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:75528:50)
    at to_affine_exn (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:160233:36)
    at caml_call1 (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:7610:28)
    at scale$3 (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:337731:34)
    at /workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:420296:49
    at caml_call_gen (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:2081:17)
    at Object.scale (/workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/_node_bindings/snarky_js_node.bc.cjs:3651:16)
    at Signature.verify (file:///workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/lib/signature.js:126:23)
    at DelegationOracle.verify (file:///workspace/zkAppPool/oracle/build/src/DelegationOracleVerifier.js:46:42)
    at file:///workspace/zkAppPool/oracle/node_modules/snarkyjs/dist/node/lib/zkapp.js:152:32

If I simply override the oraclePublicKey with the following, it works just fine:

oraclePublicKey = PublicKey.fromBase58("B62qphyUJg3TjMKi74T2rF8Yer5rQjBr1UyEG7Wg9XEYAHjaSiSqFv1");

Code example here, with the above hack: https://github.com/garethtdavies/zkAppPool/blob/5176a050c469ebab978fcf9631c7ac6bfd590970/oracle/src/DelegationOracleVerifier.ts#L44

Could it be that the public key is not initialized yet, so it's all zeroes? That's what the error message sounds like

Do you mean it's not on-chain yet? It is stored in this account: B62qmLWZfcbqrQPMky44w6K6Myj9aydbHKE5fG2N6wrXxFbkfEUWdRM

You can see there the fields are 13117991216867267972578094433946611068215850158296483053051446309883779846074 and 0 . Manually decoding that via https://github.com/garethtdavies/zkAppPool/blob/main/oracle/src/debug-events.ts gives B62qphyUJg3TjMKi74T2rF8Yer5rQjBr1UyEG7Wg9XEYAHjaSiSqFv1 as expected.

Query to get on-chain state:

{
  account(publicKey: "B62qmLWZfcbqrQPMky44w6K6Myj9aydbHKE5fG2N6wrXxFbkfEUWdRM") {
    publicKey
    zkappState
  }
}

I understand the error now - it's because of running stuff multiple times, the first one with fake values. We should address this soon

So the goal would be to run it the first time in an environment where assertions don't throw

@garethtdavies you could use the following workaround for now:

You can pass in the oraclePublicKey as an additional parameter to your method, to avoid .get() which gives you the wrong result. Then, to check that it matches the on-chain one, you can do this.oraclePublicKey.assertEquals(oraclePublicKey); as before.

So this would be the diff in pseudo code

+ // oraclePublicKey gets passed in as argument
- let oraclePublicKey = this.oraclePublicKey.get();
this.oraclePublicKey.assertEquals(oraclePublicKey);

Oh! An even simpler workaround would be to warm the cache before doing the transaction:

await Mina.fetchAccount(zkAppAddress);

let tx = await Mina.transaction(...)