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/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}