arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/verifier/verifier.go
verifier/verifier.goRaw
  1package verifier
  2
  3import (
  4	"github.com/consensys/gnark/frontend"
  5	"github.com/succinctlabs/gnark-plonky2-verifier/challenger"
  6	"github.com/succinctlabs/gnark-plonky2-verifier/fri"
  7	gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
  8	"github.com/succinctlabs/gnark-plonky2-verifier/plonk"
  9	"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
 10	"github.com/succinctlabs/gnark-plonky2-verifier/types"
 11)
 12
 13type VerifierChip struct {
 14	api               frontend.API `gnark:"-"`
 15	poseidonGlChip    *poseidon.GoldilocksChip
 16	poseidonBN254Chip *poseidon.BN254Chip
 17	plonkChip         *plonk.PlonkChip
 18	friChip           *fri.Chip
 19}
 20
 21func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip {
 22	friChip := fri.NewChip(api, &commonCircuitData.FriParams)
 23	plonkChip := plonk.NewPlonkChip(api, commonCircuitData)
 24	poseidonGlChip := poseidon.NewGoldilocksChip(api)
 25	poseidonBN254Chip := poseidon.NewBN254Chip(api)
 26	return &VerifierChip{
 27		api:               api,
 28		poseidonGlChip:    poseidonGlChip,
 29		poseidonBN254Chip: poseidonBN254Chip,
 30		plonkChip:         plonkChip,
 31		friChip:           friChip,
 32	}
 33}
 34
 35func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.GoldilocksHashOut {
 36	return c.poseidonGlChip.HashNoPad(publicInputs)
 37}
 38
 39func (c *VerifierChip) GetChallenges(
 40	proof types.Proof,
 41	publicInputsHash poseidon.GoldilocksHashOut,
 42	commonData types.CommonCircuitData,
 43	verifierData types.VerifierOnlyCircuitData,
 44) types.ProofChallenges {
 45	config := commonData.Config
 46	numChallenges := config.NumChallenges
 47	challenger := challenger.NewChip(c.api)
 48
 49	var circuitDigest = verifierData.CircuitDigest
 50
 51	challenger.ObserveBN254Hash(circuitDigest)
 52	challenger.ObserveHash(publicInputsHash)
 53	challenger.ObserveCap(proof.WiresCap)
 54	plonkBetas := challenger.GetNChallenges(numChallenges)
 55	plonkGammas := challenger.GetNChallenges(numChallenges)
 56
 57	challenger.ObserveCap(proof.PlonkZsPartialProductsCap)
 58	plonkAlphas := challenger.GetNChallenges(numChallenges)
 59
 60	challenger.ObserveCap(proof.QuotientPolysCap)
 61	plonkZeta := challenger.GetExtensionChallenge()
 62
 63	challenger.ObserveOpenings(fri.ToOpenings(proof.Openings))
 64
 65	return types.ProofChallenges{
 66		PlonkBetas:  plonkBetas,
 67		PlonkGammas: plonkGammas,
 68		PlonkAlphas: plonkAlphas,
 69		PlonkZeta:   plonkZeta,
 70		FriChallenges: challenger.GetFriChallenges(
 71			proof.OpeningProof.CommitPhaseMerkleCaps,
 72			proof.OpeningProof.FinalPoly,
 73			proof.OpeningProof.PowWitness,
 74			commonData.DegreeBits,
 75			config.FriConfig,
 76		),
 77	}
 78}
 79
 80/*
 81func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) common.ProofWithPublicInputs {
 82	// Generate the parts of the witness that is for the plonky2 proof input
 83
 84	capHeight := commonData.Config.FriConfig.CapHeight
 85
 86	friCommitPhaseMerkleCaps := []common.MerkleCap{}
 87	for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ {
 88		friCommitPhaseMerkleCaps = append(friCommitPhaseMerkleCaps, common.NewMerkleCap(capHeight))
 89	}
 90
 91	salt := commonData.SaltSize()
 92	numLeavesPerOracle := []uint{
 93		commonData.NumPreprocessedPolys(),
 94		commonData.Config.NumWires + salt,
 95		commonData.NumZsPartialProductsPolys() + salt,
 96		commonData.NumQuotientPolys() + salt,
 97	}
 98	friQueryRoundProofs := []common.FriQueryRound{}
 99	for i := uint64(0); i < commonData.FriParams.Config.NumQueryRounds; i++ {
100		evalProofs := []common.EvalProof{}
101		merkleProofLen := commonData.FriParams.LDEBits() - capHeight
102		for _, numLeaves := range numLeavesPerOracle {
103			leaves := make([]field.F, numLeaves)
104			merkleProof := common.NewMerkleProof(merkleProofLen)
105			evalProofs = append(evalProofs, common.NewEvalProof(leaves, merkleProof))
106		}
107
108		initialTreesProof := common.NewFriInitialTreeProof(evalProofs)
109		steps := []common.FriQueryStep{}
110		for _, arityBit := range commonData.FriParams.ReductionArityBits {
111			if merkleProofLen < arityBit {
112				panic("merkleProofLen < arityBits")
113			}
114
115			steps = append(steps, common.NewFriQueryStep(arityBit, merkleProofLen))
116		}
117
118		friQueryRoundProofs = append(friQueryRoundProofs, common.NewFriQueryRound(steps, initialTreesProof))
119	}
120
121	proofInput := common.ProofWithPublicInputs{
122		Proof: common.Proof{
123			WiresCap:                  common.NewMerkleCap(capHeight),
124			PlonkZsPartialProductsCap: common.NewMerkleCap(capHeight),
125			QuotientPolysCap:          common.NewMerkleCap(capHeight),
126			Openings: common.NewOpeningSet(
127				commonData.Config.NumConstants,
128				commonData.Config.NumRoutedWires,
129				commonData.Config.NumWires,
130				commonData.Config.NumChallenges,
131				commonData.NumPartialProducts,
132				commonData.QuotientDegreeFactor,
133			),
134			OpeningProof: common.FriProof{
135				CommitPhaseMerkleCaps: friCommitPhaseMerkleCaps,
136				QueryRoundProofs:      friQueryRoundProofs,
137				FinalPoly:             common.NewPolynomialCoeffs(commonData.FriParams.FinalPolyLen()),
138			},
139		},
140		PublicInputs: make([]field.F, commonData.NumPublicInputs),
141	}
142
143	return proofInput
144}
145*/
146
147func (c *VerifierChip) Verify(
148	proof types.Proof,
149	publicInputs []gl.Variable,
150	verifierData types.VerifierOnlyCircuitData,
151	commonData types.CommonCircuitData,
152) {
153	glApi := gl.NewChip(c.api)
154	// TODO: Need to range check all the proof and public input elements to make sure they are within goldilocks field
155
156	// Generate the parts of the witness that is for the plonky2 proof input
157	publicInputsHash := c.GetPublicInputsHash(publicInputs)
158	proofChallenges := c.GetChallenges(proof, publicInputsHash, commonData, verifierData)
159
160	c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
161
162	initialMerkleCaps := []types.FriMerkleCap{
163		verifierData.ConstantSigmasCap,
164		proof.WiresCap,
165		proof.PlonkZsPartialProductsCap,
166		proof.QuotientPolysCap,
167	}
168
169	// Seems like there is a bug in the emulated field code.
170	// Add ZERO to all of the fri challenges values to reduce them.
171	proofChallenges.PlonkZeta[0] = glApi.Add(proofChallenges.PlonkZeta[0], gl.Zero())
172	proofChallenges.PlonkZeta[1] = glApi.Add(proofChallenges.PlonkZeta[1], gl.Zero())
173
174	proofChallenges.FriChallenges.FriAlpha[0] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[0], gl.Zero())
175	proofChallenges.FriChallenges.FriAlpha[1] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[1], gl.Zero())
176
177	for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
178		proofChallenges.FriChallenges.FriBetas[i][0] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][0], gl.Zero())
179		proofChallenges.FriChallenges.FriBetas[i][1] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][1], gl.Zero())
180	}
181
182	proofChallenges.FriChallenges.FriPowResponse = glApi.Add(proofChallenges.FriChallenges.FriPowResponse, gl.Zero())
183
184	for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ {
185		proofChallenges.FriChallenges.FriQueryIndices[i] = glApi.Add(proofChallenges.FriChallenges.FriQueryIndices[i], gl.Zero())
186	}
187
188	c.friChip.VerifyFriProof(
189		fri.GetInstance(&commonData, glApi, proofChallenges.PlonkZeta, commonData.DegreeBits),
190		fri.ToOpenings(proof.Openings),
191		&proofChallenges.FriChallenges,
192		initialMerkleCaps,
193		&proof.OpeningProof,
194	)
195}