arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonky2_verifier/verifier.go
plonky2_verifier/verifier.goRaw
  1package plonky2_verifier
  2
  3import (
  4	. "gnark-plonky2-verifier/field"
  5	"gnark-plonky2-verifier/poseidon"
  6
  7	"github.com/consensys/gnark/frontend"
  8)
  9
 10type VerifierChip struct {
 11	api          frontend.API           `gnark:"-"`
 12	fieldAPI     frontend.API           `gnark:"-"`
 13	qeAPI        *QuadraticExtensionAPI `gnark:"-"`
 14	poseidonChip *poseidon.PoseidonChip
 15	plonkChip    *PlonkChip
 16	friChip      *FriChip
 17}
 18
 19func NewVerifierChip(api frontend.API, fieldAPI frontend.API, qeAPI *QuadraticExtensionAPI, poseidonChip *poseidon.PoseidonChip, plonkChip *PlonkChip, friChip *FriChip) *VerifierChip {
 20	return &VerifierChip{
 21		api:          api,
 22		fieldAPI:     fieldAPI,
 23		qeAPI:        qeAPI,
 24		poseidonChip: poseidonChip,
 25		plonkChip:    plonkChip,
 26		friChip:      friChip,
 27	}
 28}
 29
 30func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) Hash {
 31	return c.poseidonChip.HashNoPad(publicInputs)
 32}
 33
 34func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) ProofChallenges {
 35	config := commonData.Config
 36	numChallenges := config.NumChallenges
 37	challenger := NewChallengerChip(c.api, c.fieldAPI, c.poseidonChip)
 38
 39	var circuitDigest = commonData.CircuitDigest
 40
 41	challenger.ObserveHash(circuitDigest)
 42	challenger.ObserveHash(publicInputsHash)
 43	challenger.ObserveCap(proofWithPis.Proof.WiresCap)
 44	plonkBetas := challenger.GetNChallenges(numChallenges)
 45	plonkGammas := challenger.GetNChallenges(numChallenges)
 46
 47	challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
 48	plonkAlphas := challenger.GetNChallenges(numChallenges)
 49
 50	challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
 51	plonkZeta := challenger.GetExtensionChallenge()
 52
 53	challenger.ObserveOpenings(proofWithPis.Proof.Openings.ToFriOpenings())
 54
 55	return ProofChallenges{
 56		PlonkBetas:  plonkBetas,
 57		PlonkGammas: plonkGammas,
 58		PlonkAlphas: plonkAlphas,
 59		PlonkZeta:   plonkZeta,
 60		FriChallenges: challenger.GetFriChallenges(
 61			proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
 62			proofWithPis.Proof.OpeningProof.FinalPoly,
 63			proofWithPis.Proof.OpeningProof.PowWitness,
 64			commonData.DegreeBits,
 65			config.FriConfig,
 66		),
 67	}
 68}
 69
 70func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) {
 71	// TODO: Verify shape of the proof?
 72
 73	publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
 74	proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData)
 75
 76	c.plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
 77
 78	initialMerkleCaps := []MerkleCap{
 79		verifierData.ConstantSigmasCap,
 80		proofWithPis.Proof.WiresCap,
 81		proofWithPis.Proof.PlonkZsPartialProductsCap,
 82		proofWithPis.Proof.QuotientPolysCap,
 83	}
 84
 85	// Seems like there is a bug in the emulated field code.
 86	// Add ZERO to all of the fri challenges values to reduce them.
 87	proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], ZERO_F).(F)
 88	proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], ZERO_F).(F)
 89
 90	proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], ZERO_F).(F)
 91	proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], ZERO_F).(F)
 92
 93	for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
 94		proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], ZERO_F).(F)
 95		proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], ZERO_F).(F)
 96	}
 97
 98	proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, ZERO_F).(F)
 99
100	for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndicies); i++ {
101		proofChallenges.FriChallenges.FriQueryIndicies[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndicies[i], ZERO_F).(F)
102	}
103
104	c.friChip.VerifyFriProof(
105		commonData.GetFriInstance(c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits),
106		proofWithPis.Proof.Openings.ToFriOpenings(),
107		&proofChallenges.FriChallenges,
108		initialMerkleCaps,
109		&proofWithPis.Proof.OpeningProof,
110	)
111}