Privacy, Self-Sovereignty

Notes on ZK research at Guild.xyz (WIP)

0xPARCarrow-up-right (Program for Applied Research in Cryptography) is actively developing methods to prove public key derivation from secret keys, verifying ECDSA signatures, etc. in zk snarks. They use circomarrow-up-right for this which is a fairly low level language for writing zk snark circuits. Problem is, that these circuits contain millions of constraints and require a significant amount of computational resources (tens of gigabytes of RAM). StealthDroparrow-up-right is a prototype implementation making use of such circuits.

We are looking for alternative solutions (more lightweight) to prove that someone has the corresponding private key for a given public key without disclosing their public key. So far, ring signaturesarrow-up-right are quite promising, as our usecase is exactly that we need to prove that we are part of a group of addresses that hold some kind of tokens. Through Balancyarrow-up-right we are able to construct such address groups publicly. An entry-level (mathematical) introduction of how ring signatures work can be found in Monero's handbookarrow-up-right. There is a Rust repoarrow-up-right that implements the math in this handbook which helped constructing our prototype.

There are some further practical issues to solve though. StealthDrop uses ECDSA verification circom scriptsarrow-up-right that are way more bulkier than just proving secret/public key derivation because there's no way to extract the bare private key from a wallet like Metamask. You can read an interesting twitter thread about this herearrow-up-right.

Ring signatures also make use of direct access to the secret key when generating the proof. However, there might exist a solutionarrow-up-right where EDCSA signature verification happens via masking the public key via Pedersen commitments. The whitepaper describing the algorithm can be found herearrow-up-right, and it builds on Groth's seminal paperarrow-up-right. The advantage of this method is that it doesn't seem to require direct access to the user's private key. Thus, the user only signs a message (using Metamask for example), commits a Pedersen commitment masking their public key and generates the proof based on these values.

Proposed flow

  • I. Balancy generates a list of eligible (Ethereum) addresses for a given guild.

  • II. Users whose address is found in this array (ring) may provide a ring signature that proves they are eligible to enter the guild.

  • III. The guild backend receives the ring signature (proof) along with the ID of the guild and (Discord) ID of the user and verifies the proof.

Last updated

Was this helpful?