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