Consensys / anonymous-zether

A private payment system for Ethereum-based blockchains, with no trusted setup.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transfer failing with reason Recovery failure for B^x * A.

naddison36 opened this issue · comments

I've trying the example against a local Geth node but the transfer from Alice to Bob keeps failing in ZetherVerifier with reason Recovery failure for B^x * A.

Any ideas on what I'm doing wrong?

I can move what I'm doing into a public repo if it helps, but I'm essentially following the example of Alice depositing into the Anonymous Zether contract and then transferring to Bob.

As this is the 1st revert check in verification function, it could fail if you are pass wrong params during proof generation. Most likely cause of this would be different epochs during proof generation and verification AFAIK. I have encountered this many times while testing and Most of it was due to mismatch in epochs.

Thanks for your help @panghalamit

My proofs are taking over 400 seconds to create on my laptop so when I use and epoch of 6 second, the verification fails.
It's taking over 60 seconds just to process this line in the Zether proof generator
https://github.com/jpmorganchase/anonymous-zether/blob/master/packages/anonymous.js/src/prover/zether/zether.js#L63

My laptop is a MacBook Pro with a 2.7 GHz Intel Core i7 processor

Setting my epoch to 500 worked. I can now send a shielded transfer.

My proofs are taking over 400 seconds to create on my laptop

Good Lord, seriously? for which anonset size? This is way, way too much—shouldn't be this long. Let's figure out what's going on.

@naddison36

you're running this in NodeJS, yes? which version...? which calls exactly are you making to anonymous-zether, i.e. how are you invoking it? can you also report your bn.js and elliptic.js versions? thanks.

also, importantly—try running this on your host box, not on a guest virtual machine.

I was running node v10.15.2. Dependency versions are:

  • bn.js@4.11.8
  • elliptic@6.5.1

It takes my MacBook pro around 60 seconds to run this line in zether.js proof.s = params.commit(sL, sR, rho);
https://github.com/jpmorganchase/anonymous-zether/blob/master/packages/anonymous.js/src/prover/zether/zether.js#L63

It takes about 30 seconds each to run the following two for loops in the commit. These are looping over an array of 64 entries
https://github.com/jpmorganchase/anonymous-zether/blob/master/packages/anonymous.js/src/prover/algebra.js#L40
https://github.com/jpmorganchase/anonymous-zether/blob/master/packages/anonymous.js/src/prover/algebra.js#L43

I've also tried node v12.11.1 and the proof generation was 10 seconds slower at 384 compared to 374 seconds of node 10. But the times vary +- 10 seconds or both versions.

These tests were done with no decoys: const receipt = await aliceClient.transfer("Bob", 9);

this is bonkers. are you on running on an honest, i.e. host machine?

could you try some experiments—e.g., navigate to anonymous.js/src, open up a node console, and run:

const { GeneratorParams, FieldVector } = require('./prover/algebra.js');
const utils = require('./utils/utils.js')
const bn128 = require('./utils/bn128.js')
var params = new GeneratorParams();
params.extend(64);
var gExp = new FieldVector(Array.from({ length: 64 }).map(bn128.randomScalar));
var hExp = new FieldVector(Array.from({ length: 64 }).map(bn128.randomScalar));
params.commit(gExp, hExp, bn128.randomScalar());

for me, the last command takes just around 300 ms.

The last command in the above take just under 400 ms on my machine. That's a big improvement on a minute!

I was running the transfer in a Jest test on WebStorm. I'll experiment to see if that makes any difference.

The good news is I can replicate the problem. If I run the below Jest test written in TypeScript on WebStorm the last line takes 56 seconds

test("commit test", () => {
  const { GeneratorParams, FieldVector } = require("../prover/algebra.js");
  const bn128 = require("../utils/bn128.js");
  const params = new GeneratorParams();
  params.extend(64);
  const gExp = new FieldVector(Array.from({ length: 64 }).map(bn128.randomScalar));
  const hExp = new FieldVector(Array.from({ length: 64 }).map(bn128.randomScalar));

  const startTime = new Date();
  params.commit(gExp, hExp, bn128.randomScalar());
  const endTime = new Date();
  console.log(`End ${endTime - startTime}`);
});

Now to narrow in on what's causing the problem

The problem is Jest. The exact same JS code in a Jest test takes 60 seconds compared to 396 ms outside Jest.
I'm using Jest 24.9.0
I'll play around with the Jest settings. If no luck I'll raise a Jest issue as this is crazy.
This is definitely not an Anonymous Zether issue so I'll close this issue.

I've raised a Jest issue jestjs/jest#9006

Just to close this off for anyone else looking at this, adding the following Jest config gave me a 100x speed improvement when running the transfer proof in Jest. It now only takes 4 seconds compared to 400 seconds without this Jest config

	extraGlobals: ["Math"]

@naddison36 wow. Big thanks for doing this digging, and glad we've gotten everything worked out!