arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonky2_verifier/fri.go
plonky2_verifier/fri.goRaw
  1package plonky2_verifier
  2
  3import (
  4	"fmt"
  5	"gnark-ed25519/field"
  6	. "gnark-ed25519/field"
  7	"math"
  8
  9	"github.com/consensys/gnark/frontend"
 10)
 11
 12type FriOpeningBatch struct {
 13	values []QuadraticExtension
 14}
 15
 16type FriOpenings struct {
 17	Batches []FriOpeningBatch
 18}
 19
 20func (c *OpeningSet) ToFriOpenings() FriOpenings {
 21	values := c.Constants
 22	values = append(values, c.PlonkSigmas...)
 23	values = append(values, c.Wires...)
 24	values = append(values, c.PlonkZs...)
 25	values = append(values, c.PartialProducts...)
 26	values = append(values, c.QuotientPolys...)
 27	zetaBatch := FriOpeningBatch{values: values}
 28	zetaNextBatch := FriOpeningBatch{values: c.PlonkZsNext}
 29	return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
 30}
 31
 32type FriChip struct {
 33	api   frontend.API
 34	field frontend.API
 35	qe    *QuadraticExtensionAPI
 36
 37	friParams               *FriParams
 38	verifierOnlyCircuitData *VerifierOnlyCircuitData
 39}
 40
 41func NewFriChip(api frontend.API, field frontend.API, qe *QuadraticExtensionAPI, friParams *FriParams) *FriChip {
 42	return &FriChip{
 43		api:       api,
 44		field:     field,
 45		qe:        qe,
 46		friParams: friParams,
 47	}
 48}
 49
 50func (f *FriChip) assertLeadingZeros(powWitness F, friConfig FriConfig) {
 51	// Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros.
 52	// Note that this is assuming that the Goldilocks field is being used.  Specfically that the
 53	// field is 64 bits long
 54	maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
 55	f.field.Println(powWitness)
 56	fmt.Println(maxPowWitness)
 57	fmt.Println(friConfig.ProofOfWorkBits)
 58	f.field.AssertIsLessOrEqual(powWitness, field.NewFieldElement(maxPowWitness))
 59}
 60
 61func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha QuadraticExtension) []QuadraticExtension {
 62	// One reduced opening for all openings evaluated at point Zeta.
 63	// Another one for all openings evaluated at point Zeta * Omega (which is only PlonkZsNext polynomial)
 64
 65	reducedOpenings := make([]QuadraticExtension, 0, 2)
 66	for _, batch := range openings.Batches {
 67		reducedOpenings = append(reducedOpenings, reduceWithPowers(f.qe, batch.values, alpha))
 68	}
 69
 70	return reducedOpenings
 71}
 72
 73func (f *FriChip) verifyMerkleProofToCap(leafData []F, leafIndex F, merkleCap MerkleCap, proof *MerkleProof) {
 74}
 75
 76func (f *FriChip) verifyInitialProof(xIndex F, proof *FriInitialTreeProof, initialMerkleCaps []MerkleCap) {
 77	if len(proof.EvalsProofs) != len(initialMerkleCaps) {
 78		panic("length of eval proofs in fri proof should equal length of initial merkle caps")
 79	}
 80
 81	for i := 0; i < len(initialMerkleCaps); i++ {
 82		evals := proof.EvalsProofs[i].Elements
 83		merkleProof := proof.EvalsProofs[i].MerkleProof
 84		cap := initialMerkleCaps[i]
 85		f.verifyMerkleProofToCap(evals, xIndex, cap, &merkleProof)
 86	}
 87}
 88
 89func (f *FriChip) verifyQueryRound(
 90	challenges *FriChallenges,
 91	precomputedReducedEval []QuadraticExtension,
 92	initialMerkleCaps []MerkleCap,
 93	proof *FriProof,
 94	xIndex F,
 95	n uint64,
 96	roundProof *FriQueryRound,
 97) {
 98	f.verifyInitialProof(xIndex, &roundProof.InitialTreesProof, initialMerkleCaps)
 99}
100
101func (f *FriChip) VerifyFriProof(
102	openings *FriOpenings,
103	friChallenges *FriChallenges,
104	initialMerkleCaps []MerkleCap,
105	friProof *FriProof,
106) {
107	// TODO:  Check fri config
108	/* if let Some(max_arity_bits) = params.max_arity_bits() {
109		self.check_recursion_config::<C>(max_arity_bits);
110	}
111
112	debug_assert_eq!(
113		params.final_poly_len(),
114		proof.final_poly.len(),
115		"Final polynomial has wrong degree."
116	); */
117
118	// Check POW
119	f.assertLeadingZeros(friProof.PowWitness, f.friParams.Config)
120
121	precomputedReducedEvals := f.fromOpeningsAndAlpha(openings, friChallenges.FriAlpha)
122
123	// Size of the LDE domain.
124	n := uint64(math.Pow(2, float64(f.friParams.DegreeBits+f.friParams.Config.RateBits)))
125
126	if len(friChallenges.FriQueryIndicies) != len(precomputedReducedEvals) {
127		panic("Number of queryRoundProofs should equal number of precomputedReducedEvals")
128	}
129
130	for idx, xIndex := range friChallenges.FriQueryIndicies {
131		roundProof := friProof.QueryRoundProofs[idx]
132
133		f.verifyQueryRound(
134			friChallenges,
135			precomputedReducedEvals,
136			initialMerkleCaps,
137			friProof,
138			xIndex,
139			n,
140			&roundProof,
141		)
142	}
143}