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