fri challenges
jtguibas jtguibas@gmail.com
Mon, 10 Oct 2022 20:45:34 -0700
6 files changed,
148 insertions(+),
40 deletions(-)
M
plonky2_verifier/challenger.go
→
plonky2_verifier/challenger.go
@@ -55,6 +55,22 @@ c.ObserveHash(cap[i])
} } +func (c *ChallengerChip) ObserveExtensionElement(element QuadraticExtension) { + c.ObserveElements(element[:]) +} + +func (c *ChallengerChip) ObserveExtensionElements(elements []QuadraticExtension) { + for i := 0; i < len(elements); i++ { + c.ObserveExtensionElement(elements[i]) + } +} + +func (c *ChallengerChip) ObserveOpenings(openings FriOpenings) { + for i := 0; i < len(openings.Batches); i++ { + c.ObserveExtensionElements(openings.Batches[i].values) + } +} + func (c *ChallengerChip) GetChallenge() F { if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { c.duplexing()@@ -66,12 +82,51 @@
return challenge } -func (c *ChallengerChip) GetNChallenges(n int) []F { +func (c *ChallengerChip) GetNChallenges(n uint64) []F { challenges := make([]F, n) - for i := 0; i < n; i++ { + for i := uint64(0); i < n; i++ { challenges[i] = c.GetChallenge() } return challenges +} + +func (c *ChallengerChip) GetExtensionChallenge() QuadraticExtension { + values := c.GetNChallenges(2) + return QuadraticExtension{values[0], values[1]} +} + +func (c *ChallengerChip) GetHash() Hash { + return [4]F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} +} + +func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []MerkleCap, finalPoly PolynomialCoeffs, powWitness F, degreeBits uint64, config FriConfig) FriChallenges { + numFriQueries := config.NumQueryRounds + ldeSize := 1 << (degreeBits + config.RateBits) + friAlpha := c.GetExtensionChallenge() + + var friBetas []QuadraticExtension + for i := 0; i < len(commitPhaseMerkleCaps); i++ { + c.ObserveCap(commitPhaseMerkleCaps[i]) + friBetas = append(friBetas, c.GetExtensionChallenge()) + } + + c.ObserveExtensionElements(finalPoly.Coeffs) + + hash := c.GetHash() + powInputs := append(hash[:], powWitness) + + friPowResponse := c.poseidonChip.HashNoPad(powInputs)[0] + friQueryIndices := c.GetNChallenges(numFriQueries) + + // need to modulo lde size on fri query indices + _ = ldeSize + + return FriChallenges{ + FriAlpha: friAlpha, + FriBetas: friBetas, + FriPowResponse: friPowResponse, + FriQueryIndicies: friQueryIndices, + } } func clearBuffer(buffer []F) []F {
M
plonky2_verifier/challenger_test.go
→
plonky2_verifier/challenger_test.go
@@ -48,9 +48,9 @@ challengerChip.ObserveHash(circuitDigest)
challengerChip.ObserveHash(publicInputHash) challengerChip.ObserveCap(wiresCap[:]) - nbChallenges := 2 - plonkBetas := challengerChip.GetNChallenges(nbChallenges) - plonkGammas := challengerChip.GetNChallenges(nbChallenges) + numChallenges := uint64(2) + plonkBetas := challengerChip.GetNChallenges(numChallenges) + plonkGammas := challengerChip.GetNChallenges(numChallenges) expectedPlonkBetas := [2]frontend.Variable{ frontend.Variable("4678728155650926271"),
A
plonky2_verifier/fri.go
@@ -0,0 +1,25 @@
+package plonky2_verifier + +import ( + . "gnark-ed25519/field" +) + +type FriOpeningBatch struct { + values []QuadraticExtension +} + +type FriOpenings struct { + Batches []FriOpeningBatch +} + +func (c *OpeningSet) ToFriOpenings() FriOpenings { + values := c.Constants + values = append(values, c.PlonkSigmas...) + values = append(values, c.Wires...) + values = append(values, c.PlonkZs...) + values = append(values, c.PartialProducts...) + values = append(values, c.QuotientPolys...) + zetaBatch := FriOpeningBatch{values: values} + zetaNextBatch := FriOpeningBatch{values: c.PlonkZsNext} + return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}} +}
M
plonky2_verifier/proof.go
→
plonky2_verifier/structs.go
@@ -105,5 +105,19 @@ NumPublicInputs uint64
KIs []F NumPartialProducts uint64 CircuitDigest Hash - // TODO: add SelectorsInfo and Gates +} + +type ProofChallenges struct { + PlonkBetas []F + PlonkGammas []F + PlonkAlphas []F + PlonkZeta QuadraticExtension + FriChallenges FriChallenges +} + +type FriChallenges struct { + FriAlpha QuadraticExtension + FriBetas []QuadraticExtension + FriPowResponse F + FriQueryIndicies []F }
M
plonky2_verifier/verifier.go
→
plonky2_verifier/verifier.go
@@ -1,43 +1,58 @@
package plonky2_verifier -// import ( -// . "gnark-ed25519/field" -// "gnark-ed25519/poseidon" +import ( + . "gnark-ed25519/field" + "gnark-ed25519/poseidon" -// "github.com/consensys/gnark/frontend" -// ) + "github.com/consensys/gnark/frontend" +) -// type VerifierChip struct { -// api frontend.API -// field frontend.API -// poseidonChip poseidon.PoseidonChip -// } +type VerifierChip struct { + api frontend.API + field frontend.API + poseidonChip poseidon.PoseidonChip +} -// func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) poseidon.HashOutput { -// return c.poseidonChip.HashNoPad(publicInputs) -// } +func (c *VerifierChip) GetPublicInputsHash(publicInputs []F) Hash { + return c.poseidonChip.HashNoPad(publicInputs) +} -// func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) { -// config := commonData.Config -// numChallenges := int(config.NumChallenges) -// challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) +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.ObserveHash(commonData.CircuitDigest) + challenger.ObserveHash(publicInputsHash) + challenger.ObserveCap(proofWithPis.Proof.WiresCap) + plonkBetas := challenger.GetNChallenges(numChallenges) + plonkGammas := challenger.GetNChallenges(numChallenges) + + challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) + plonkAlphas := challenger.GetNChallenges(numChallenges) -// challenger.ObserveHash(commonData.CircuitDigest) -// challenger.ObserveHash(publicInputsHash) -// challenger.ObserveCap(proofWithPis.Proof.WiresCap) -// plonkBetas := challenger.GetNChallenges(numChallenges) -// plonkGammas := challenger.GetNChallenges(numChallenges) + challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap) + plonkZeta := challenger.GetExtensionChallenge() -// challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) -// plonkAlphas := challenger.GetNChallenges(numChallenges) + _, _, _, _ = plonkAlphas, plonkBetas, plonkGammas, plonkZeta -// challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap) -// plonkZeta := challenger.GetNChallenges(numChallenges) + challenger.ObserveOpenings(proofWithPis.Proof.Openings.ToFriOpenings()) -// challenger.ObserveOpenings(proofWithPis.Proof.Openings) -// } + return ProofChallenges{ + PlonkBetas: plonkBetas, + PlonkGammas: plonkGammas, + PlonkAlphas: plonkAlphas, + PlonkZeta: plonkZeta, + FriChallenges: challenger.GetFriChallenges( + proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, + proofWithPis.Proof.OpeningProof.FinalPoly, + proofWithPis.Proof.OpeningProof.PowWitness, + commonData.DegreeBits, config.FriConfig, + ), + } +} -// func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { -// publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) -// challenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) -// } +func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { + publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) + _ = c.GetChallenges(proofWithPis, publicInputsHash, commonData) +}
M
utils/utils.go
→
utils/utils.go
@@ -5,7 +5,6 @@ . "gnark-ed25519/field"
"math/big" "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/emulated" ) func StrArrayToBigIntArray(input []string) []big.Int {@@ -29,7 +28,7 @@
func Uint64ArrayToFArray(input []uint64) []F { var output []F for i := 0; i < len(input); i++ { - output = append(output, emulated.NewElement[emulated.Goldilocks](input[i])) + output = append(output, NewFieldElement(input[i])) } return output }