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