arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
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)
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)
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}