arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/fri_benchmark.go
fri_benchmark.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	. "gnark-ed25519/field"
  6	. "gnark-ed25519/plonky2_verifier"
  7	"gnark-ed25519/poseidon"
  8	"os"
  9	"time"
 10
 11	"github.com/consensys/gnark-crypto/ecc"
 12	"github.com/consensys/gnark/backend/groth16"
 13	"github.com/consensys/gnark/frontend"
 14	"github.com/consensys/gnark/frontend/cs/r1cs"
 15)
 16
 17type BenchmarkLargeDummyFriCircuit struct {
 18	zeta              QuadraticExtension
 19	openings          FriOpenings
 20	friChallenges     FriChallenges
 21	initialMerkleCaps []MerkleCap
 22	friProof          FriProof
 23}
 24
 25func (circuit *BenchmarkLargeDummyFriCircuit) Define(api frontend.API) error {
 26	commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json")
 27
 28	field := NewFieldAPI(api)
 29	qeAPI := NewQuadraticExtensionAPI(field, commonCircuitData.DegreeBits)
 30	poseidonChip := poseidon.NewPoseidonChip(api, field)
 31	friChip := NewFriChip(api, field, qeAPI, poseidonChip, &commonCircuitData.FriParams)
 32
 33	friChip.VerifyFriProof(
 34		commonCircuitData.GetFriInstance(qeAPI, circuit.zeta, commonCircuitData.DegreeBits),
 35		circuit.openings,
 36		&circuit.friChallenges,
 37		circuit.initialMerkleCaps,
 38		&circuit.friProof,
 39	)
 40
 41	return nil
 42}
 43
 44func compileCircuit() frontend.CompiledConstraintSystem {
 45	fmt.Println("compiling circuit", time.Now())
 46	circuit := BenchmarkLargeDummyFriCircuit{}
 47
 48	/*
 49		commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json")
 50
 51		circuit.zeta[0] = emulated.NewElement[EmulatedField](nil)
 52		circuit.zeta[1] = emulated.NewElement[EmulatedField](nil)
 53
 54		fmt.Println("circuit zeta allocated")
 55
 56		// Batch 0 has the following openings
 57		// Constants (config.num_constants + 1)
 58		// Sigmas (config.num_routed_wires)
 59		// Wires (config.num_wires)
 60		// Plonk_Z (config.num_challenges)
 61		// Partial Products (config.num_challenges * config.num_partial_products)
 62		// Quotient Polynomails (config.num_challenges * config.quotient_degree_factor)
 63
 64		// Batch 1 has the following openings
 65		// Plonk_Z_next (config.num_challenges)
 66
 67		circuit.openings.Batches = make([]FriOpeningBatch, 2)
 68
 69		batch1Size := commonCircuitData.NumConstants + 1 +
 70			commonCircuitData.Config.NumRoutedWires +
 71			commonCircuitData.Config.NumWires +
 72			commonCircuitData.Config.NumChallenges +
 73			(commonCircuitData.Config.NumChallenges * commonCircuitData.NumPartialProducts) +
 74			(commonCircuitData.Config.NumChallenges * commonCircuitData.QuotientDegreeFactor)
 75
 76		circuit.openings.Batches[0].Values = make([]QuadraticExtension, 0)
 77		for i := uint64(0); i < batch1Size; i++ {
 78			circuit.openings.Batches[0].Values = append(circuit.openings.Batches[0].Values, NewEmptyQuadraticExtension())
 79		}
 80
 81		batch2Size := commonCircuitData.Config.NumChallenges
 82		circuit.openings.Batches[1].Values = make([]QuadraticExtension, 0)
 83		for i := uint64(0); i < batch2Size; i++ {
 84			circuit.openings.Batches[1].Values = append(circuit.openings.Batches[1].Values, NewEmptyQuadraticExtension())
 85		}
 86
 87		fmt.Println("circuit openings allocated")
 88
 89		circuit.friChallenges.FriAlpha = NewEmptyQuadraticExtension()
 90		circuit.friChallenges.FriPowResponse = emulated.NewElement[EmulatedField](nil)
 91		circuit.friChallenges.FriBetas = make([]QuadraticExtension, 0)
 92		for i := 0; i < len(commonCircuitData.FriParams.ReductionArityBits); i++ {
 93			circuit.friChallenges.FriBetas = append(circuit.friChallenges.FriBetas, NewEmptyQuadraticExtension())
 94		}
 95		circuit.friChallenges.FriQueryIndicies = make([]F, 0)
 96		for i := uint64(0); i < commonCircuitData.FriParams.Config.NumQueryRounds; i++ {
 97			circuit.friChallenges.FriQueryIndicies = append(circuit.friChallenges.FriQueryIndicies, NewEmptyFieldElement())
 98		}
 99
100		fmt.Println("circuit challenges allocated")
101
102		// initial merkle caps is the merkle cap for
103		// the constant/sigmas, wires, partial products,
104		// and quotient composite polynomial
105		// The merkle cap size is 2**cap_height hashes
106		numMerkleCaps := 4
107		merkleCapSize := 1 << commonCircuitData.Config.FriConfig.CapHeight
108		circuit.initialMerkleCaps = make([]MerkleCap, 0)
109		for i := 0; i < numMerkleCaps; i++ {
110			merkleCap := make([]Hash, 0)
111			for j := 0; j < merkleCapSize; j++ {
112				merkleCap = append(merkleCap, NewEmptyHash())
113			}
114			circuit.initialMerkleCaps = append(circuit.initialMerkleCaps, merkleCap)
115		}
116
117		fmt.Println("circuit initialMerkleCaps allocated")
118
119		// CommitPhaseMerkleCap is number of reduction_arity_bits
120		// finalPoly has 2^(degreeBits - sum(arity_bits)) coefficients
121		numCommitPhaseMerkleCaps := len(commonCircuitData.FriParams.ReductionArityBits)
122		for i := 0; i < numCommitPhaseMerkleCaps; i++ {
123			circuit.friProof.CommitPhaseMerkleCaps = make([]MerkleCap, 0)
124			merkleCap := make([]Hash, 0)
125			for j := 0; j < merkleCapSize; j++ {
126				merkleCap = append(merkleCap, NewEmptyHash())
127			}
128			circuit.friProof.CommitPhaseMerkleCaps = append(circuit.friProof.CommitPhaseMerkleCaps, merkleCap)
129		}
130
131		fmt.Println("circuit friproof CommitPhaseMerkleCaps allocated")
132
133		friOracleInfo := commonCircuitData.FriOracles()
134		circuit.friProof.QueryRoundProofs = make([]FriQueryRound, 0)
135		for i := 0; i < int(commonCircuitData.FriParams.Config.NumQueryRounds); i++ {
136
137			evalsProof := make([]EvalProof, 0)
138			// Allocation for the initial trees proof
139			for j := 0; j < len(friOracleInfo); j++ {
140				leafSize := friOracleInfo[0].NumPolys
141				merkleProofLen := commonCircuitData.DegreeBits + commonCircuitData.Config.FriConfig.RateBits - commonCircuitData.Config.FriConfig.CapHeight
142
143				evalElements := make([]F, 0)
144				for k := uint64(0); k < leafSize; k++ {
145					evalElements = append(evalElements, NewEmptyFieldElement())
146				}
147
148				merkleProofSiblings := make([]Hash, 0)
149				for k := uint64(0); k < merkleProofLen; k++ {
150					merkleProofSiblings = append(merkleProofSiblings, NewEmptyHash())
151				}
152
153				evalsProof = append(
154					evalsProof,
155					EvalProof{
156						Elements:    evalElements,
157						MerkleProof: MerkleProof{merkleProofSiblings},
158					},
159				)
160			}
161
162			// Allocation for the steps
163			steps := make([]FriQueryStep, 0)
164			codewordLenBits := commonCircuitData.DegreeBits + commonCircuitData.Config.FriConfig.RateBits
165			for j := 0; j < len(commonCircuitData.FriParams.ReductionArityBits); j++ {
166				arityBits := commonCircuitData.FriParams.ReductionArityBits[j]
167				leafSize := 1 << int(arityBits)
168				codewordLenBits -= arityBits
169				merkleProofLen := codewordLenBits - commonCircuitData.Config.FriConfig.CapHeight
170
171				evalQEs := make([]QuadraticExtension, 0)
172				for k := 0; k < leafSize; k++ {
173					evalQEs = append(evalQEs, NewEmptyQuadraticExtension())
174				}
175
176				merkleProofSiblings := make([]Hash, 0)
177				for k := uint64(0); k < merkleProofLen; k++ {
178					merkleProofSiblings = append(merkleProofSiblings, NewEmptyHash())
179				}
180
181				steps = append(
182					steps,
183					FriQueryStep{
184						Evals:       evalQEs,
185						MerkleProof: MerkleProof{merkleProofSiblings},
186					},
187				)
188			}
189
190			circuit.friProof.QueryRoundProofs = append(
191				circuit.friProof.QueryRoundProofs,
192				FriQueryRound{
193					InitialTreesProof: FriInitialTreeProof{evalsProof},
194					Steps:             steps,
195				},
196			)
197
198			fmt.Println("circuit friproof QueryRoundProofs allocated for round", i)
199		}
200
201		// Final poly allocation
202		finalPolyLenBit := commonCircuitData.DegreeBits
203		for _, arityBit := range commonCircuitData.FriParams.ReductionArityBits {
204			finalPolyLenBit -= arityBit
205		}
206
207		circuit.friProof.FinalPoly.Coeffs = make([]QuadraticExtension, 0)
208		for i := 0; i < (1 << finalPolyLenBit); i++ {
209			circuit.friProof.FinalPoly.Coeffs = append(circuit.friProof.FinalPoly.Coeffs, NewEmptyQuadraticExtension())
210		}
211
212		fmt.Println("circuit friproof FinalPoly allocated")
213
214		// PowWitness allocation
215		circuit.friProof.PowWitness = NewEmptyFieldElement()
216		fmt.Println("Partial witness allocation done")
217	*/
218
219	proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json")
220	verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json")
221
222	zeta := QuadraticExtension{
223		NewFieldElementFromString("17377750363769967882"),
224		NewFieldElementFromString("11921191651424768462"),
225	}
226	friChallenges := FriChallenges{
227		FriAlpha: QuadraticExtension{
228			NewFieldElementFromString("16721004555774385479"),
229			NewFieldElementFromString("10688151135543754663"),
230		},
231		FriBetas: []QuadraticExtension{
232			{
233				NewFieldElementFromString("3312441922957827805"),
234				NewFieldElementFromString("15128092514958289671"),
235			},
236			{
237				NewFieldElementFromString("13630530769060141802"),
238				NewFieldElementFromString("14559883974933163008"),
239			},
240			{
241				NewFieldElementFromString("16146508250083930687"),
242				NewFieldElementFromString("5176346568444408396"),
243			},
244		},
245		FriPowResponse: NewFieldElement(4389),
246		FriQueryIndicies: []F{
247			NewFieldElementFromString("16334967868590615051"),
248			NewFieldElementFromString("2911473540496037915"),
249			NewFieldElementFromString("14887216056886344225"),
250			NewFieldElementFromString("7808811227805914295"),
251			NewFieldElementFromString("2018594961417375749"),
252			NewFieldElementFromString("3733368398777208435"),
253			NewFieldElementFromString("2623035669037055104"),
254			NewFieldElementFromString("299243030573481514"),
255			NewFieldElementFromString("7189789717962704433"),
256			NewFieldElementFromString("14566344026886816268"),
257			NewFieldElementFromString("12555390069003437453"),
258			NewFieldElementFromString("17225508403199418233"),
259			NewFieldElementFromString("5088797913879903292"),
260			NewFieldElementFromString("9715691392773433023"),
261			NewFieldElementFromString("7565836764713256165"),
262			NewFieldElementFromString("1500143546029322929"),
263			NewFieldElementFromString("1245802417104422080"),
264			NewFieldElementFromString("6831959786661245110"),
265			NewFieldElementFromString("17271054758535453780"),
266			NewFieldElementFromString("6225460404576395409"),
267			NewFieldElementFromString("15932661092896277351"),
268			NewFieldElementFromString("12452534049198240575"),
269			NewFieldElementFromString("4225199666055520177"),
270			NewFieldElementFromString("13235091290587791090"),
271			NewFieldElementFromString("2562357622728700774"),
272			NewFieldElementFromString("17676678042980201498"),
273			NewFieldElementFromString("5837067135702409874"),
274			NewFieldElementFromString("11238419549114325157"),
275		},
276	}
277
278	initialMerkleCaps := []MerkleCap{
279		verifierOnlyCircuitData.ConstantSigmasCap,
280		proofWithPis.Proof.WiresCap,
281		proofWithPis.Proof.PlonkZsPartialProductsCap,
282		proofWithPis.Proof.QuotientPolysCap,
283	}
284
285	circuit.zeta = zeta
286	circuit.openings = proofWithPis.Proof.Openings.ToFriOpenings()
287	circuit.friChallenges = friChallenges
288	circuit.initialMerkleCaps = initialMerkleCaps
289	circuit.friProof = proofWithPis.Proof.OpeningProof
290
291	r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit)
292	if err != nil {
293		fmt.Println("error in building circuit", err)
294		os.Exit(1)
295	}
296
297	return r1cs
298}
299
300func createProof(r1cs frontend.CompiledConstraintSystem) groth16.Proof {
301	proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json")
302	verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json")
303
304	zeta := QuadraticExtension{
305		NewFieldElementFromString("17377750363769967882"),
306		NewFieldElementFromString("11921191651424768462"),
307	}
308	friChallenges := FriChallenges{
309		FriAlpha: QuadraticExtension{
310			NewFieldElementFromString("16721004555774385479"),
311			NewFieldElementFromString("10688151135543754663"),
312		},
313		FriBetas: []QuadraticExtension{
314			{
315				NewFieldElementFromString("3312441922957827805"),
316				NewFieldElementFromString("15128092514958289671"),
317			},
318			{
319				NewFieldElementFromString("13630530769060141802"),
320				NewFieldElementFromString("14559883974933163008"),
321			},
322			{
323				NewFieldElementFromString("16146508250083930687"),
324				NewFieldElementFromString("5176346568444408396"),
325			},
326		},
327		FriPowResponse: NewFieldElement(4389),
328		FriQueryIndicies: []F{
329			NewFieldElementFromString("16334967868590615051"),
330			NewFieldElementFromString("2911473540496037915"),
331			NewFieldElementFromString("14887216056886344225"),
332			NewFieldElementFromString("7808811227805914295"),
333			NewFieldElementFromString("2018594961417375749"),
334			NewFieldElementFromString("3733368398777208435"),
335			NewFieldElementFromString("2623035669037055104"),
336			NewFieldElementFromString("299243030573481514"),
337			NewFieldElementFromString("7189789717962704433"),
338			NewFieldElementFromString("14566344026886816268"),
339			NewFieldElementFromString("12555390069003437453"),
340			NewFieldElementFromString("17225508403199418233"),
341			NewFieldElementFromString("5088797913879903292"),
342			NewFieldElementFromString("9715691392773433023"),
343			NewFieldElementFromString("7565836764713256165"),
344			NewFieldElementFromString("1500143546029322929"),
345			NewFieldElementFromString("1245802417104422080"),
346			NewFieldElementFromString("6831959786661245110"),
347			NewFieldElementFromString("17271054758535453780"),
348			NewFieldElementFromString("6225460404576395409"),
349			NewFieldElementFromString("15932661092896277351"),
350			NewFieldElementFromString("12452534049198240575"),
351			NewFieldElementFromString("4225199666055520177"),
352			NewFieldElementFromString("13235091290587791090"),
353			NewFieldElementFromString("2562357622728700774"),
354			NewFieldElementFromString("17676678042980201498"),
355			NewFieldElementFromString("5837067135702409874"),
356			NewFieldElementFromString("11238419549114325157"),
357		},
358	}
359
360	initialMerkleCaps := []MerkleCap{
361		verifierOnlyCircuitData.ConstantSigmasCap,
362		proofWithPis.Proof.WiresCap,
363		proofWithPis.Proof.PlonkZsPartialProductsCap,
364		proofWithPis.Proof.QuotientPolysCap,
365	}
366
367	// Witness
368	assignment := &BenchmarkLargeDummyFriCircuit{
369		zeta:              zeta,
370		openings:          proofWithPis.Proof.Openings.ToFriOpenings(),
371		friChallenges:     friChallenges,
372		initialMerkleCaps: initialMerkleCaps,
373		friProof:          proofWithPis.Proof.OpeningProof,
374	}
375
376	fmt.Println("Generating witness", time.Now())
377	witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
378	publicWitness, _ := witness.Public()
379	pk, vk, err := groth16.Setup(r1cs)
380	if err != nil {
381		fmt.Println(err)
382		os.Exit(1)
383	}
384
385	fmt.Println("Creating proof", time.Now())
386	proof, err := groth16.Prove(r1cs, pk, witness)
387	if err != nil {
388		fmt.Println(err)
389		os.Exit(1)
390	}
391	fmt.Println("Verifying proof", time.Now())
392	err = groth16.Verify(proof, vk, publicWitness)
393	if err != nil {
394		fmt.Println(err)
395		os.Exit(1)
396	}
397
398	return proof
399}
400
401func main() {
402	r1cs := compileCircuit()
403	fi, _ := os.Open("dummy_fri.r1cs")
404	r1cs.WriteTo(fi)
405	proof := createProof(r1cs)
406	fmt.Println(proof.CurveID(), time.Now())
407}