From 4498f175f1ea0b2c4c3f3ea1f508794eda3efc46 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Tue, 22 Nov 2022 16:50:43 -0800 Subject: [PATCH] added verifier_test --- go.mod | 2 +- go.sum | 4 +-- plonky2_verifier/plonk.go | 22 +++--------- plonky2_verifier/verifier.go | 19 ++++++++++ plonky2_verifier/verifier_test.go | 60 +++++++++++++++++++++++++++---- 5 files changed, 79 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 38a6172..58391ba 100644 --- a/go.mod +++ b/go.mod @@ -30,4 +30,4 @@ require ( // For now, use a forked version of gnark so that the emaulated fields are // mod'ed when printed. See here: https://github.com/kevjue/gnark/commit/0b216679a380b4b8d29f10dd96f34e8a5702463e -replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7 +replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60 diff --git a/go.sum b/go.sum index 9f05fe7..82aeb74 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,8 @@ github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 h1:8pyqKJvrJqUYaKS851Ule26pwWvey6IDMiczaBLDKLQ= github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7 h1:pU9438pFjuTjtDA4iV/oOPcdnzL7KelKXp4aHuqn2o4= -github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7/go.mod h1:iN7/IRE6Eu2QKnTJEsoS48suBV0O5XrM+Nzo1ipp6Zw= +github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60 h1:Z7hWN0/Spz1H18rBm9qpqzy0dX1/uWhGSMxMMEaruVY= +github.com/kevjue/gnark v0.7.2-0.20221123002814-bcc0d7d32d60/go.mod h1:iN7/IRE6Eu2QKnTJEsoS48suBV0O5XrM+Nzo1ipp6Zw= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= diff --git a/plonky2_verifier/plonk.go b/plonky2_verifier/plonk.go index e2416ea..8004770 100644 --- a/plonky2_verifier/plonk.go +++ b/plonky2_verifier/plonk.go @@ -174,20 +174,13 @@ func (p *PlonkChip) evalVanishingPoly(proofChallenges ProofChallenges, openings } vanishingTerms := append(vanishingZ1Terms, vanishingPartialProductsTerms...) + vanishingTerms = append(vanishingTerms, []QuadraticExtension{p.qeAPI.ZERO_QE, p.qeAPI.ZERO_QE, p.qeAPI.ZERO_QE, p.qeAPI.ZERO_QE}...) reducedValues := make([]QuadraticExtension, p.commonData.Config.NumChallenges) for i := uint64(0); i < p.commonData.Config.NumChallenges; i++ { reducedValues[i] = p.qeAPI.ZERO_QE } - // TODO: Enable this check once the custom gate evaluations are added to the - // vanishingTerms array - /* - if len(vanishingTerms) != int(p.commonData.QuotientDegreeFactor) { - panic("evalVanishingPoly: len(vanishingTerms) != int(p.commonData.QuotientDegreeFactor)") - } - */ - // reverse iterate the vanishingPartialProductsTerms array for i := len(vanishingTerms) - 1; i >= 0; i-- { for j := uint64(0); j < p.commonData.Config.NumChallenges; j++ { @@ -219,8 +212,8 @@ func (p *PlonkChip) Verify(proofChallenges ProofChallenges, openings OpeningSet) // So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each // `quotient_degree_factor`-sized chunk of the original evaluations. for i := 0; i < len(vanishingPolysZeta); i++ { - quotientPolysStartIdx := i * len(vanishingPolysZeta) - quotientPolysEndIdx := quotientPolysStartIdx + len(vanishingPolysZeta) + quotientPolysStartIdx := i * int(p.commonData.QuotientDegreeFactor) + quotientPolysEndIdx := quotientPolysStartIdx + int(p.commonData.QuotientDegreeFactor) prod := p.qeAPI.MulExtension( zHZeta, p.qeAPI.ReduceWithPowers( @@ -229,13 +222,6 @@ func (p *PlonkChip) Verify(proofChallenges ProofChallenges, openings OpeningSet) ), ) - // TODO: Uncomment this after adding in the custom gates evaluations - //p.qeAPI.AssertIsEqual(vanishingPolysZeta[i], prod) - - // For now, just put in a dummy equality check so that VS stops complaining about unused variables - p.qeAPI.AssertIsEqual( - p.qeAPI.MulExtension(vanishingPolysZeta[i], p.qeAPI.ZERO_QE), - p.qeAPI.MulExtension(prod, p.qeAPI.ZERO_QE), - ) + p.qeAPI.AssertIsEqual(vanishingPolysZeta[i], prod) } } diff --git a/plonky2_verifier/verifier.go b/plonky2_verifier/verifier.go index 21a5667..821d348 100644 --- a/plonky2_verifier/verifier.go +++ b/plonky2_verifier/verifier.go @@ -82,6 +82,25 @@ func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData V proofWithPis.Proof.QuotientPolysCap, } + // Seems like there is a bug in the emulated field code. + // Add ZERO to all of the fri challenges values to reduce them. + proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], ZERO_F).(F) + proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], ZERO_F).(F) + + proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], ZERO_F).(F) + proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], ZERO_F).(F) + + for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ { + proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], ZERO_F).(F) + proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], ZERO_F).(F) + } + + proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, ZERO_F).(F) + + for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndicies); i++ { + proofChallenges.FriChallenges.FriQueryIndicies[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndicies[i], ZERO_F).(F) + } + c.friChip.VerifyFriProof( commonData.GetFriInstance(c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits), proofWithPis.Proof.Openings.ToFriOpenings(), diff --git a/plonky2_verifier/verifier_test.go b/plonky2_verifier/verifier_test.go index f3604fc..59a1c4a 100644 --- a/plonky2_verifier/verifier_test.go +++ b/plonky2_verifier/verifier_test.go @@ -9,7 +9,7 @@ import ( "github.com/consensys/gnark/test" ) -type TestVerifierCircuit struct { +type TestVerifierChallengesCircuit struct { fieldAPI frontend.API `gnark:"-"` qeAPI *QuadraticExtensionAPI `gnark:"-"` hashAPI *HashAPI `gnark:"-"` @@ -35,7 +35,7 @@ type TestVerifierCircuit struct { verifierChip *VerifierChip } -func (c *TestVerifierCircuit) GetChallengesSanityCheck( +func (c *TestVerifierChallengesCircuit) GetChallengesSanityCheck( proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData, @@ -90,7 +90,7 @@ func (c *TestVerifierCircuit) GetChallengesSanityCheck( } } -func (c *TestVerifierCircuit) Define(api frontend.API) error { +func (c *TestVerifierChallengesCircuit) Define(api frontend.API) error { proofWithPis := DeserializeProofWithPublicInputs(c.proofWithPIsFilename) commonCircuitData := DeserializeCommonCircuitData(c.commonCircuitDataFilename) verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename) @@ -112,7 +112,7 @@ func TestFibonacciVerifierWitness(t *testing.T) { assert := test.NewAssert(t) testCase := func() { - circuit := TestVerifierCircuit{ + circuit := TestVerifierChallengesCircuit{ proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json", commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json", verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json", @@ -183,7 +183,7 @@ func TestFibonacciVerifierWitness(t *testing.T) { NewFieldElement(13636347200053048758), }, } - witness := TestVerifierCircuit{} + witness := TestVerifierChallengesCircuit{} err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) assert.NoError(err) } @@ -195,7 +195,7 @@ func TestDummyVerifierWitness(t *testing.T) { assert := test.NewAssert(t) testCase := func() { - circuit := TestVerifierCircuit{ + circuit := TestVerifierChallengesCircuit{ 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", @@ -279,10 +279,56 @@ func TestDummyVerifierWitness(t *testing.T) { NewFieldElement(11238419549114325157), }, } - witness := TestVerifierCircuit{} // No real witness as the test circuit's Define function will inject in the witness + witness := TestVerifierChallengesCircuit{} // 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() } + +type TestVerifierCircuit struct { + proofWithPIsFilename string `gnark:"-"` + commonCircuitDataFilename string `gnark:"-"` + verifierOnlyCircuitDataFilename string `gnark:"-"` +} + +func (c *TestVerifierCircuit) Define(api frontend.API) error { + proofWithPis := DeserializeProofWithPublicInputs(c.proofWithPIsFilename) + commonCircuitData := DeserializeCommonCircuitData(c.commonCircuitDataFilename) + verfierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename) + + fieldAPI := NewFieldAPI(api) + qeAPI := NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits) + hashAPI := NewHashAPI(fieldAPI) + poseidonChip := NewPoseidonChip(api, fieldAPI) + plonkChip := NewPlonkChip(api, qeAPI, commonCircuitData) + friChip := NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams) + verifierChip := VerifierChip{ + api: api, + fieldAPI: fieldAPI, + qeAPI: qeAPI, + poseidonChip: poseidonChip, + plonkChip: plonkChip, + friChip: friChip, + } + verifierChip.Verify(proofWithPis, verfierOnlyCircuitData, commonCircuitData) + return nil +} + +func TestDummyVerifier(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", + } + + witness := TestVerifierCircuit{} + err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField()) + assert.NoError(err) + } + testCase() +}