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}