Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof verification is true for IDCommitment not in merkle tree? #57

Closed
richard-ramos opened this issue Oct 1, 2022 · 2 comments
Closed
Assignees
Labels
track:zerokit Zerokit track (Applied ZK/Explorations)

Comments

@richard-ramos
Copy link
Member

Is it possible that verify (https://github.com/vacp2p/zerokit/blob/master/rln/src/public.rs#L211-L228) returns Ok(true) due to a difference in architecture (32bits vs 64bits) ?
I'm confused, because I see it returning true for an IDCommitment that does not belong to the merkle tree
In rln-wasm I commented this line: https://github.com/vacp2p/zerokit/blob/master/rln-wasm/src/lib.rs#L167
and then executed cargo make test

@richard-ramos richard-ramos added the track:zerokit Zerokit track (Applied ZK/Explorations) label Oct 1, 2022
@s1fr0
Copy link
Contributor

s1fr0 commented Oct 1, 2022

If the proof was correctly generated for that id_commitment, then is expected behavior from verify (not from verify_rln_proof).

If you look at the circuit, the root is computed from the id_commitmentMerkle proof passed to it, which do not carry any tree information, except the path for id_commitment. Hence the global tree state cannot be verified by the ZK proof alone. What you do is to see what is the expected root from the path and check against the root of the tree stored in the RLN object, and this is what verify_rln_proof does along with checking the other public outputs y and nullifier (implicitly checked by circuit wires if x is correct)

zerokit/rln/src/public.rs

Lines 327 to 332 in a5aa4e8

let x = hash_to_field(&signal);
Ok(verified
&& (self.tree.root() == proof_values.root)
&& (x == proof_values.x)
&& (proof_values.rln_identifier == hash_to_field(RLN_IDENTIFIER)))
}
.

Note that if you generate proof_values from a RLN witness through proof_values_from_witness, verify will always succeed if the proof was generating using prove with input that witness.

Ideally, for a user that wants to publish a message should suffice to send: message, zkproof, nullifier, epoch. All the other (proof) values, i.e. y, root, x, rln_identifier can indeed be computed from the RLN object state (and you can then avoid to use verify_rln_proof which checks instead all proof value provided against the RLN state object, i.e. the tree root).

The reason for such two (prove, verify), (generate_rln_proof, verify_rln_proof) pairs of procs is because we want a construction that we can port to other modules. The abstraction is that you have a witness that is passed to prove that generates a proof which is then verified by verify against some proof_values.
This generic construction works regardless of what the zerokit zk module effectively does, since it does not any application specific things and is useful to test if the circuit interface is working correctly.
Once it works fine, we implement in generate_module_proof and verify_module_proof their module-specialized version with additional checks and so on.

Hope this clarifies and I hope I'm not overseeing a bug!

@richard-ramos
Copy link
Member Author

Thank you for this detailed information! It indeed clarifies why I was seeing the behavior I described with verify, which I mistakenly exposed in wasm instead of verify_rln_proof. In this PR #58 I'm using the correct function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
track:zerokit Zerokit track (Applied ZK/Explorations)
Projects
None yet
Development

No branches or pull requests

3 participants