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     frontend.API                 `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(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
 86func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
 87	// TODO: Verify shape of the proof?
 88
 89	publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
 90	proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData, verifierData)
 91
 92	c.plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
 93
 94	initialMerkleCaps := []common.MerkleCap{
 95		verifierData.ConstantSigmasCap,
 96		proofWithPis.Proof.WiresCap,
 97		proofWithPis.Proof.PlonkZsPartialProductsCap,
 98		proofWithPis.Proof.QuotientPolysCap,
 99	}
100
101	// Seems like there is a bug in the emulated field code.
102	// Add ZERO to all of the fri challenges values to reduce them.
103	proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], field.ZERO_F).(field.F)
104	proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], field.ZERO_F).(field.F)
105
106	proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], field.ZERO_F).(field.F)
107	proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], field.ZERO_F).(field.F)
108
109	for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
110		proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], field.ZERO_F).(field.F)
111		proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], field.ZERO_F).(field.F)
112	}
113
114	proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, field.ZERO_F).(field.F)
115
116	for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ {
117		proofChallenges.FriChallenges.FriQueryIndices[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndices[i], field.ZERO_F).(field.F)
118	}
119
120	c.friChip.VerifyFriProof(
121		fri.GetFriInstance(&commonData, c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits),
122		fri.ToFriOpenings(proofWithPis.Proof.Openings),
123		&proofChallenges.FriChallenges,
124		initialMerkleCaps,
125		&proofWithPis.Proof.OpeningProof,
126	)
127}