Neo SPCC has shared a guide to zero-knowledge proof development on the Neo blockchain. Since the upgrade to Neo v3.6 and NeoGo v0.102.0, the platform now supports arithmetic operations across BLS12-381 elliptic curve points, a necessary tool for the implementation of zero-knowledge proving systems.

A zero-knowledge proof is a method of demonstrating that a statement is true without revealing the statement itself. In its walkthrough of the new tools, Neo SPCC uses the example of a simple cubic equation: y = x^3 + x + 5. The prover will give a secret input for the value x, which will be used to compute the public value y.

Circuit design

To create a zero-knowledge proof for a given computation, the computation must be represented as a set of algebraic constraints called a circuit. The article demonstrates the use of gnark, open-source ZK-SNARK Go library by Consensys, to construct and compile these circuits from high-level Go code.

A circuit for the cubic equation is defined and then compiled into a Rank-1 Constraint System (R1CS) over the BLS21-381 elliptic curve scalar field as supported by Neo N3. The resulting constraint system can be used to create the proving/verifying keys needed to build and verify proofs for the original equation. Examples are provided for how circuits can be tested before proceeding further.

Verifier contracts

The next step is to generate proving and verifying keys for the circuit. The verifying key is used to generate a smart contract that can perform circuit-specific proofs. The proving key is used to generate proofs with a given input.

During the process of development and testing, users will typically generate their own keys locally. However, production-grade applications should use a trusted ceremony to generate keys in a manner which avoids randomness being leaked. If the randomness used to generate these keys is compromised, an attacker could break the system by generating false proofs.

Although developers may optionally write their own contracts to implement proof verification, NeoGo provides a new zkpbinding package which can make things considerably easier. A snippet is provided that shows how a verifier contract and the files needed for compilation and deployment can be generated using the constraint system and verification key.

Generating and verifying proofs

Verifier contracts produced by NeoGo have a single VerifyProof method, which accepts a proof of knowledge (in the form of three BLS12-381 EC points) plus any public input data. The contracts implement the Groth16 verification algorithm to check that the proof is valid for the provided public input.

The constraint system used to generate the verifier contract may also be used to generate proofs using the gnark library. Continuing with the cubic equation example, the prover wants to show they know a solution to the equation y = x^3 + x + 5 where the public input is the value for y, which in this case is 35, but without revealing x.

The prover generates a proof by using their private input x = 3 and the public y = 35. Before the proof can be used with NeoVM, it requires some formatting, which is facilitated by a helper in the zkpbinding package. The proof can now be verified using the corresponding verification contract. The prover shows they know a private input which is valid for y = 35, but their actual input was hidden within the three elliptic curve points of the proof.

Production applications

Though simple, the cubic equation example offers a good example of how information can be made private in an application. Zero-knowledge proofs may serve as a building block for new use cases and protocol enhancements, including scalability improvements (e.g. rollups).

While providing links to other resources for development of more complex and practical circuits, Neo SPCC highlighted the importance in having a secure trusted setup ceremony. This procedure ensures the randomness used for key generation remains uncompromised.

Trusted ceremonies typically involve a multi-party computation, divided into two phases. Phase 1, the “Powers of Tau”, is universal, meaning generated parameters can be used for any ZK SNARK using the same elliptic curve.

Neo developers opted against hosting its own Phase 1 ceremony, instead suggesting the adoption of an existing source with trusted attestations, such as Filecoin or ZCash.

Phase 2 is a circuit-specific procedure; a team will need to source a suitable MPC implementation to fit their needs. The parameters obtained from the Phase 2 step can be used to generate secure proving and verifying keys. Examples and documentation is provided.

The original article may be read at the link below:
https://neospcc.medium.com/falling-down-the-zk-cave-with-neogo-797d54e66597