mirror of
https://github.com/logos-storage/gnark-plonky2-verifier.git
synced 2026-01-08 08:03:12 +00:00
finished interpolate function in fri round verification
This commit is contained in:
parent
f877e3bda3
commit
d847bbd8e8
@ -277,6 +277,54 @@ func (f *FriChip) finalPolyEval(finalPoly PolynomialCoeffs, point QuadraticExten
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *FriChip) interpolate(x QuadraticExtension, xPoints []QuadraticExtension, yPoints []QuadraticExtension, barycentricWeights []QuadraticExtension) QuadraticExtension {
|
||||
if len(xPoints) != len(yPoints) || len(xPoints) != len(barycentricWeights) {
|
||||
panic("length of xPoints, yPoints, and barycentricWeights are inconsistent")
|
||||
}
|
||||
|
||||
lX := f.qeAPI.ONE_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
lX = f.qeAPI.MulExtension(
|
||||
lX,
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sum := f.qeAPI.ZERO_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
sum = f.qeAPI.AddExtension(
|
||||
f.qeAPI.MulExtension(
|
||||
f.qeAPI.DivExtension(
|
||||
barycentricWeights[i],
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
),
|
||||
yPoints[i],
|
||||
),
|
||||
sum,
|
||||
)
|
||||
}
|
||||
|
||||
interpolation := f.qeAPI.MulExtension(lX, sum)
|
||||
|
||||
returnField := interpolation
|
||||
// Now check if x is already within the xPoints
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
returnField = f.qeAPI.Select(
|
||||
f.qeAPI.IsZero(f.qeAPI.SubExtension(x, xPoints[i])),
|
||||
yPoints[i],
|
||||
returnField,
|
||||
)
|
||||
}
|
||||
|
||||
return returnField
|
||||
}
|
||||
|
||||
func (f *FriChip) computeEvaluation(
|
||||
x F,
|
||||
xIndexWithinCosetBits []frontend.Variable,
|
||||
@ -314,34 +362,35 @@ func (f *FriChip) computeEvaluation(
|
||||
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
|
||||
cosetStart := f.fieldAPI.Mul(start, x).(F)
|
||||
|
||||
xPoints := make([]F, len(evals))
|
||||
xPoints := make([]QuadraticExtension, len(evals))
|
||||
yPoints := permutedEvals
|
||||
|
||||
// TODO: Make g_F a constant
|
||||
g_F := NewFieldElement(g.Uint64())
|
||||
xPoints[0] = cosetStart
|
||||
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
||||
for i := 1; i < len(evals); i++ {
|
||||
xPoints[i] = f.fieldAPI.Mul(xPoints[i-1], g_F).(F)
|
||||
xPoints[i] = f.qeAPI.FieldToQE(f.fieldAPI.Mul(xPoints[i-1], g_F).(F))
|
||||
}
|
||||
|
||||
// TODO: This is n^2. Is there a way to do this better?
|
||||
// Compute the barycentric weights
|
||||
barycentricWeights := make([]F, len(xPoints))
|
||||
barycentricWeights := make([]QuadraticExtension, len(xPoints))
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
barycentricWeights[i] = ONE_F
|
||||
barycentricWeights[i] = f.qeAPI.ONE_QE
|
||||
for j := 0; j < len(xPoints); j++ {
|
||||
if i != j {
|
||||
barycentricWeights[i] = f.fieldAPI.Mul(
|
||||
f.fieldAPI.Sub(xPoints[i], xPoints[j]),
|
||||
barycentricWeights[i] = f.qeAPI.MulExtension(
|
||||
f.qeAPI.SubExtension(xPoints[i], xPoints[j]),
|
||||
barycentricWeights[i],
|
||||
).(F)
|
||||
)
|
||||
}
|
||||
}
|
||||
// Take the inverse of the barycentric weights
|
||||
// TODO: Can provide a witness to this value
|
||||
barycentricWeights[i] = f.fieldAPI.Inverse(barycentricWeights[i]).(F)
|
||||
barycentricWeights[i] = f.qeAPI.InverseExtension(barycentricWeights[i])
|
||||
}
|
||||
|
||||
return f.interpolate(beta, xPoints, yPoints, barycentricWeights)
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyQueryRound(
|
||||
@ -405,7 +454,7 @@ func (f *FriChip) verifyQueryRound(
|
||||
newEval := f.qeAPI.Lookup2(xIndexWithinCosetBits[2], xIndexWithinCosetBits[3], evals[0], evals[1], evals[2], evals[3])
|
||||
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
||||
|
||||
oldEval := f.computeEvaluation(
|
||||
oldEval = f.computeEvaluation(
|
||||
subgroupX,
|
||||
xIndexWithinCosetBits,
|
||||
arityBits,
|
||||
|
||||
@ -1,11 +1,37 @@
|
||||
package plonky2_verifier
|
||||
|
||||
import (
|
||||
"gnark-ed25519/field"
|
||||
. "gnark-ed25519/field"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
)
|
||||
|
||||
type PlonkOracle struct {
|
||||
index uint64
|
||||
blinding bool
|
||||
}
|
||||
|
||||
var CONSTANTS_SIGMAS = PlonkOracle{
|
||||
index: 0,
|
||||
blinding: false,
|
||||
}
|
||||
|
||||
var WIRES = PlonkOracle{
|
||||
index: 1,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var ZS_PARTIAL_PRODUCTS = PlonkOracle{
|
||||
index: 2,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var QUOTIENT = PlonkOracle{
|
||||
index: 3,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
type PlonkChip struct {
|
||||
api frontend.API
|
||||
qe *QuadraticExtensionAPI
|
||||
@ -30,7 +56,7 @@ func NewPlonkChip(api frontend.API, qe *QuadraticExtensionAPI, commonData Common
|
||||
|
||||
DEGREE: NewFieldElement(1 << commonData.DegreeBits),
|
||||
DEGREE_BITS_F: NewFieldElement(commonData.DegreeBits),
|
||||
DEGREE_QE: QuadraticExtension{NewFieldElement(1 << commonData.DegreeBits), NewFieldElement(0)},
|
||||
DEGREE_QE: QuadraticExtension{NewFieldElement(1 << commonData.DegreeBits), field.ZERO_F},
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +72,7 @@ func (p *PlonkChip) evalL0(x QuadraticExtension, xPowN QuadraticExtension) Quadr
|
||||
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||
evalZeroPoly := p.qe.SubExtension(
|
||||
xPowN,
|
||||
p.qe.ONE,
|
||||
p.qe.ONE_QE,
|
||||
)
|
||||
denominator := p.qe.SubExtension(
|
||||
p.qe.ScalarMulExtension(x, p.DEGREE),
|
||||
@ -109,7 +135,7 @@ func (p *PlonkChip) evalVanishingPoly(zetaPowN QuadraticExtension) []QuadraticEx
|
||||
// L_0(zeta) (Z(zeta) - 1) = 0
|
||||
z1_term := p.qe.MulExtension(
|
||||
l0Zeta,
|
||||
p.qe.SubExtension(p.openings.PlonkZs[i], p.qe.ONE))
|
||||
p.qe.SubExtension(p.openings.PlonkZs[i], p.qe.ONE_QE))
|
||||
vanishingZ1Terms = append(vanishingZ1Terms, z1_term)
|
||||
|
||||
numeratorValues := make([]QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||
@ -187,7 +213,7 @@ func (p *PlonkChip) Verify() {
|
||||
vanishingPolysZeta := p.evalVanishingPoly(zetaPowN)
|
||||
|
||||
// Calculate Z(H)
|
||||
zHZeta := p.qe.SubExtension(zetaPowN, p.qe.ONE)
|
||||
zHZeta := p.qe.SubExtension(zetaPowN, p.qe.ONE_QE)
|
||||
|
||||
// `quotient_polys_zeta` holds `num_challenges * quotient_degree_factor` evaluations.
|
||||
// Each chunk of `quotient_degree_factor` holds the evaluations of `t_0(zeta),...,t_{quotient_degree_factor-1}(zeta)`
|
||||
@ -197,8 +223,7 @@ func (p *PlonkChip) Verify() {
|
||||
for i := 0; i < len(p.openings.QuotientPolys); i += int(p.commonData.QuotientDegreeFactor) {
|
||||
prod := p.qe.MulExtension(
|
||||
zHZeta,
|
||||
reduceWithPowers(
|
||||
p.qe,
|
||||
p.qe.ReduceWithPowers(
|
||||
p.openings.QuotientPolys[i:i+int(p.commonData.QuotientDegreeFactor)],
|
||||
zetaPowN,
|
||||
),
|
||||
|
||||
@ -14,7 +14,7 @@ type QuadraticExtensionAPI struct {
|
||||
W F
|
||||
DTH_ROOT F
|
||||
|
||||
ONE QuadraticExtension
|
||||
ONE_QE QuadraticExtension
|
||||
ZERO_QE QuadraticExtension
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *Quadrat
|
||||
W: NewFieldElement(7),
|
||||
DTH_ROOT: NewFieldElement(18446744069414584320),
|
||||
|
||||
ONE: QuadraticExtension{ONE_F, ZERO_F},
|
||||
ONE_QE: QuadraticExtension{ONE_F, ZERO_F},
|
||||
ZERO_QE: QuadraticExtension{ZERO_F, ZERO_F},
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,10 @@ func (c *QuadraticExtensionAPI) DivExtension(a QuadraticExtension, b QuadraticEx
|
||||
return c.MulExtension(a, c.InverseExtension(b))
|
||||
}
|
||||
|
||||
func (c *QuadraticExtensionAPI) IsZero(a QuadraticExtension) frontend.Variable {
|
||||
return c.fieldAPI.Mul(c.fieldAPI.IsZero(a[0]), c.fieldAPI.IsZero(a[1]))
|
||||
}
|
||||
|
||||
// TODO: Instead of calculating the inverse within the circuit, can witness the
|
||||
// inverse and assert that a_inverse * a = 1. Should reduce # of constraints.
|
||||
func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) QuadraticExtension {
|
||||
@ -85,7 +89,7 @@ func (c *QuadraticExtensionAPI) FieldToQE(a F) QuadraticExtension {
|
||||
func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent uint64) QuadraticExtension {
|
||||
switch exponent {
|
||||
case 0:
|
||||
return c.ONE
|
||||
return c.ONE_QE
|
||||
case 1:
|
||||
return a
|
||||
case 2:
|
||||
@ -94,7 +98,7 @@ func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent u
|
||||
}
|
||||
|
||||
current := a
|
||||
product := c.ONE
|
||||
product := c.ONE_QE
|
||||
|
||||
for i := 0; i < bits.Len64(exponent); i++ {
|
||||
if i != 0 {
|
||||
@ -125,6 +129,16 @@ func (c *QuadraticExtensionAPI) ReduceWithPowers(terms []QuadraticExtension, sca
|
||||
return sum
|
||||
}
|
||||
|
||||
func (c *QuadraticExtensionAPI) Select(b0 frontend.Variable, qe0, qe1 QuadraticExtension) QuadraticExtension {
|
||||
var retQE QuadraticExtension
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
retQE[i] = c.fieldAPI.Select(b0, qe0[i], qe1[i]).(F)
|
||||
}
|
||||
|
||||
return retQE
|
||||
}
|
||||
|
||||
func (c *QuadraticExtensionAPI) Lookup2(b0 frontend.Variable, b1 frontend.Variable, qe0, qe1, qe2, qe3 QuadraticExtension) QuadraticExtension {
|
||||
var retQE QuadraticExtension
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user