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.ObserveBN254Hash(circuitDigest)
 57	challenger.ObserveHash(publicInputsHash)
 58	challenger.ObserveCap(proof.WiresCap)
 59	plonkBetas := challenger.GetNChallenges(numChallenges)
 60	plonkGammas := challenger.GetNChallenges(numChallenges)
 61
 62	challenger.ObserveCap(proof.PlonkZsPartialProductsCap)
 63	plonkAlphas := challenger.GetNChallenges(numChallenges)
 64
 65	challenger.ObserveCap(proof.QuotientPolysCap)
 66	plonkZeta := challenger.GetExtensionChallenge()
 67
 68	challenger.ObserveOpenings(c.friChip.ToOpenings(proof.Openings))
 69
 70	return variables.ProofChallenges{
 71		PlonkBetas:  plonkBetas,
 72		PlonkGammas: plonkGammas,
 73		PlonkAlphas: plonkAlphas,
 74		PlonkZeta:   plonkZeta,
 75		FriChallenges: challenger.GetFriChallenges(
 76			proof.OpeningProof.CommitPhaseMerkleCaps,
 77			proof.OpeningProof.FinalPoly,
 78			proof.OpeningProof.PowWitness,
 79			config.FriConfig,
 80		),
 81	}
 82}
 83
 84func (c *VerifierChip) rangeCheckProof(proof variables.Proof) {
 85	// Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness.
 86
 87	// 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,
 88	// we will assume that caller is doing that check.
 89
 90	// Range check the proof's openings.
 91	for _, constant := range proof.Openings.Constants {
 92		c.glChip.RangeCheckQE(constant)
 93	}
 94
 95	for _, plonkSigma := range proof.Openings.PlonkSigmas {
 96		c.glChip.RangeCheckQE(plonkSigma)
 97	}
 98
 99	for _, wire := range proof.Openings.Wires {
100		c.glChip.RangeCheckQE(wire)
101	}
102
103	for _, plonkZ := range proof.Openings.PlonkZs {
104		c.glChip.RangeCheckQE(plonkZ)
105	}
106
107	for _, plonkZNext := range proof.Openings.PlonkZsNext {
108		c.glChip.RangeCheckQE(plonkZNext)
109	}
110
111	for _, partialProduct := range proof.Openings.PartialProducts {
112		c.glChip.RangeCheckQE(partialProduct)
113	}
114
115	for _, quotientPoly := range proof.Openings.QuotientPolys {
116		c.glChip.RangeCheckQE(quotientPoly)
117	}
118
119	// Range check the openings proof.
120	for _, queryRound := range proof.OpeningProof.QueryRoundProofs {
121		for _, evalsProof := range queryRound.InitialTreesProof.EvalsProofs {
122			for _, evalsProofElement := range evalsProof.Elements {
123				c.glChip.RangeCheck(evalsProofElement)
124			}
125		}
126
127		for _, queryStep := range queryRound.Steps {
128			for _, eval := range queryStep.Evals {
129				c.glChip.RangeCheckQE(eval)
130			}
131		}
132	}
133
134	// Range check the fri's final poly.
135	for _, coeff := range proof.OpeningProof.FinalPoly.Coeffs {
136		c.glChip.RangeCheckQE(coeff)
137	}
138
139	// Range check the pow witness.
140	c.glChip.RangeCheck(proof.OpeningProof.PowWitness)
141}
142
143func (c *VerifierChip) Verify(
144	proof variables.Proof,
145	publicInputs []gl.Variable,
146	verifierData variables.VerifierOnlyCircuitData,
147) {
148	c.rangeCheckProof(proof)
149
150	// Generate the parts of the witness that is for the plonky2 proof input
151	publicInputsHash := c.GetPublicInputsHash(publicInputs)
152	proofChallenges := c.GetChallenges(proof, publicInputsHash, verifierData)
153
154	c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
155
156	initialMerkleCaps := []variables.FriMerkleCap{
157		verifierData.ConstantSigmasCap,
158		proof.WiresCap,
159		proof.PlonkZsPartialProductsCap,
160		proof.QuotientPolysCap,
161	}
162
163	c.friChip.VerifyFriProof(
164		c.friChip.GetInstance(proofChallenges.PlonkZeta),
165		c.friChip.ToOpenings(proof.Openings),
166		&proofChallenges.FriChallenges,
167		initialMerkleCaps,
168		&proof.OpeningProof,
169	)
170}