Open yushihang opened 2 months ago
@yushihang thanks for raising the questions here and sharing your analysis.
Yes. I agree a local check will catch the invalid proof earlier. We should add those checks in.
Separately, I had a chat with @jimthematrix on this issue, the concurrency issue in the js witness calculator is something he's already aware of.
https://github.com/hyperledger-labs/zeto/issues/84 has also been raised to cover concurrent proof generation exploration in golang SDK.
Hi @Chengxuan
Thank you for your response and detailed explanation.
In our testing, we discovered a solution that might solve the issue of “Wrong witness data generated during concurrent requests using promises".
Whether this solution is suitable for all scenarios needs to be confirmed after a review by the Iden3 team. Therefore, I tried to submit a pull request here: https://github.com/iden3/circom/pull/299.
In the meantime, we will also try using the solution you provided to address the issue.
Thanks very much.
Thanks to @Chengxuan for the help during our discussion this afternoon.
After the discussion, I found that the main reason for the verification failure of the ZKProof generated concurrently for transfers on the contract side is related to the
calculateWTNSBin()
function.This function is provided by the
witness_calculator.js
file, which is generated after compiling the circom file. It reads the witness data from the globally unique WebAssembly instance’s SharedRWMemory functions,which are not promise safe.When using promises for concurrent ZKProof generations, this may lead to multiple different requests returning the same witness value, resulting in identical (and incorrect) contents in the generated public.json and proof.json.
I noticed that @Chengxuan has already submitted a PR https://github.com/hyperledger-labs/zeto/pull/79 to address this issue 👍.
And from the perspective of better checking and protection, is it necessary to validate whether the input values of the circuit correspond to the data in the public signals, after the prove() function call is completed and the public signal is generated?
For example, we could check whether nullifiers[0] is equal to publicSignal[n], and so on.
This may allow us to discover this issue with the ZKProof before it is sent for verification on the contract side.”