From c3e16622a2d8d785e9885cc7b3a4aaa122522aeb Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 10 Nov 2022 16:30:53 -0800 Subject: [PATCH] added GetFriInstance --- plonky2_verifier/fri_test.go | 6 +- plonky2_verifier/fri_utils.go | 171 ++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 plonky2_verifier/fri_utils.go diff --git a/plonky2_verifier/fri_test.go b/plonky2_verifier/fri_test.go index 07867cc..ccc93c6 100644 --- a/plonky2_verifier/fri_test.go +++ b/plonky2_verifier/fri_test.go @@ -21,6 +21,10 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { poseidonChip := poseidon.NewPoseidonChip(api, field) friChip := NewFriChip(api, field, qe, poseidonChip, &commonCircuitData.FriParams) + zeta := QuadraticExtension{ + NewFieldElementFromString("14887793628029982930"), + NewFieldElementFromString("1136137158284059037"), + } friChallenges := FriChallenges{ FriAlpha: QuadraticExtension{ NewFieldElementFromString("14641715242626918707"), @@ -68,7 +72,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { } friChip.VerifyFriProof( - commonCircuitData.GetFriInstance(), + commonCircuitData.GetFriInstance(qe, zeta, commonCircuitData.DegreeBits), proofWithPis.Proof.Openings.ToFriOpenings(), &friChallenges, initialMerkleCaps, diff --git a/plonky2_verifier/fri_utils.go b/plonky2_verifier/fri_utils.go new file mode 100644 index 0000000..1a897e5 --- /dev/null +++ b/plonky2_verifier/fri_utils.go @@ -0,0 +1,171 @@ +package plonky2_verifier + +import ( + "gnark-ed25519/field" + . "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}} +} + +type FriPolynomialInfo struct { + OracleIndex uint64 + PolynomialInfo uint64 +} + +type FriOracleInfo struct { + NumPolys uint64 + Blinding bool +} + +type FriBatchInfo struct { + Point QuadraticExtension + Polynomials []FriPolynomialInfo +} + +type FriInstanceInfo struct { + Oracles []FriOracleInfo + Batches []FriBatchInfo +} + +func (c *CommonCircuitData) polynomialInfoFromRange(oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []FriPolynomialInfo { + returnArr := make([]FriPolynomialInfo, 0) + for i := startPolyIdx; i < endPolyIdx; i++ { + returnArr = append(returnArr, + FriPolynomialInfo{ + OracleIndex: oracleIdx, + PolynomialInfo: i, + }) + } + + return returnArr + +} + +// Range of the sigma polynomials in the `constants_sigmas_commitment`. +func (c *CommonCircuitData) sigmasRange() []uint64 { + returnArr := make([]uint64, 0) + for i := c.NumConstants; i <= c.NumConstants+c.Config.NumRoutedWires; i++ { + returnArr = append(returnArr, i) + } + + return returnArr +} + +func (c *CommonCircuitData) numPreprocessedPolys() uint64 { + sigmasRange := c.sigmasRange() + return sigmasRange[len(sigmasRange)-1] +} + +func (c *CommonCircuitData) numZSPartialProductsPolys() uint64 { + return c.Config.NumChallenges * (1 + c.NumPartialProducts) +} + +func (c *CommonCircuitData) numQuotientPolys() uint64 { + return c.Config.NumChallenges * c.QuotientDegreeFactor +} + +func (c *CommonCircuitData) friPreprocessedPolys() []FriPolynomialInfo { + return c.polynomialInfoFromRange( + CONSTANTS_SIGMAS.index, + 0, + c.numPreprocessedPolys(), + ) +} + +func (c *CommonCircuitData) friWirePolys() []FriPolynomialInfo { + numWirePolys := c.Config.NumWires + return c.polynomialInfoFromRange(WIRES.index, 0, numWirePolys) +} + +func (c *CommonCircuitData) friZSPartialProductsPolys() []FriPolynomialInfo { + return c.polynomialInfoFromRange( + ZS_PARTIAL_PRODUCTS.index, + 0, + c.numZSPartialProductsPolys(), + ) +} + +func (c *CommonCircuitData) friQuotientPolys() []FriPolynomialInfo { + return c.polynomialInfoFromRange( + QUOTIENT.index, + 0, + c.numQuotientPolys(), + ) +} + +func (c *CommonCircuitData) friZSPolys() []FriPolynomialInfo { + return c.polynomialInfoFromRange( + ZS_PARTIAL_PRODUCTS.index, + 0, + c.Config.NumChallenges, + ) +} + +func (c *CommonCircuitData) friOracles() []FriOracleInfo { + return []FriOracleInfo{ + { + NumPolys: c.numPreprocessedPolys(), + Blinding: CONSTANTS_SIGMAS.blinding, + }, + { + NumPolys: c.Config.NumWires, + Blinding: WIRES.blinding, + }, + { + NumPolys: c.numZSPartialProductsPolys(), + Blinding: ZS_PARTIAL_PRODUCTS.blinding, + }, + { + NumPolys: c.numQuotientPolys(), + Blinding: QUOTIENT.blinding, + }, + } +} + +func (c *CommonCircuitData) friAllPolys() []FriPolynomialInfo { + returnArr := make([]FriPolynomialInfo, 0) + returnArr = append(returnArr, c.friPreprocessedPolys()...) + returnArr = append(returnArr, c.friWirePolys()...) + returnArr = append(returnArr, c.friZSPartialProductsPolys()...) + returnArr = append(returnArr, c.friQuotientPolys()...) + + return returnArr +} + +func (c *CommonCircuitData) GetFriInstance(qeAPI *QuadraticExtensionAPI, zeta QuadraticExtension, degreeBits uint64) FriInstanceInfo { + zetaBatch := FriBatchInfo{ + Point: zeta, + Polynomials: c.friAllPolys(), + } + + g := field.GoldilocksPrimitiveRootOfUnity(degreeBits) + zetaNext := qeAPI.MulExtension(QuadraticExtension{field.NewFieldElement(g.Uint64()), field.ZERO_F}, zeta) + + zetaNextBath := FriBatchInfo{ + Point: zetaNext, + Polynomials: c.friZSPolys(), + } + + return FriInstanceInfo{ + Oracles: c.friOracles(), + Batches: []FriBatchInfo{zetaBatch, zetaNextBath}, + } +}