arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/benchmark_plonk.go
benchmark_plonk.goRaw
  1package main
  2
  3import (
  4	"bytes"
  5	"flag"
  6	"fmt"
  7	"math/big"
  8	"os"
  9	"time"
 10
 11	gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
 12	"github.com/succinctlabs/gnark-plonky2-verifier/types"
 13	"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
 14
 15	"github.com/consensys/gnark-crypto/ecc"
 16	"github.com/consensys/gnark/backend/plonk"
 17	"github.com/consensys/gnark/constraint"
 18	"github.com/consensys/gnark/frontend"
 19	"github.com/consensys/gnark/frontend/cs/scs"
 20	"github.com/consensys/gnark/profile"
 21	"github.com/consensys/gnark/test"
 22)
 23
 24type BenchmarkPlonky2VerifierCircuitPlonk struct {
 25	Proof        types.Proof
 26	PublicInputs []gl.GoldilocksVariable `gnark:",public"`
 27
 28	verifierChip       *verifier.VerifierChip `gnark:"-"`
 29	plonky2CircuitName string                 `gnark:"-"`
 30}
 31
 32func (circuit *BenchmarkPlonky2VerifierCircuitPlonk) Define(api frontend.API) error {
 33	circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/"
 34	commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
 35	verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
 36
 37	circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
 38
 39	circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData)
 40
 41	return nil
 42}
 43
 44func compileCircuitPlonk(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, plonk.ProvingKey, plonk.VerifyingKey) {
 45	circuit := BenchmarkPlonky2VerifierCircuitPlonk{
 46		plonky2CircuitName: plonky2Circuit,
 47	}
 48	proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
 49	circuit.Proof = proofWithPis.Proof
 50	circuit.PublicInputs = proofWithPis.PublicInputs
 51
 52	var p *profile.Profile
 53	if profileCircuit {
 54		p = profile.Start()
 55	}
 56	r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &circuit)
 57	if err != nil {
 58		fmt.Println("error in building circuit", err)
 59		os.Exit(1)
 60	}
 61
 62	if profileCircuit {
 63		p.Stop()
 64		p.Top()
 65		println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients())
 66		println("r1cs.GetNbConstraints(): ", r1cs.GetNbConstraints())
 67		println("r1cs.GetNbSecretVariables(): ", r1cs.GetNbSecretVariables())
 68		println("r1cs.GetNbPublicVariables(): ", r1cs.GetNbPublicVariables())
 69		println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables())
 70	}
 71
 72	// Don't serialize the circuit for now, since it takes up too much memory
 73	/*
 74		if serialize {
 75			fR1CS, _ := os.Create("circuit")
 76			r1cs.WriteTo(fR1CS)
 77			fR1CS.Close()
 78		}
 79	*/
 80
 81	srs, err := test.NewKZGSRS(r1cs)
 82	if err != nil {
 83		panic(err)
 84	}
 85
 86	fmt.Println("Running circuit setup", time.Now())
 87	pk, vk, err := plonk.Setup(r1cs, srs)
 88	if err != nil {
 89		fmt.Println(err)
 90		os.Exit(1)
 91	}
 92
 93	if serialize {
 94		fPK, _ := os.Create("proving.key")
 95		pk.WriteTo(fPK)
 96		fPK.Close()
 97
 98		fVK, _ := os.Create("verifying.key")
 99		vk.WriteTo(fVK)
100		fVK.Close()
101	}
102
103	if outputSolidity {
104		fSolidity, _ := os.Create("proof.sol")
105		err = vk.ExportSolidity(fSolidity)
106	}
107
108	return r1cs, pk, vk
109}
110
111func createProofPlonk(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk plonk.ProvingKey, vk plonk.VerifyingKey, serialize bool) plonk.Proof {
112	proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
113
114	// Witness
115	assignment := &BenchmarkPlonky2VerifierCircuitPlonk{
116		Proof:        proofWithPis.Proof,
117		PublicInputs: proofWithPis.PublicInputs,
118	}
119
120	fmt.Println("Generating witness", time.Now())
121	witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
122	publicWitness, _ := witness.Public()
123
124	fmt.Println("Creating proof", time.Now())
125	proof, err := plonk.Prove(r1cs, pk, witness)
126	if err != nil {
127		fmt.Println(err)
128		os.Exit(1)
129	}
130	fmt.Println("Verifying proof", time.Now())
131	err = plonk.Verify(proof, vk, publicWitness)
132	if err != nil {
133		fmt.Println(err)
134		os.Exit(1)
135	}
136
137	const fpSize = 4 * 8
138	var buf bytes.Buffer
139	proof.WriteRawTo(&buf)
140	proofBytes := buf.Bytes()
141
142	var (
143		a [2]*big.Int
144		b [2][2]*big.Int
145		c [2]*big.Int
146	)
147
148	// proof.Ar, proof.Bs, proof.Krs
149	a[0] = new(big.Int).SetBytes(proofBytes[fpSize*0 : fpSize*1])
150	a[1] = new(big.Int).SetBytes(proofBytes[fpSize*1 : fpSize*2])
151	b[0][0] = new(big.Int).SetBytes(proofBytes[fpSize*2 : fpSize*3])
152	b[0][1] = new(big.Int).SetBytes(proofBytes[fpSize*3 : fpSize*4])
153	b[1][0] = new(big.Int).SetBytes(proofBytes[fpSize*4 : fpSize*5])
154	b[1][1] = new(big.Int).SetBytes(proofBytes[fpSize*5 : fpSize*6])
155	c[0] = new(big.Int).SetBytes(proofBytes[fpSize*6 : fpSize*7])
156	c[1] = new(big.Int).SetBytes(proofBytes[fpSize*7 : fpSize*8])
157
158	println("a[0] is ", a[0].String())
159	println("a[1] is ", a[1].String())
160
161	println("b[0][0] is ", b[0][0].String())
162	println("b[0][1] is ", b[0][1].String())
163	println("b[1][0] is ", b[1][0].String())
164	println("b[1][1] is ", b[1][1].String())
165
166	println("c[0] is ", c[0].String())
167	println("c[1] is ", c[1].String())
168
169	return proof
170}
171
172func main() {
173	plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark")
174	profileCircuit := flag.Bool("profile", false, "profile the circuit")
175	serialize := flag.Bool("serialize", false, "serialize the circuit")
176	outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit")
177
178	flag.Parse()
179
180	if plonky2Circuit == nil || *plonky2Circuit == "" {
181		fmt.Println("Please provide a plonky2 circuit to benchmark")
182		os.Exit(1)
183	}
184
185	r1cs, pk, vk := compileCircuitPlonk(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity)
186	createProofPlonk(*plonky2Circuit, r1cs, pk, vk, *serialize)
187}