neo-project / proposals

NEO Enhancement Proposals
Creative Commons Attribution 4.0 International
136 stars 113 forks source link

Create and standardize a non-native registry contract for SNARK verification parameters #181

Open EdgeDLT opened 2 weeks ago

EdgeDLT commented 2 weeks ago

In most blockchain ecosystems that use zero-knowledge proofs, a zkdApp developer will often deploy its own verifier contract which hardcodes circuit-specific parameters used for proof verification. A new circuit (even a new version of the same circuit) means a new verifier to be deployed. Lots of time, GAS, and plenty of room for things to go wrong.

ZKP support on Neo N3 is still nascent, but we are likely going to follow along the same tracks and have a chance to get ahead of the problem.

My suggestion is that we design and standardize a registry contract as a non-native utility, akin to NeoNS. It would store circuit-specific verification data (the four curve points and independent commitments) for a given circuit. This data would be retrieved using a circuit identifier and version number.

In N3 ZK tooling, such as NeoGo's zkpbinding package, after a circuit has been setup and verifier/prover keys generated, developers should be prompted to submit the verification elements to the registry, rather than pay to deploy another copy of the verifier logic with this information hardcoded (e.g. as currently in zkpbinding.GenerateVerifier).

To verify a proof, the dApp would call verifyProof on the registry contract directly, providing the circuit identifier and version number alongside the proof.

Simple example implementation

AnnaShaleva commented 2 weeks ago

Just for the record: as I said earlier in Discord, I agree that having such non-native contract would be beneficial for both Neo and Neo users, because it's more convenient, it doesn't cost a lot to the end-user and provides better user experience (user only have to store verification parameters instead of generating/deploying/maintaining verification contract by himself).

The only concern from my side is why other blockchain projects don't use this approach with a standard registry contract. The only thing that came to my mind is that the problem is in trust: this contract is responsible for verification of important paths, and if this contract is managed by some single outside entity, then it may be too risky for on-chain projects to put their trust into this contract - and here we are, every project wants to deploy its own contract. Thus, I'd like to ask anyone who has an expertise in this topic to name the reason why other chains don't use this approach with a single verification registry.

As an example of verification contracts autogen for other chains, here's a set of Solidity verification contract templates for different proving algorithms provided by consensys/gnark toolchain: https://github.com/Consensys/gnark/blob/fdb2b0de422b1c4fc5c6d08e81e788095ac818a6/internal/generator/backend/main.go