iden3 / snarkjs

zkSNARK implementation in JavaScript & WASM
GNU General Public License v3.0
1.75k stars 420 forks source link

Way to verify vkey for a circuit? #473

Open Stentonian opened 6 months ago

Stentonian commented 6 months ago

Hi, I am wondering how the verifier can check that the proof they are verifying corresponds to a particular circuit. Let's assume we are using groth16.

The bare minimum the verifier gets from the prover is the vkey, the public inputs, and the groth16 proof data. But how is the verifier to know that the proof they are verifying corresponds to a particular circuit? They could be verifying any old computation.

If the prover were to give the verifier the proving key then the verifier could use the following commands to do the check:

# first verify the zkey
snarkjs zkey verify circuit.r1cs ptau_file final.zkey

# then generate the verification key, and check it equals the one given by the prover
snarkjs zkey export verificationkey final.zkey vkey.json

From my understanding it does not matter if the proving key is known by the verifier i.e. it does not leak any information about the witness. Is this correct?

The problem with this approach is that the snarkjs zkey verify command takes about as long as generating the zkey. So for large circuits this quickly becomes unrealistic for the verifier to do.

OBrezhniev commented 4 months ago

Hi! Yes, you can safely share proving key with the verifier. It doesn't leak any knowledge about the witness. It's up to the verifier to verify zkeys and vkeys, or get them from a repository / public registry where someone else has done that and just trust it.

Stentonian commented 3 months ago

Is there a faster approach?

The problem with this approach is that the snarkjs zkey verify command takes about as long as generating the zkey. So for large circuits this quickly becomes unrealistic for the verifier to do.

If there is no current faster approach, it might be useful to research one. I can't imagine it would be too difficult to figure out so maybe it's worth me having a go at figuring it out?

For more modern snarks.. is there even an issue with computational time? Or is it just g16?

OBrezhniev commented 1 month ago

Usually verifier would get the verification key from a trusted source and keep it.

If source is not trusted or just to be sure verifier may check that it corresponds to a specific circuit, but it's a one time procedure and after that there's no need in zkey (and r1cs) file on verifier side.

Then verifier just verifies proofs with the verification key stored locally.