arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
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}