mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
added the function friCombineInitial
This commit is contained in:
@@ -12,26 +12,6 @@ import (
|
|||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
)
|
)
|
||||||
|
|
||||||
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 FriChip struct {
|
type FriChip struct {
|
||||||
api frontend.API
|
api frontend.API
|
||||||
fieldAPI frontend.API
|
fieldAPI frontend.API
|
||||||
@@ -190,22 +170,10 @@ func (f *FriChip) assertNoncanonicalIndicesOK() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriChip) verifyQueryRound(
|
func (f *FriChip) calculateSubgroupX(
|
||||||
challenges *FriChallenges,
|
xIndexBits []frontend.Variable,
|
||||||
precomputedReducedEval []QuadraticExtension,
|
|
||||||
initialMerkleCaps []MerkleCap,
|
|
||||||
proof *FriProof,
|
|
||||||
xIndex F,
|
|
||||||
n uint64,
|
|
||||||
nLog uint64,
|
nLog uint64,
|
||||||
roundProof *FriQueryRound,
|
) F {
|
||||||
) {
|
|
||||||
f.assertNoncanonicalIndicesOK()
|
|
||||||
xIndexBits := f.fieldAPI.ToBinary(xIndex, int(nLog))
|
|
||||||
capIndexBits := xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]
|
|
||||||
|
|
||||||
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndexBits)
|
|
||||||
|
|
||||||
// Compute x from its index
|
// Compute x from its index
|
||||||
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
||||||
// TODO - Make these as global values
|
// TODO - Make these as global values
|
||||||
@@ -240,10 +208,105 @@ func (f *FriChip) verifyQueryRound(
|
|||||||
).(F)
|
).(F)
|
||||||
}
|
}
|
||||||
|
|
||||||
subgroupX := f.fieldAPI.Mul(g, product).(F)
|
return f.fieldAPI.Mul(g, product).(F)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FriChip) friCombineInitial(
|
||||||
|
instance FriInstanceInfo,
|
||||||
|
proof FriInitialTreeProof,
|
||||||
|
friAlpha QuadraticExtension,
|
||||||
|
subgroupX_QE QuadraticExtension,
|
||||||
|
precomputedReducedEval []QuadraticExtension,
|
||||||
|
) QuadraticExtension {
|
||||||
|
sum := f.qeAPI.ZERO_QE
|
||||||
|
|
||||||
|
if len(instance.Batches) != len(precomputedReducedEval) {
|
||||||
|
panic("len(openings) != len(precomputedReducedEval)")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(instance.Batches); i++ {
|
||||||
|
batch := instance.Batches[i]
|
||||||
|
reducedOpenings := precomputedReducedEval[i]
|
||||||
|
|
||||||
|
point := batch.Point
|
||||||
|
evals := make([]QuadraticExtension, 0)
|
||||||
|
for _, polynomial := range batch.Polynomials {
|
||||||
|
evals = append(
|
||||||
|
evals,
|
||||||
|
QuadraticExtension{proof.EvalsProofs[polynomial.OracleIndex].Elements[polynomial.PolynomialInfo], field.ZERO_F},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
reducedEvals := reduceWithPowers(f.qeAPI, evals, friAlpha)
|
||||||
|
numerator := f.qeAPI.SubExtension(reducedEvals, reducedOpenings)
|
||||||
|
denominator := f.qeAPI.SubExtension(subgroupX_QE, point)
|
||||||
|
sum = f.qeAPI.MulExtension(f.qeAPI.ExpU64Extension(friAlpha, uint64(len(evals))), sum)
|
||||||
|
sum = f.qeAPI.AddExtension(
|
||||||
|
f.qeAPI.DivExtension(
|
||||||
|
numerator,
|
||||||
|
denominator,
|
||||||
|
),
|
||||||
|
sum,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.qeAPI.MulExtension(sum, subgroupX_QE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FriChip) finalPolyEval(finalPoly PolynomialCoeffs, point QuadraticExtension) QuadraticExtension {
|
||||||
|
ret := f.qeAPI.ZERO_QE
|
||||||
|
for i := len(finalPoly.Coeffs) - 1; i >= 0; i-- {
|
||||||
|
ret = f.qeAPI.AddExtension(
|
||||||
|
f.qeAPI.MulExtension(
|
||||||
|
ret,
|
||||||
|
point,
|
||||||
|
),
|
||||||
|
finalPoly.Coeffs[i],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FriChip) verifyQueryRound(
|
||||||
|
instance FriInstanceInfo,
|
||||||
|
challenges *FriChallenges,
|
||||||
|
precomputedReducedEval []QuadraticExtension,
|
||||||
|
initialMerkleCaps []MerkleCap,
|
||||||
|
proof *FriProof,
|
||||||
|
xIndex F,
|
||||||
|
n uint64,
|
||||||
|
nLog uint64,
|
||||||
|
roundProof *FriQueryRound,
|
||||||
|
) {
|
||||||
|
f.assertNoncanonicalIndicesOK()
|
||||||
|
xIndexBits := f.fieldAPI.ToBinary(xIndex, int(nLog))
|
||||||
|
capIndexBits := xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]
|
||||||
|
|
||||||
|
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndexBits)
|
||||||
|
|
||||||
|
subgroupX := f.calculateSubgroupX(
|
||||||
|
xIndexBits,
|
||||||
|
nLog,
|
||||||
|
)
|
||||||
|
|
||||||
|
subgroupX_QE := QuadraticExtension{subgroupX, field.ZERO_F}
|
||||||
|
|
||||||
|
oldEval := f.friCombineInitial(
|
||||||
|
instance,
|
||||||
|
roundProof.InitialTreesProof,
|
||||||
|
challenges.FriAlpha,
|
||||||
|
subgroupX_QE,
|
||||||
|
precomputedReducedEval,
|
||||||
|
)
|
||||||
|
|
||||||
|
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
|
||||||
|
|
||||||
|
f.fieldAPI.AssertIsEqual(oldEval[0], finalPolyEval[0])
|
||||||
|
f.fieldAPI.AssertIsEqual(oldEval[1], finalPolyEval[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriChip) VerifyFriProof(
|
func (f *FriChip) VerifyFriProof(
|
||||||
|
instance FriInstanceInfo,
|
||||||
openings FriOpenings,
|
openings FriOpenings,
|
||||||
friChallenges *FriChallenges,
|
friChallenges *FriChallenges,
|
||||||
initialMerkleCaps []MerkleCap,
|
initialMerkleCaps []MerkleCap,
|
||||||
@@ -281,6 +344,7 @@ func (f *FriChip) VerifyFriProof(
|
|||||||
roundProof := friProof.QueryRoundProofs[idx]
|
roundProof := friProof.QueryRoundProofs[idx]
|
||||||
|
|
||||||
f.verifyQueryRound(
|
f.verifyQueryRound(
|
||||||
|
instance,
|
||||||
friChallenges,
|
friChallenges,
|
||||||
precomputedReducedEvals,
|
precomputedReducedEvals,
|
||||||
initialMerkleCaps,
|
initialMerkleCaps,
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
friChip.VerifyFriProof(
|
friChip.VerifyFriProof(
|
||||||
|
commonCircuitData.GetFriInstance(),
|
||||||
proofWithPis.Proof.Openings.ToFriOpenings(),
|
proofWithPis.Proof.Openings.ToFriOpenings(),
|
||||||
&friChallenges,
|
&friChallenges,
|
||||||
initialMerkleCaps,
|
initialMerkleCaps,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package plonky2_verifier
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gnark-ed25519/field"
|
||||||
. "gnark-ed25519/field"
|
. "gnark-ed25519/field"
|
||||||
|
"math/bits"
|
||||||
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"github.com/consensys/gnark/frontend"
|
||||||
)
|
)
|
||||||
@@ -12,7 +14,6 @@ type QuadraticExtensionAPI struct {
|
|||||||
|
|
||||||
W F
|
W F
|
||||||
DTH_ROOT F
|
DTH_ROOT F
|
||||||
ZERO_F F
|
|
||||||
|
|
||||||
ONE QuadraticExtension
|
ONE QuadraticExtension
|
||||||
ZERO_QE QuadraticExtension
|
ZERO_QE QuadraticExtension
|
||||||
@@ -66,7 +67,7 @@ func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) Quadratic
|
|||||||
a1_is_zero := c.fieldAPI.IsZero(a[1])
|
a1_is_zero := c.fieldAPI.IsZero(a[1])
|
||||||
|
|
||||||
// assert that a0_is_zero OR a1_is_zero == false
|
// assert that a0_is_zero OR a1_is_zero == false
|
||||||
c.fieldAPI.AssertIsEqual(c.fieldAPI.Mul(a0_is_zero, a1_is_zero).(F), c.ZERO_F)
|
c.fieldAPI.AssertIsEqual(c.fieldAPI.Mul(a0_is_zero, a1_is_zero).(F), field.ZERO_F)
|
||||||
|
|
||||||
a_pow_r_minus_1 := QuadraticExtension{a[0], c.fieldAPI.Mul(a[1], c.DTH_ROOT).(F)}
|
a_pow_r_minus_1 := QuadraticExtension{a[0], c.fieldAPI.Mul(a[1], c.DTH_ROOT).(F)}
|
||||||
a_pow_r := c.MulExtension(a_pow_r_minus_1, a)
|
a_pow_r := c.MulExtension(a_pow_r_minus_1, a)
|
||||||
@@ -78,7 +79,35 @@ func (c *QuadraticExtensionAPI) ScalarMulExtension(a QuadraticExtension, scalar
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension {
|
func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension {
|
||||||
return QuadraticExtension{a, c.ZERO_F}
|
return QuadraticExtension{a, field.ZERO_F}
|
||||||
|
}
|
||||||
|
|
||||||
|
// / Exponentiate `base` to the power of a known `exponent`.
|
||||||
|
func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent uint64) QuadraticExtension {
|
||||||
|
switch exponent {
|
||||||
|
case 0:
|
||||||
|
return c.ONE
|
||||||
|
case 1:
|
||||||
|
return a
|
||||||
|
case 2:
|
||||||
|
return c.SquareExtension(a)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
current := a
|
||||||
|
product := c.ONE
|
||||||
|
|
||||||
|
for i := 0; i < bits.Len64(exponent); i++ {
|
||||||
|
if i != 0 {
|
||||||
|
current = c.SquareExtension(current)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent >> i & 1) != 0 {
|
||||||
|
product = c.MulExtension(product, current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return product
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) {
|
func (c *QuadraticExtensionAPI) Println(a QuadraticExtension) {
|
||||||
|
|||||||
Reference in New Issue
Block a user