gnark-plonky2-verifier/plonky2_verifier/verifier_test.go
plonky2_verifier/verifier_test.goRaw
1package plonky2_verifier
2
3import (
4 . "gnark-plonky2-verifier/field"
5 . "gnark-plonky2-verifier/poseidon"
6 "testing"
7
8 "github.com/consensys/gnark/frontend"
9 "github.com/consensys/gnark/test"
10)
11
12type TestVerifierChallengesCircuit struct {
13 fieldAPI frontend.API `gnark:"-"`
14 qeAPI *QuadraticExtensionAPI `gnark:"-"`
15 hashAPI *HashAPI `gnark:"-"`
16
17 proofWithPIsFilename string `gnark:"-"`
18 commonCircuitDataFilename string `gnark:"-"`
19 verifierOnlyCircuitDataFilename string `gnark:"-"`
20
21 numChallenges uint64 `gnark:"-"`
22 numFriQueries uint64 `gnark:"-"`
23
24 t *testing.T `gnark:"-"`
25
26 expectedPublicInputsHash Hash
27 expectedPlonkBetas []F // slice length == num challenges
28 expectedPlonkGammas []F // slice length == num challenges
29 expectedPlonkAlphas []F // slice length == num challenges
30 expectedPlonkZeta QuadraticExtension
31 expectedFriAlpha QuadraticExtension
32 expectedFriBetas []QuadraticExtension // slice length == num fri rounds
33 expectedFriQueryIndices []F // slice length == num fri queries
34
35 verifierChip *VerifierChip
36}
37
38func (c *TestVerifierChallengesCircuit) GetChallengesSanityCheck(
39 proofWithPis ProofWithPublicInputs,
40 verifierData VerifierOnlyCircuitData,
41 commonData CommonCircuitData,
42) {
43 publicInputsHash := c.verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs)
44 proofChallenges := c.verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonData)
45
46 c.hashAPI.AssertIsEqualHash(publicInputsHash, c.expectedPublicInputsHash)
47
48 if len(proofChallenges.PlonkBetas) != int(c.numChallenges) {
49 c.t.Errorf("len(PlonkBetas) should equal numChallenges")
50 }
51 for i := 0; i < int(c.numChallenges); i++ {
52 c.fieldAPI.AssertIsEqual(proofChallenges.PlonkBetas[i], c.expectedPlonkBetas[i])
53 }
54
55 if len(proofChallenges.PlonkGammas) != int(c.numChallenges) {
56 c.t.Errorf("len(PlonkGammas) should equal numChallenges")
57 }
58 for i := 0; i < int(c.numChallenges); i++ {
59 c.fieldAPI.AssertIsEqual(proofChallenges.PlonkGammas[i], c.expectedPlonkGammas[i])
60 }
61
62 if len(proofChallenges.PlonkAlphas) != int(c.numChallenges) {
63 c.t.Errorf("len(PlonkAlphas) should equal numChallenges")
64 }
65 for i := 0; i < int(c.numChallenges); i++ {
66 c.fieldAPI.AssertIsEqual(proofChallenges.PlonkAlphas[i], c.expectedPlonkAlphas[i])
67 }
68
69 c.qeAPI.AssertIsEqual(proofChallenges.PlonkZeta, c.expectedPlonkZeta)
70
71 c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriAlpha, c.expectedFriAlpha)
72
73 if len(proofChallenges.FriChallenges.FriBetas) != len(commonData.FriParams.ReductionArityBits) {
74 c.t.Errorf("len(PlonkAlphas) should equal num fri rounds")
75 }
76 for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ {
77 c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriBetas[i], c.expectedFriBetas[i])
78 }
79
80 // This test is commented out because pow_witness is randomized between runs of the prover.
81 // expectedPowResponse := NewFieldElementFromString("92909863298412")
82 // c.field.AssertIsEqual(proofChallenges.FriChallenges.FriPowResponse, expectedPowResponse)
83
84 if len(proofChallenges.FriChallenges.FriQueryIndicies) != int(c.numFriQueries) {
85 c.t.Errorf("len(expectedFriQueryIndices) should equal num fri queries")
86 }
87
88 for i := 0; i < int(c.numFriQueries); i++ {
89 c.fieldAPI.AssertIsEqual(c.expectedFriQueryIndices[i], proofChallenges.FriChallenges.FriQueryIndicies[i])
90 }
91}
92
93func (c *TestVerifierChallengesCircuit) Define(api frontend.API) error {
94 proofWithPis := DeserializeProofWithPublicInputs(c.proofWithPIsFilename)
95 commonCircuitData := DeserializeCommonCircuitData(c.commonCircuitDataFilename)
96 verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename)
97
98 c.numChallenges = commonCircuitData.Config.NumChallenges
99 c.numFriQueries = commonCircuitData.FriParams.Config.NumQueryRounds
100
101 c.fieldAPI = NewFieldAPI(api)
102 c.qeAPI = NewQuadraticExtensionAPI(c.fieldAPI, commonCircuitData.DegreeBits)
103 c.hashAPI = NewHashAPI(c.fieldAPI)
104 poseidonChip := NewPoseidonChip(api, c.fieldAPI, c.qeAPI)
105 c.verifierChip = &VerifierChip{api: api, fieldAPI: c.fieldAPI, qeAPI: c.qeAPI, poseidonChip: poseidonChip}
106
107 c.GetChallengesSanityCheck(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
108 return nil
109}
110
111func TestFibonacciVerifierWitness(t *testing.T) {
112 assert := test.NewAssert(t)
113
114 testCase := func() {
115 circuit := TestVerifierChallengesCircuit{
116 proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json",
117 commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json",
118 verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json",
119 t: t,
120
121 expectedPublicInputsHash: Hash{
122 NewFieldElementFromString("8416658900775745054"),
123 NewFieldElementFromString("12574228347150446423"),
124 NewFieldElementFromString("9629056739760131473"),
125 NewFieldElementFromString("3119289788404190010"),
126 },
127
128 expectedPlonkBetas: []F{
129 NewFieldElementFromString("4678728155650926271"),
130 NewFieldElementFromString("13611962404289024887"),
131 },
132
133 expectedPlonkGammas: []F{
134 NewFieldElementFromString("13237663823305715949"),
135 NewFieldElementFromString("15389314098328235145"),
136 },
137
138 expectedPlonkAlphas: []F{
139 NewFieldElementFromString("14505919539124304197"),
140 NewFieldElementFromString("1695455639263736117"),
141 },
142
143 expectedPlonkZeta: QuadraticExtension{
144 NewFieldElementFromString("14887793628029982930"),
145 NewFieldElementFromString("1136137158284059037"),
146 },
147
148 expectedFriAlpha: QuadraticExtension{
149 NewFieldElementFromString("14641715242626918707"),
150 NewFieldElementFromString("10574243340537902930"),
151 },
152
153 expectedFriBetas: []QuadraticExtension{},
154
155 expectedFriQueryIndices: []F{
156 NewFieldElement(6790812084677375942),
157 NewFieldElement(12394212020331474798),
158 NewFieldElement(16457600747000998582),
159 NewFieldElement(1543271328932331916),
160 NewFieldElement(12115726870906958644),
161 NewFieldElement(6775897107605342797),
162 NewFieldElement(15989401564746021030),
163 NewFieldElement(10691676456016926845),
164 NewFieldElement(1632499470630032007),
165 NewFieldElement(1317292355445098328),
166 NewFieldElement(18391440812534384252),
167 NewFieldElement(17321705613231354333),
168 NewFieldElement(6176487551308859603),
169 NewFieldElement(7119835651572002873),
170 NewFieldElement(3903019169623116693),
171 NewFieldElement(4886491111111487546),
172 NewFieldElement(4087641893164620518),
173 NewFieldElement(13801643080324181364),
174 NewFieldElement(16993775312274189321),
175 NewFieldElement(9268202926222765679),
176 NewFieldElement(10683001302406181735),
177 NewFieldElement(13359465725531647963),
178 NewFieldElement(4523327590105620849),
179 NewFieldElement(4883588003760409588),
180 NewFieldElement(187699146998097671),
181 NewFieldElement(14489263557623716717),
182 NewFieldElement(11748359318238148146),
183 NewFieldElement(13636347200053048758),
184 },
185 }
186 witness := TestVerifierChallengesCircuit{}
187 err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
188 assert.NoError(err)
189 }
190
191 testCase()
192}
193
194func TestDummyVerifierWitness(t *testing.T) {
195 assert := test.NewAssert(t)
196
197 testCase := func() {
198 circuit := TestVerifierChallengesCircuit{
199 proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
200 commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
201 verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
202 t: t,
203
204 expectedPublicInputsHash: Hash{
205 NewFieldElementFromString("0"),
206 NewFieldElementFromString("0"),
207 NewFieldElementFromString("0"),
208 NewFieldElementFromString("0"),
209 },
210
211 expectedPlonkBetas: []F{
212 NewFieldElementFromString("11216469004148781751"),
213 NewFieldElementFromString("6201977337075152249"),
214 },
215
216 expectedPlonkGammas: []F{
217 NewFieldElementFromString("8369751006669847974"),
218 NewFieldElementFromString("3610024170884289835"),
219 },
220
221 expectedPlonkAlphas: []F{
222 NewFieldElementFromString("970160439138448145"),
223 NewFieldElementFromString("2402201283787401921"),
224 },
225
226 expectedPlonkZeta: QuadraticExtension{
227 NewFieldElementFromString("17377750363769967882"),
228 NewFieldElementFromString("11921191651424768462"),
229 },
230
231 expectedFriAlpha: QuadraticExtension{
232 NewFieldElementFromString("16721004555774385479"),
233 NewFieldElementFromString("10688151135543754663"),
234 },
235
236 expectedFriBetas: []QuadraticExtension{
237 {
238 NewFieldElementFromString("3312441922957827805"),
239 NewFieldElementFromString("15128092514958289671"),
240 },
241 {
242 NewFieldElementFromString("13630530769060141802"),
243 NewFieldElementFromString("14559883974933163008"),
244 },
245 {
246 NewFieldElementFromString("16146508250083930687"),
247 NewFieldElementFromString("5176346568444408396"),
248 },
249 },
250
251 expectedFriQueryIndices: []F{
252 NewFieldElement(16334967868590615051),
253 NewFieldElement(2911473540496037915),
254 NewFieldElement(14887216056886344225),
255 NewFieldElement(7808811227805914295),
256 NewFieldElement(2018594961417375749),
257 NewFieldElement(3733368398777208435),
258 NewFieldElement(2623035669037055104),
259 NewFieldElement(299243030573481514),
260 NewFieldElement(7189789717962704433),
261 NewFieldElement(14566344026886816268),
262 NewFieldElement(12555390069003437453),
263 NewFieldElement(17225508403199418233),
264 NewFieldElement(5088797913879903292),
265 NewFieldElement(9715691392773433023),
266 NewFieldElement(7565836764713256165),
267 NewFieldElement(1500143546029322929),
268 NewFieldElement(1245802417104422080),
269 NewFieldElement(6831959786661245110),
270 NewFieldElement(17271054758535453780),
271 NewFieldElement(6225460404576395409),
272 NewFieldElement(15932661092896277351),
273 NewFieldElement(12452534049198240575),
274 NewFieldElement(4225199666055520177),
275 NewFieldElement(13235091290587791090),
276 NewFieldElement(2562357622728700774),
277 NewFieldElement(17676678042980201498),
278 NewFieldElement(5837067135702409874),
279 NewFieldElement(11238419549114325157),
280 },
281 }
282 witness := TestVerifierChallengesCircuit{} // No real witness as the test circuit's Define function will inject in the witness
283 err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
284 assert.NoError(err)
285 }
286
287 testCase()
288}
289
290type TestVerifierCircuit struct {
291 proofWithPIsFilename string `gnark:"-"`
292 commonCircuitDataFilename string `gnark:"-"`
293 verifierOnlyCircuitDataFilename string `gnark:"-"`
294}
295
296func (c *TestVerifierCircuit) Define(api frontend.API) error {
297 proofWithPis := DeserializeProofWithPublicInputs(c.proofWithPIsFilename)
298 commonCircuitData := DeserializeCommonCircuitData(c.commonCircuitDataFilename)
299 verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename)
300
301 fieldAPI := NewFieldAPI(api)
302 qeAPI := NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
303 hashAPI := NewHashAPI(fieldAPI)
304 poseidonChip := NewPoseidonChip(api, fieldAPI, qeAPI)
305 plonkChip := NewPlonkChip(api, qeAPI, commonCircuitData)
306 friChip := NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams)
307 verifierChip := VerifierChip{
308 api: api,
309 fieldAPI: fieldAPI,
310 qeAPI: qeAPI,
311 poseidonChip: poseidonChip,
312 plonkChip: plonkChip,
313 friChip: friChip,
314 }
315 verifierChip.Verify(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
316 return nil
317}
318
319func TestDummyVerifier(t *testing.T) {
320 assert := test.NewAssert(t)
321
322 testCase := func() {
323 circuit := TestVerifierCircuit{
324 proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
325 commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
326 verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
327 }
328
329 witness := TestVerifierCircuit{}
330 err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
331 assert.NoError(err)
332 }
333 testCase()
334}