diff --git a/plonky2_verifier/challenger.go b/plonky2_verifier/challenger.go index 955c4be..8ec47dd 100644 --- a/plonky2_verifier/challenger.go +++ b/plonky2_verifier/challenger.go @@ -11,13 +11,13 @@ import ( type ChallengerChip struct { api frontend.API field frontend.API - poseidonChip poseidon.PoseidonChip + poseidonChip *poseidon.PoseidonChip spongeState [poseidon.SPONGE_WIDTH]F inputBuffer []F outputBuffer []F } -func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip poseidon.PoseidonChip) *ChallengerChip { +func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip *poseidon.PoseidonChip) *ChallengerChip { var spongeState [poseidon.SPONGE_WIDTH]F var inputBuffer []F var outputBuffer []F diff --git a/plonky2_verifier/challenger_test.go b/plonky2_verifier/challenger_test.go index e1bdb8f..1ad0ed9 100644 --- a/plonky2_verifier/challenger_test.go +++ b/plonky2_verifier/challenger_test.go @@ -22,7 +22,7 @@ type TestChallengerCircuit struct { func (circuit *TestChallengerCircuit) Define(api frontend.API) error { field := field.NewFieldAPI(api) poseidonChip := NewPoseidonChip(api, field) - challengerChip := NewChallengerChip(api, field, *poseidonChip) + challengerChip := NewChallengerChip(api, field, poseidonChip) var circuitDigest [4]F for i := 0; i < len(circuitDigest); i++ { diff --git a/plonky2_verifier/fri.go b/plonky2_verifier/fri.go index 365cde4..fe5cbda 100644 --- a/plonky2_verifier/fri.go +++ b/plonky2_verifier/fri.go @@ -17,6 +17,7 @@ type FriChip struct { api frontend.API fieldAPI frontend.API qeAPI *QuadraticExtensionAPI + hashAPI *HashAPI poseidonChip *poseidon.PoseidonChip @@ -24,7 +25,14 @@ type FriChip struct { verifierOnlyCircuitData *VerifierOnlyCircuitData } -func NewFriChip(api frontend.API, fieldAPI frontend.API, qeAPI *QuadraticExtensionAPI, poseidonChip *poseidon.PoseidonChip, friParams *FriParams) *FriChip { +func NewFriChip( + api frontend.API, + fieldAPI frontend.API, + qeAPI *QuadraticExtensionAPI, + hashAPI *HashAPI, + poseidonChip *poseidon.PoseidonChip, + friParams *FriParams, +) *FriChip { return &FriChip{ api: api, fieldAPI: fieldAPI, @@ -113,7 +121,7 @@ func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []F, leafIndexBits rightHashCompress[2] = rightHash[2] rightHashCompress[3] = rightHash[3] - currentDigest = SelectHash(f.fieldAPI, bit, leftHashCompress, rightHashCompress) + currentDigest = f.hashAPI.SelectHash(bit, leftHashCompress, rightHashCompress) } // We assume that the cap_height is 4. Create two levels of the Lookup2 circuit @@ -131,15 +139,15 @@ func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []F, leafIndexBits // First create the "leaf" lookup2 circuits // The will use the least significant bits of the capIndexBits array for i := 0; i < NUM_LEAF_LOOKUPS; i++ { - leafLookups[i] = Lookup2Hash( - f.fieldAPI, capIndexBits[0], capIndexBits[1], + leafLookups[i] = f.hashAPI.Lookup2Hash( + capIndexBits[0], capIndexBits[1], merkleCap[i*NUM_LEAF_LOOKUPS], merkleCap[i*NUM_LEAF_LOOKUPS+1], merkleCap[i*NUM_LEAF_LOOKUPS+2], merkleCap[i*NUM_LEAF_LOOKUPS+3], ) } // Use the most 2 significant bits of the capIndexBits array for the "root" lookup - merkleCapEntry := Lookup2Hash(f.fieldAPI, capIndexBits[2], capIndexBits[3], leafLookups[0], leafLookups[1], leafLookups[2], leafLookups[3]) - AssertIsEqualHash(f.fieldAPI, currentDigest, merkleCapEntry) + merkleCapEntry := f.hashAPI.Lookup2Hash(capIndexBits[2], capIndexBits[3], leafLookups[0], leafLookups[1], leafLookups[2], leafLookups[3]) + f.hashAPI.AssertIsEqualHash(currentDigest, merkleCapEntry) } func (f *FriChip) verifyInitialProof(xIndexBits []frontend.Variable, proof *FriInitialTreeProof, initialMerkleCaps []MerkleCap, capIndexBits []frontend.Variable) { diff --git a/plonky2_verifier/fri_test.go b/plonky2_verifier/fri_test.go index 356bcb6..f4f45e8 100644 --- a/plonky2_verifier/fri_test.go +++ b/plonky2_verifier/fri_test.go @@ -18,8 +18,9 @@ func (circuit *TestFibonacciFriCircuit) Define(api frontend.API) error { field := NewFieldAPI(api) qe := NewQuadraticExtensionAPI(field, commonCircuitData.DegreeBits) + hash := NewHashAPI(field) poseidonChip := poseidon.NewPoseidonChip(api, field) - friChip := NewFriChip(api, field, qe, poseidonChip, &commonCircuitData.FriParams) + friChip := NewFriChip(api, field, qe, hash, poseidonChip, &commonCircuitData.FriParams) zeta := QuadraticExtension{ NewFieldElementFromString("14887793628029982930"), @@ -104,8 +105,9 @@ func (circuit *TestLargeDummyFriCircuit) Define(api frontend.API) error { field := NewFieldAPI(api) qe := NewQuadraticExtensionAPI(field, commonCircuitData.DegreeBits) + hash := NewHashAPI(field) poseidonChip := poseidon.NewPoseidonChip(api, field) - friChip := NewFriChip(api, field, qe, poseidonChip, &commonCircuitData.FriParams) + friChip := NewFriChip(api, field, qe, hash, poseidonChip, &commonCircuitData.FriParams) zeta := QuadraticExtension{ NewFieldElementFromString("17377750363769967882"), diff --git a/plonky2_verifier/hash.go b/plonky2_verifier/hash.go index b6bca3c..47dbc4d 100644 --- a/plonky2_verifier/hash.go +++ b/plonky2_verifier/hash.go @@ -7,34 +7,46 @@ import ( "github.com/consensys/gnark/frontend" ) -func SelectHash(fieldAPI frontend.API, bit frontend.Variable, leftHash, rightHash Hash) Hash { +type HashAPI struct { + fieldAPI frontend.API +} + +func NewHashAPI( + fieldAPI frontend.API, +) *HashAPI { + return &HashAPI{ + fieldAPI: fieldAPI, + } +} + +func (h *HashAPI) SelectHash(bit frontend.Variable, leftHash, rightHash Hash) Hash { var returnHash Hash for i := 0; i < 4; i++ { - returnHash[i] = fieldAPI.Select(bit, leftHash[i], rightHash[i]).(F) + returnHash[i] = h.fieldAPI.Select(bit, leftHash[i], rightHash[i]).(F) } return returnHash } -func Lookup2Hash(fieldAPI frontend.API, b0 frontend.Variable, b1 frontend.Variable, h0, h1, h2, h3 Hash) Hash { +func (h *HashAPI) Lookup2Hash(b0 frontend.Variable, b1 frontend.Variable, h0, h1, h2, h3 Hash) Hash { var returnHash Hash for i := 0; i < 4; i++ { - returnHash[i] = fieldAPI.Lookup2(b0, b1, h0[i], h1[i], h2[i], h3[i]).(F) + returnHash[i] = h.fieldAPI.Lookup2(b0, b1, h0[i], h1[i], h2[i], h3[i]).(F) } return returnHash } -func AssertIsEqualHash(fieldAPI frontend.API, h1, h2 Hash) { +func (h *HashAPI) AssertIsEqualHash(h1, h2 Hash) { for i := 0; i < 4; i++ { - fieldAPI.AssertIsEqual(h1[0], h2[0]) + h.fieldAPI.AssertIsEqual(h1[0], h2[0]) } } -func PrintHash(f frontend.API, h Hash) { +func (h *HashAPI) PrintHash(hash Hash) { for i := 0; i < 4; i++ { fmt.Println("Hash Limb", i) - f.Println(h[i]) + h.fieldAPI.Println(hash[i]) } } diff --git a/plonky2_verifier/verifier.go b/plonky2_verifier/verifier.go index 54bdf8c..21a5667 100644 --- a/plonky2_verifier/verifier.go +++ b/plonky2_verifier/verifier.go @@ -1,7 +1,6 @@ package plonky2_verifier import ( - "fmt" . "gnark-ed25519/field" "gnark-ed25519/poseidon" @@ -10,8 +9,22 @@ import ( type VerifierChip struct { api frontend.API - field frontend.API - poseidonChip poseidon.PoseidonChip + fieldAPI frontend.API + qeAPI *QuadraticExtensionAPI + poseidonChip *poseidon.PoseidonChip + plonkChip *PlonkChip + friChip *FriChip +} + +func NewVerifierChip(api frontend.API, fieldAPI frontend.API, qeAPI *QuadraticExtensionAPI, poseidonChip *poseidon.PoseidonChip, plonkChip *PlonkChip, friChip *FriChip) *VerifierChip { + return &VerifierChip{ + api: api, + fieldAPI: fieldAPI, + qeAPI: qeAPI, + poseidonChip: poseidonChip, + plonkChip: plonkChip, + friChip: friChip, + } } func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) Hash { @@ -21,7 +34,7 @@ func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) Hash { func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) ProofChallenges { config := commonData.Config numChallenges := config.NumChallenges - challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) + challenger := NewChallengerChip(c.api, c.fieldAPI, c.poseidonChip) var circuitDigest = commonData.CircuitDigest @@ -59,5 +72,21 @@ func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData V publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) - fmt.Printf("%+v\n", proofChallenges) + + c.plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings) + + initialMerkleCaps := []MerkleCap{ + verifierData.ConstantSigmasCap, + proofWithPis.Proof.WiresCap, + proofWithPis.Proof.PlonkZsPartialProductsCap, + proofWithPis.Proof.QuotientPolysCap, + } + + c.friChip.VerifyFriProof( + commonData.GetFriInstance(c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits), + proofWithPis.Proof.Openings.ToFriOpenings(), + &proofChallenges.FriChallenges, + initialMerkleCaps, + &proofWithPis.Proof.OpeningProof, + ) } diff --git a/plonky2_verifier/verifier_test.go b/plonky2_verifier/verifier_test.go index 9516ed1..63572a1 100644 --- a/plonky2_verifier/verifier_test.go +++ b/plonky2_verifier/verifier_test.go @@ -9,132 +9,180 @@ import ( "github.com/consensys/gnark/test" ) -type TestVerifierCircuit struct{} +type TestVerifierCircuit struct { + fieldAPI frontend.API `gnark:"-"` + qeAPI *QuadraticExtensionAPI `gnark:"-"` + hashAPI *HashAPI `gnark:"-"` -func (c *VerifierChip) GetChallengesSanityCheck(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { - publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) - proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) + proofWithPIsFilename string `gnark:"-"` + commonCircuitDataFilename string `gnark:"-"` + verifierOnlyCircuitDataFilename string `gnark:"-"` - expectedPublicInputsHash := [4]F{ - NewFieldElementFromString("8416658900775745054"), - NewFieldElementFromString("12574228347150446423"), - NewFieldElementFromString("9629056739760131473"), - NewFieldElementFromString("3119289788404190010"), - } + numChallenges uint64 `gnark:"-"` + numFriQueries uint64 `gnark:"-"` - for i := 0; i < 4; i++ { - c.field.AssertIsEqual(publicInputsHash[i], expectedPublicInputsHash[i]) - } + t *testing.T `gnark:"-"` - expectedPlonkBetas := [2]F{ - NewFieldElementFromString("4678728155650926271"), - NewFieldElementFromString("13611962404289024887"), - } + expectedPublicInputsHash Hash + expectedPlonkBetas []F // slice length == num challenges + expectedPlonkGammas []F // slice length == num challenges + expectedPlonkAlphas []F // slice length == num challenges + expectedPlonkZeta QuadraticExtension + expectedFriAlpha QuadraticExtension + expectedFriBetas []QuadraticExtension // slice length == num fri rounds + expectedFriQueryIndices []F // slice length == num fri queries - for i := 0; i < 2; i++ { - c.field.AssertIsEqual(proofChallenges.PlonkBetas[i], expectedPlonkBetas[i]) - } + verifierChip *VerifierChip +} - expectedPlonkGammas := [2]F{ - NewFieldElementFromString("13237663823305715949"), - NewFieldElementFromString("15389314098328235145"), - } +func (c *TestVerifierCircuit) GetChallengesSanityCheck( + proofWithPis ProofWithPublicInputs, + verifierData VerifierOnlyCircuitData, + commonData CommonCircuitData, +) { + publicInputsHash := c.verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs) + proofChallenges := c.verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonData) - for i := 0; i < 2; i++ { - c.field.AssertIsEqual(proofChallenges.PlonkGammas[i], expectedPlonkGammas[i]) - } + c.hashAPI.AssertIsEqualHash(publicInputsHash, c.expectedPublicInputsHash) - expectedPlonkAlphas := [2]F{ - NewFieldElementFromString("14505919539124304197"), - NewFieldElementFromString("1695455639263736117"), + if len(proofChallenges.PlonkBetas) != int(c.numChallenges) { + c.t.Errorf("len(PlonkBetas) should equal numChallenges") } - - for i := 0; i < 2; i++ { - c.field.AssertIsEqual(proofChallenges.PlonkAlphas[i], expectedPlonkAlphas[i]) + for i := 0; i < int(c.numChallenges); i++ { + c.fieldAPI.AssertIsEqual(proofChallenges.PlonkBetas[i], c.expectedPlonkBetas[i]) } - expectedPlonkZetas := [2]F{ - NewFieldElementFromString("14887793628029982930"), - NewFieldElementFromString("1136137158284059037"), + if len(proofChallenges.PlonkGammas) != int(c.numChallenges) { + c.t.Errorf("len(PlonkGammas) should equal numChallenges") } - - for i := 0; i < 2; i++ { - c.field.AssertIsEqual(proofChallenges.PlonkZeta[i], expectedPlonkZetas[i]) + for i := 0; i < int(c.numChallenges); i++ { + c.fieldAPI.AssertIsEqual(proofChallenges.PlonkGammas[i], c.expectedPlonkGammas[i]) } - expectedFriAlpha := [2]F{ - NewFieldElementFromString("14641715242626918707"), - NewFieldElementFromString("10574243340537902930"), + if len(proofChallenges.PlonkAlphas) != int(c.numChallenges) { + c.t.Errorf("len(PlonkAlphas) should equal numChallenges") } - - for i := 0; i < 2; i++ { - c.field.AssertIsEqual(proofChallenges.FriChallenges.FriAlpha[i], expectedFriAlpha[i]) + for i := 0; i < int(c.numChallenges); i++ { + c.fieldAPI.AssertIsEqual(proofChallenges.PlonkAlphas[i], c.expectedPlonkAlphas[i]) } - if len(proofChallenges.FriChallenges.FriBetas) != 0 { - panic("There should be no fri betas") + c.qeAPI.AssertIsEqual(proofChallenges.PlonkZeta, c.expectedPlonkZeta) + + c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriAlpha, c.expectedFriAlpha) + + if len(proofChallenges.FriChallenges.FriBetas) != len(commonData.FriParams.ReductionArityBits) { + c.t.Errorf("len(PlonkAlphas) should equal num fri rounds") + } + for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ { + c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriBetas[i], c.expectedFriBetas[i]) } // This test is commented out because pow_witness is randomized between runs of the prover. // expectedPowResponse := NewFieldElementFromString("92909863298412") // c.field.AssertIsEqual(proofChallenges.FriChallenges.FriPowResponse, expectedPowResponse) - expectedFriQueryIndices := [...]F{ - NewFieldElement(6790812084677375942), - NewFieldElement(12394212020331474798), - NewFieldElement(16457600747000998582), - NewFieldElement(1543271328932331916), - NewFieldElement(12115726870906958644), - NewFieldElement(6775897107605342797), - NewFieldElement(15989401564746021030), - NewFieldElement(10691676456016926845), - NewFieldElement(1632499470630032007), - NewFieldElement(1317292355445098328), - NewFieldElement(18391440812534384252), - NewFieldElement(17321705613231354333), - NewFieldElement(6176487551308859603), - NewFieldElement(7119835651572002873), - NewFieldElement(3903019169623116693), - NewFieldElement(4886491111111487546), - NewFieldElement(4087641893164620518), - NewFieldElement(13801643080324181364), - NewFieldElement(16993775312274189321), - NewFieldElement(9268202926222765679), - NewFieldElement(10683001302406181735), - NewFieldElement(13359465725531647963), - NewFieldElement(4523327590105620849), - NewFieldElement(4883588003760409588), - NewFieldElement(187699146998097671), - NewFieldElement(14489263557623716717), - NewFieldElement(11748359318238148146), - NewFieldElement(13636347200053048758), - } - - if len(expectedFriQueryIndices) != len(proofChallenges.FriChallenges.FriQueryIndicies) { - panic("len(expectedFriQueryIndices) != len(proofChallenges.FriChallenges.FriQueryIndicies)") + if len(proofChallenges.FriChallenges.FriQueryIndicies) != int(c.numFriQueries) { + c.t.Errorf("len(expectedFriQueryIndices) should equal num fri queries") } - for i := 0; i < len(expectedFriQueryIndices); i++ { - c.field.AssertIsEqual(expectedFriQueryIndices[i], proofChallenges.FriChallenges.FriQueryIndicies[i]) + for i := 0; i < int(c.numFriQueries); i++ { + c.fieldAPI.AssertIsEqual(c.expectedFriQueryIndices[i], proofChallenges.FriChallenges.FriQueryIndicies[i]) } } -func (circuit *TestVerifierCircuit) Define(api frontend.API) error { - field := NewFieldAPI(api) - poseidonChip := NewPoseidonChip(api, field) - verifierChip := VerifierChip{api: api, field: field, poseidonChip: *poseidonChip} - proofWithPis := DeserializeProofWithPublicInputs("./data/fibonacci/proof_with_public_inputs.json") - commonCircuitData := DeserializeCommonCircuitData("./data/fibonacci/common_circuit_data.json") - verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./data/fibonacci/verifier_only_circuit_data.json") - verifierChip.GetChallengesSanityCheck(proofWithPis, verfierOnlyCircuitData, commonCircuitData) +func (c *TestVerifierCircuit) Define(api frontend.API) error { + proofWithPis := DeserializeProofWithPublicInputs(c.proofWithPIsFilename) + commonCircuitData := DeserializeCommonCircuitData(c.commonCircuitDataFilename) + verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename) + + c.numChallenges = commonCircuitData.Config.NumChallenges + c.numFriQueries = commonCircuitData.FriParams.Config.NumQueryRounds + + c.fieldAPI = NewFieldAPI(api) + c.qeAPI = NewQuadraticExtensionAPI(c.fieldAPI, commonCircuitData.DegreeBits) + c.hashAPI = NewHashAPI(c.fieldAPI) + poseidonChip := NewPoseidonChip(api, c.fieldAPI) + c.verifierChip = &VerifierChip{api: api, fieldAPI: c.fieldAPI, qeAPI: c.qeAPI, poseidonChip: poseidonChip} + + c.GetChallengesSanityCheck(proofWithPis, verfierOnlyCircuitData, commonCircuitData) return nil } -func TestVerifierWitness(t *testing.T) { +func TestFibonacciVerifierWitness(t *testing.T) { assert := test.NewAssert(t) testCase := func() { - circuit := TestVerifierCircuit{} + circuit := TestVerifierCircuit{ + proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json", + commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json", + verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json", + t: t, + + expectedPublicInputsHash: Hash{ + NewFieldElementFromString("8416658900775745054"), + NewFieldElementFromString("12574228347150446423"), + NewFieldElementFromString("9629056739760131473"), + NewFieldElementFromString("3119289788404190010"), + }, + + expectedPlonkBetas: []F{ + NewFieldElementFromString("4678728155650926271"), + NewFieldElementFromString("13611962404289024887"), + }, + + expectedPlonkGammas: []F{ + NewFieldElementFromString("13237663823305715949"), + NewFieldElementFromString("15389314098328235145"), + }, + + expectedPlonkAlphas: []F{ + NewFieldElementFromString("14505919539124304197"), + NewFieldElementFromString("1695455639263736117"), + }, + + expectedPlonkZeta: QuadraticExtension{ + NewFieldElementFromString("14887793628029982930"), + NewFieldElementFromString("1136137158284059037"), + }, + + expectedFriAlpha: QuadraticExtension{ + NewFieldElementFromString("14641715242626918707"), + NewFieldElementFromString("10574243340537902930"), + }, + + expectedFriBetas: []QuadraticExtension{}, + + expectedFriQueryIndices: []F{ + NewFieldElement(6790812084677375942), + NewFieldElement(12394212020331474798), + NewFieldElement(16457600747000998582), + NewFieldElement(1543271328932331916), + NewFieldElement(12115726870906958644), + NewFieldElement(6775897107605342797), + NewFieldElement(15989401564746021030), + NewFieldElement(10691676456016926845), + NewFieldElement(1632499470630032007), + NewFieldElement(1317292355445098328), + NewFieldElement(18391440812534384252), + NewFieldElement(17321705613231354333), + NewFieldElement(6176487551308859603), + NewFieldElement(7119835651572002873), + NewFieldElement(3903019169623116693), + NewFieldElement(4886491111111487546), + NewFieldElement(4087641893164620518), + NewFieldElement(13801643080324181364), + NewFieldElement(16993775312274189321), + NewFieldElement(9268202926222765679), + NewFieldElement(10683001302406181735), + NewFieldElement(13359465725531647963), + NewFieldElement(4523327590105620849), + NewFieldElement(4883588003760409588), + NewFieldElement(187699146998097671), + NewFieldElement(14489263557623716717), + NewFieldElement(11748359318238148146), + NewFieldElement(13636347200053048758), + }, + } witness := TestVerifierCircuit{} err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) assert.NoError(err) @@ -142,3 +190,99 @@ func TestVerifierWitness(t *testing.T) { testCase() } + +func TestDummyVerifierWitness(t *testing.T) { + assert := test.NewAssert(t) + + testCase := func() { + circuit := TestVerifierCircuit{ + proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json", + commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json", + verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json", + t: t, + + expectedPublicInputsHash: Hash{ + NewFieldElementFromString("0"), + NewFieldElementFromString("0"), + NewFieldElementFromString("0"), + NewFieldElementFromString("0"), + }, + + expectedPlonkBetas: []F{ + NewFieldElementFromString("11216469004148781751"), + NewFieldElementFromString("6201977337075152249"), + }, + + expectedPlonkGammas: []F{ + NewFieldElementFromString("8369751006669847974"), + NewFieldElementFromString("3610024170884289835"), + }, + + expectedPlonkAlphas: []F{ + NewFieldElementFromString("970160439138448145"), + NewFieldElementFromString("2402201283787401921"), + }, + + expectedPlonkZeta: QuadraticExtension{ + NewFieldElementFromString("17377750363769967882"), + NewFieldElementFromString("11921191651424768462"), + }, + + expectedFriAlpha: QuadraticExtension{ + NewFieldElementFromString("16721004555774385479"), + NewFieldElementFromString("10688151135543754663"), + }, + + expectedFriBetas: []QuadraticExtension{ + { + NewFieldElementFromString("3312441922957827805"), + NewFieldElementFromString("15128092514958289671"), + }, + { + NewFieldElementFromString("13630530769060141802"), + NewFieldElementFromString("14559883974933163008"), + }, + { + NewFieldElementFromString("16146508250083930687"), + NewFieldElementFromString("5176346568444408396"), + }, + }, + + expectedFriQueryIndices: []F{ + NewFieldElement(92683), + NewFieldElement(71707), + NewFieldElement(113185), + NewFieldElement(5303), + NewFieldElement(69637), + NewFieldElement(52851), + NewFieldElement(130176), + NewFieldElement(130602), + NewFieldElement(17969), + NewFieldElement(49676), + NewFieldElement(50573), + NewFieldElement(73593), + NewFieldElement(97340), + NewFieldElement(42687), + NewFieldElement(66789), + NewFieldElement(12977), + NewFieldElement(66752), + NewFieldElement(28854), + NewFieldElement(89172), + NewFieldElement(73873), + NewFieldElement(66407), + NewFieldElement(62271), + NewFieldElement(40881), + NewFieldElement(130802), + NewFieldElement(13158), + NewFieldElement(13338), + NewFieldElement(8850), + NewFieldElement(120997), + }, + } + witness := TestVerifierCircuit{} // No real witness as the test circuit's Define function will inject in the witness + err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) + assert.NoError(err) + } + + testCase() +}