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	"github.com/succinctlabs/gnark-plonky2-verifier/variables"
 12)
 13
 14type VerifierChip struct {
 15	api               frontend.API             `gnark:"-"`
 16	glChip            *gl.Chip                 `gnark:"-"`
 17	poseidonGlChip    *poseidon.GoldilocksChip `gnark:"-"`
 18	poseidonBN254Chip *poseidon.BN254Chip      `gnark:"-"`
 19	plonkChip         *plonk.PlonkChip         `gnark:"-"`
 20	friChip           *fri.Chip                `gnark:"-"`
 21	commonData        types.CommonCircuitData  `gnark:"-"`
 22}
 23
 24func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip {
 25	glChip := gl.New(api)
 26	friChip := fri.NewChip(api, &commonCircuitData, &commonCircuitData.FriParams)
 27	plonkChip := plonk.NewPlonkChip(api, commonCircuitData)
 28	poseidonGlChip := poseidon.NewGoldilocksChip(api)
 29	poseidonBN254Chip := poseidon.NewBN254Chip(api)
 30	return &VerifierChip{
 31		api:               api,
 32		glChip:            glChip,
 33		poseidonGlChip:    poseidonGlChip,
 34		poseidonBN254Chip: poseidonBN254Chip,
 35		plonkChip:         plonkChip,
 36		friChip:           friChip,
 37		commonData:        commonCircuitData,
 38	}
 39}
 40
 41func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.GoldilocksHashOut {
 42	return c.poseidonGlChip.HashNoPad(publicInputs)
 43}
 44
 45func (c *VerifierChip) GetChallenges(
 46	proof variables.Proof,
 47	publicInputsHash poseidon.GoldilocksHashOut,
 48	verifierData variables.VerifierOnlyCircuitData,
 49) variables.ProofChallenges {
 50	config := c.commonData.Config
 51	numChallenges := config.NumChallenges
 52	challenger := challenger.NewChip(c.api)
 53
 54	var circuitDigest = verifierData.CircuitDigest
 55
 56	challenger.ObserveFriParams(c.commonData.FriParams)
 57	challenger.ObserveBN254Hash(circuitDigest)
 58	challenger.ObserveHash(publicInputsHash)
 59	challenger.ObserveCap(proof.WiresCap)
 60	plonkBetas := challenger.GetNChallenges(numChallenges)
 61	plonkGammas := challenger.GetNChallenges(numChallenges)
 62
 63	challenger.ObserveCap(proof.PlonkZsPartialProductsCap)
 64	plonkAlphas := challenger.GetNChallenges(numChallenges)
 65
 66	challenger.ObserveCap(proof.QuotientPolysCap)
 67	plonkZeta := challenger.GetExtensionChallenge()
 68
 69	challenger.ObserveOpenings(c.friChip.ToOpenings(proof.Openings))
 70
 71	return variables.ProofChallenges{
 72		PlonkBetas:  plonkBetas,
 73		PlonkGammas: plonkGammas,
 74		PlonkAlphas: plonkAlphas,
 75		PlonkZeta:   plonkZeta,
 76		FriChallenges: challenger.GetFriChallenges(
 77			proof.OpeningProof.CommitPhaseMerkleCaps,
 78			proof.OpeningProof.FinalPoly,
 79			proof.OpeningProof.PowWitness,
 80			config.FriConfig,
 81		),
 82	}
 83}
 84
 85func (c *VerifierChip) rangeCheckProof(proof variables.Proof) {
 86	// Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness.
 87
 88	// Note that this is NOT range checking the public inputs (first 32 elements should be no more than 8 bits and the last 4 elements should be no more than 64 bits).  Since this is currently being inputted via the smart contract,
 89	// we will assume that caller is doing that check.
 90
 91	// Range check the proof's openings.
 92	for _, constant := range proof.Openings.Constants {
 93		c.glChip.RangeCheckQE(constant)
 94	}
 95
 96	for _, plonkSigma := range proof.Openings.PlonkSigmas {
 97		c.glChip.RangeCheckQE(plonkSigma)
 98	}
 99
100	for _, wire := range proof.Openings.Wires {
101		c.glChip.RangeCheckQE(wire)
102	}
103
104	for _, plonkZ := range proof.Openings.PlonkZs {
105		c.glChip.RangeCheckQE(plonkZ)
106	}
107
108	for _, plonkZNext := range proof.Openings.PlonkZsNext {
109		c.glChip.RangeCheckQE(plonkZNext)
110	}
111
112	for _, partialProduct := range proof.Openings.PartialProducts {
113		c.glChip.RangeCheckQE(partialProduct)
114	}
115
116	for _, quotientPoly := range proof.Openings.QuotientPolys {
117		c.glChip.RangeCheckQE(quotientPoly)
118	}
119
120	// Range check the openings proof.
121	for _, queryRound := range proof.OpeningProof.QueryRoundProofs {
122		for _, evalsProof := range queryRound.InitialTreesProof.EvalsProofs {
123			for _, evalsProofElement := range evalsProof.Elements {
124				c.glChip.RangeCheck(evalsProofElement)
125			}
126		}
127
128		for _, queryStep := range queryRound.Steps {
129			for _, eval := range queryStep.Evals {
130				c.glChip.RangeCheckQE(eval)
131			}
132		}
133	}
134
135	// Range check the fri's final poly.
136	for _, coeff := range proof.OpeningProof.FinalPoly.Coeffs {
137		c.glChip.RangeCheckQE(coeff)
138	}
139
140	// Range check the pow witness.
141	c.glChip.RangeCheck(proof.OpeningProof.PowWitness)
142}
143
144func (c *VerifierChip) Verify(
145	proof variables.Proof,
146	publicInputs []gl.Variable,
147	verifierData variables.VerifierOnlyCircuitData,
148) {
149	c.rangeCheckProof(proof)
150
151	// Generate the parts of the witness that is for the plonky2 proof input
152	publicInputsHash := c.GetPublicInputsHash(publicInputs)
153	proofChallenges := c.GetChallenges(proof, publicInputsHash, verifierData)
154
155	c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
156
157	initialMerkleCaps := []variables.FriMerkleCap{
158		verifierData.ConstantSigmasCap,
159		proof.WiresCap,
160		proof.PlonkZsPartialProductsCap,
161		proof.QuotientPolysCap,
162	}
163
164	c.friChip.VerifyFriProof(
165		c.friChip.GetInstance(proofChallenges.PlonkZeta),
166		c.friChip.ToOpenings(proof.Openings),
167		&proofChallenges.FriChallenges,
168		initialMerkleCaps,
169		&proof.OpeningProof,
170	)
171}