arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
range check inputted plonky2 proof (#29)

* gl

* stage 1 optimizations

* working optimized poseidon

* Fix posedion tests

* in progress gate type refactor

* working gates

* working e2e

* hm'

* hm2

* debug saga continues

* more debugging cry

* more debug

* it finally works

* optimizations

* more optimizations

* new changes

* more optimizations

* more cleanup

* some refactoring

* new files

* flattening of packages

* working commit

* more refactor

* more flattening

* more flattening

* more more refactor

* more optimizations

* more optimizations

* more optimizations

* plonk benchmark

* plonk

* fix r1cs

* resolve kevin's comments

* Update goldilocks/base.go

Co-authored-by: Kevin Jue <kjue235@gmail.com>

* Update goldilocks/base.go

Co-authored-by: Kevin Jue <kjue235@gmail.com>

* Update goldilocks/base.go

Co-authored-by: Kevin Jue <kjue235@gmail.com>

* Update goldilocks/quadratic_extension.go

Co-authored-by: Kevin Jue <kjue235@gmail.com>

* added range check for the inputted proof

* removed the go.mod replace directive

* removed some hacky code

* removed duplicate import

* renamed rangecheckQEVariable to rangecheckQE

* resolved conflict

---------

Co-authored-by: John Guibas <john@succinct.xyz>
Kevin Jue kjue235@gmail.com
Mon, 24 Jul 2023 16:18:37 -0700
commit

7bd0035e65e3e1b198604cf07779e2c95475df04

parent

b670530e7f02b42443d0c0616f203fb5871ba92c

3 files changed, 73 insertions(+), 30 deletions(-)

jump to
M go.mod → go.mod

@@ -28,6 +28,4 @@ golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect

golang.org/x/sys v0.5.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect -) - -// replace github.com/consensys/gnark => /Users/kevin/succinctlabs/gnark +)
M goldilocks/quadratic_extension.go → goldilocks/quadratic_extension.go

@@ -232,3 +232,8 @@ ) {

p.AssertIsEqual(a[0], b[0]) p.AssertIsEqual(a[1], b[1]) } + +func (p *Chip) RangeCheckQE(a QuadraticExtensionVariable) { + p.RangeCheck(a[0]) + p.RangeCheck(a[1]) +}
M verifier/verifier.go → verifier/verifier.go

@@ -11,20 +11,23 @@ "github.com/succinctlabs/gnark-plonky2-verifier/types"

) type VerifierChip struct { - api frontend.API `gnark:"-"` - poseidonGlChip *poseidon.GoldilocksChip - poseidonBN254Chip *poseidon.BN254Chip - plonkChip *plonk.PlonkChip - friChip *fri.Chip + api frontend.API `gnark:"-"` + glChip *gl.Chip `gnark:"-"` + poseidonGlChip *poseidon.GoldilocksChip `gnark:"-"` + poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"` + plonkChip *plonk.PlonkChip `gnark:"-"` + friChip *fri.Chip `gnark:"-"` } func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip { + glChip := gl.NewChip(api) friChip := fri.NewChip(api, &commonCircuitData.FriParams) plonkChip := plonk.NewPlonkChip(api, commonCircuitData) poseidonGlChip := poseidon.NewGoldilocksChip(api) poseidonBN254Chip := poseidon.NewBN254Chip(api) return &VerifierChip{ api: api, + glChip: glChip, poseidonGlChip: poseidonGlChip, poseidonBN254Chip: poseidonBN254Chip, plonkChip: plonkChip,

@@ -144,14 +147,70 @@ return proofInput

} */ +func (c *VerifierChip) rangeCheckProof(proof types.Proof) { + // Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness. + + // Note that this is NOT range checking the public inputs (first 32 elements should be no more than 8 bits and the last 4 elements should be no more than 64 bits). Since this is currently being inputted via the smart contract, + // we will assume that caller is doing that check. + + // Range check the proof's openings. + for _, constant := range proof.Openings.Constants { + c.glChip.RangeCheckQE(constant) + } + + for _, plonkSigma := range proof.Openings.PlonkSigmas { + c.glChip.RangeCheckQE(plonkSigma) + } + + for _, wire := range proof.Openings.Wires { + c.glChip.RangeCheckQE(wire) + } + + for _, plonkZ := range proof.Openings.PlonkZs { + c.glChip.RangeCheckQE(plonkZ) + } + + for _, plonkZNext := range proof.Openings.PlonkZsNext { + c.glChip.RangeCheckQE(plonkZNext) + } + + for _, partialProduct := range proof.Openings.PartialProducts { + c.glChip.RangeCheckQE(partialProduct) + } + + for _, quotientPoly := range proof.Openings.QuotientPolys { + c.glChip.RangeCheckQE(quotientPoly) + } + + // Range check the openings proof. + for _, queryRound := range proof.OpeningProof.QueryRoundProofs { + for _, initialTreesElement := range queryRound.InitialTreesProof.EvalsProofs[0].Elements { + c.glChip.RangeCheck(initialTreesElement) + } + + for _, queryStep := range queryRound.Steps { + for _, eval := range queryStep.Evals { + c.glChip.RangeCheckQE(eval) + } + } + } + + // Range check the fri's final poly. + for _, coeff := range proof.OpeningProof.FinalPoly.Coeffs { + c.glChip.RangeCheckQE(coeff) + } + + // Range check the pow witness. + c.glChip.RangeCheck(proof.OpeningProof.PowWitness) +} + func (c *VerifierChip) Verify( proof types.Proof, publicInputs []gl.Variable, verifierData types.VerifierOnlyCircuitData, commonData types.CommonCircuitData, ) { - glApi := gl.NewChip(c.api) - // TODO: Need to range check all the proof and public input elements to make sure they are within goldilocks field + c.rangeCheckProof(proof) // Generate the parts of the witness that is for the plonky2 proof input publicInputsHash := c.GetPublicInputsHash(publicInputs)

@@ -166,27 +225,8 @@ proof.PlonkZsPartialProductsCap,

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] = glApi.Add(proofChallenges.PlonkZeta[0], gl.Zero()) - proofChallenges.PlonkZeta[1] = glApi.Add(proofChallenges.PlonkZeta[1], gl.Zero()) - - proofChallenges.FriChallenges.FriAlpha[0] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[0], gl.Zero()) - proofChallenges.FriChallenges.FriAlpha[1] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[1], gl.Zero()) - - for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ { - proofChallenges.FriChallenges.FriBetas[i][0] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][0], gl.Zero()) - proofChallenges.FriChallenges.FriBetas[i][1] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][1], gl.Zero()) - } - - proofChallenges.FriChallenges.FriPowResponse = glApi.Add(proofChallenges.FriChallenges.FriPowResponse, gl.Zero()) - - for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ { - proofChallenges.FriChallenges.FriQueryIndices[i] = glApi.Add(proofChallenges.FriChallenges.FriQueryIndices[i], gl.Zero()) - } - c.friChip.VerifyFriProof( - fri.GetInstance(&commonData, glApi, proofChallenges.PlonkZeta, commonData.DegreeBits), + fri.GetInstance(&commonData, c.glChip, proofChallenges.PlonkZeta, commonData.DegreeBits), fri.ToOpenings(proof.Openings), &proofChallenges.FriChallenges, initialMerkleCaps,