gnark-plonky2-verifier/benchmark.go
benchmark.goRaw
1package main
2
3import (
4 "flag"
5 "fmt"
6 "os"
7 "time"
8
9 "github.com/succinctlabs/gnark-plonky2-verifier/field"
10 "github.com/succinctlabs/gnark-plonky2-verifier/verifier"
11 "github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
12 "github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
13
14 "github.com/consensys/gnark-crypto/ecc"
15 "github.com/consensys/gnark/backend/groth16"
16 "github.com/consensys/gnark/constraint"
17 "github.com/consensys/gnark/frontend"
18 "github.com/consensys/gnark/frontend/cs/r1cs"
19 "github.com/consensys/gnark/profile"
20)
21
22type BenchmarkPlonky2VerifierCircuit struct {
23 Proof common.Proof
24 PublicInputs []field.F `gnark:",public"`
25
26 verifierChip *verifier.VerifierChip `gnark:"-"`
27 plonky2CircuitName string `gnark:"-"`
28}
29
30func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error {
31 circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/"
32 commonCircuitData := utils.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
33 verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
34
35 circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
36
37 circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData)
38
39 return nil
40}
41
42func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) {
43 circuit := BenchmarkPlonky2VerifierCircuit{
44 plonky2CircuitName: plonky2Circuit,
45 }
46 proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
47 circuit.Proof = proofWithPis.Proof
48 circuit.PublicInputs = proofWithPis.PublicInputs
49
50 var p *profile.Profile
51 if profileCircuit {
52 p = profile.Start()
53 }
54 r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit)
55 if err != nil {
56 fmt.Println("error in building circuit", err)
57 os.Exit(1)
58 }
59
60 if profileCircuit {
61 p.Stop()
62 p.Top()
63 println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients())
64 println("r1cs.GetNbConstraints(): ", r1cs.GetNbConstraints())
65 println("r1cs.GetNbSecretVariables(): ", r1cs.GetNbSecretVariables())
66 println("r1cs.GetNbPublicVariables(): ", r1cs.GetNbPublicVariables())
67 println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables())
68 }
69
70 // Don't serialize the circuit for now, since it takes up too much memory
71 /*
72 if serialize {
73 fR1CS, _ := os.Create("circuit")
74 r1cs.WriteTo(fR1CS)
75 fR1CS.Close()
76 }
77 */
78
79 fmt.Println("Running circuit setup", time.Now())
80 pk, vk, err := groth16.Setup(r1cs)
81 if err != nil {
82 fmt.Println(err)
83 os.Exit(1)
84 }
85
86 if serialize {
87 fPK, _ := os.Create("proving.key")
88 pk.WriteTo(fPK)
89 fPK.Close()
90
91 fVK, _ := os.Create("verifying.key")
92 vk.WriteTo(fVK)
93 fVK.Close()
94 }
95
96 if outputSolidity {
97 fSolidity, _ := os.Create("proof.sol")
98 err = vk.ExportSolidity(fSolidity)
99 }
100
101 return r1cs, pk, vk
102}
103
104func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk groth16.ProvingKey, vk groth16.VerifyingKey, serialize bool) groth16.Proof {
105 proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
106
107 // Witness
108 assignment := &BenchmarkPlonky2VerifierCircuit{
109 Proof: proofWithPis.Proof,
110 PublicInputs: proofWithPis.PublicInputs,
111 }
112
113 fmt.Println("Generating witness", time.Now())
114 witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
115 publicWitness, _ := witness.Public()
116
117 fmt.Println("Creating proof", time.Now())
118 proof, err := groth16.Prove(r1cs, pk, witness)
119 if err != nil {
120 fmt.Println(err)
121 os.Exit(1)
122 }
123 fmt.Println("Verifying proof", time.Now())
124 err = groth16.Verify(proof, vk, publicWitness)
125 if err != nil {
126 fmt.Println(err)
127 os.Exit(1)
128 }
129
130 if serialize {
131 fProof, _ := os.Create("proof.proof")
132 proof.WriteTo(fProof)
133 }
134
135 return proof
136}
137
138func main() {
139 plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark")
140 profileCircuit := flag.Bool("profile", false, "profile the circuit")
141 serialize := flag.Bool("serialize", false, "serialize the circuit")
142 outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit")
143
144 flag.Parse()
145
146 if plonky2Circuit == nil || *plonky2Circuit == "" {
147 fmt.Println("Please provide a plonky2 circuit to benchmark")
148 os.Exit(1)
149 }
150
151 r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity)
152 createProof(*plonky2Circuit, r1cs, pk, vk, *serialize)
153}