mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 17:11:31 +01:00
finished interpolate function in fri round verification
This commit is contained in:
@@ -277,6 +277,54 @@ func (f *FriChip) finalPolyEval(finalPoly PolynomialCoeffs, point QuadraticExten
|
|||||||
return ret
|
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(
|
func (f *FriChip) computeEvaluation(
|
||||||
x F,
|
x F,
|
||||||
xIndexWithinCosetBits []frontend.Variable,
|
xIndexWithinCosetBits []frontend.Variable,
|
||||||
@@ -314,34 +362,35 @@ func (f *FriChip) computeEvaluation(
|
|||||||
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
|
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
|
||||||
cosetStart := f.fieldAPI.Mul(start, x).(F)
|
cosetStart := f.fieldAPI.Mul(start, x).(F)
|
||||||
|
|
||||||
xPoints := make([]F, len(evals))
|
xPoints := make([]QuadraticExtension, len(evals))
|
||||||
yPoints := permutedEvals
|
yPoints := permutedEvals
|
||||||
|
|
||||||
// TODO: Make g_F a constant
|
// TODO: Make g_F a constant
|
||||||
g_F := NewFieldElement(g.Uint64())
|
g_F := NewFieldElement(g.Uint64())
|
||||||
xPoints[0] = cosetStart
|
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
||||||
for i := 1; i < len(evals); i++ {
|
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?
|
// TODO: This is n^2. Is there a way to do this better?
|
||||||
// Compute the barycentric weights
|
// Compute the barycentric weights
|
||||||
barycentricWeights := make([]F, len(xPoints))
|
barycentricWeights := make([]QuadraticExtension, len(xPoints))
|
||||||
for i := 0; i < len(xPoints); i++ {
|
for i := 0; i < len(xPoints); i++ {
|
||||||
barycentricWeights[i] = ONE_F
|
barycentricWeights[i] = f.qeAPI.ONE_QE
|
||||||
for j := 0; j < len(xPoints); j++ {
|
for j := 0; j < len(xPoints); j++ {
|
||||||
if i != j {
|
if i != j {
|
||||||
barycentricWeights[i] = f.fieldAPI.Mul(
|
barycentricWeights[i] = f.qeAPI.MulExtension(
|
||||||
f.fieldAPI.Sub(xPoints[i], xPoints[j]),
|
f.qeAPI.SubExtension(xPoints[i], xPoints[j]),
|
||||||
barycentricWeights[i],
|
barycentricWeights[i],
|
||||||
).(F)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Take the inverse of the barycentric weights
|
// Take the inverse of the barycentric weights
|
||||||
// TODO: Can provide a witness to this value
|
// 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(
|
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])
|
newEval := f.qeAPI.Lookup2(xIndexWithinCosetBits[2], xIndexWithinCosetBits[3], evals[0], evals[1], evals[2], evals[3])
|
||||||
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
||||||
|
|
||||||
oldEval := f.computeEvaluation(
|
oldEval = f.computeEvaluation(
|
||||||
subgroupX,
|
subgroupX,
|
||||||
xIndexWithinCosetBits,
|
xIndexWithinCosetBits,
|
||||||
arityBits,
|
arityBits,
|
||||||
|
|||||||
@@ -1,11 +1,37 @@
|
|||||||
package plonky2_verifier
|
package plonky2_verifier
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"gnark-ed25519/field"
|
||||||
. "gnark-ed25519/field"
|
. "gnark-ed25519/field"
|
||||||
|
|
||||||
"github.com/consensys/gnark/frontend"
|
"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 {
|
type PlonkChip struct {
|
||||||
api frontend.API
|
api frontend.API
|
||||||
qe *QuadraticExtensionAPI
|
qe *QuadraticExtensionAPI
|
||||||
@@ -30,7 +56,7 @@ func NewPlonkChip(api frontend.API, qe *QuadraticExtensionAPI, commonData Common
|
|||||||
|
|
||||||
DEGREE: NewFieldElement(1 << commonData.DegreeBits),
|
DEGREE: NewFieldElement(1 << commonData.DegreeBits),
|
||||||
DEGREE_BITS_F: NewFieldElement(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))
|
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||||
evalZeroPoly := p.qe.SubExtension(
|
evalZeroPoly := p.qe.SubExtension(
|
||||||
xPowN,
|
xPowN,
|
||||||
p.qe.ONE,
|
p.qe.ONE_QE,
|
||||||
)
|
)
|
||||||
denominator := p.qe.SubExtension(
|
denominator := p.qe.SubExtension(
|
||||||
p.qe.ScalarMulExtension(x, p.DEGREE),
|
p.qe.ScalarMulExtension(x, p.DEGREE),
|
||||||
@@ -109,7 +135,7 @@ func (p *PlonkChip) evalVanishingPoly(zetaPowN QuadraticExtension) []QuadraticEx
|
|||||||
// L_0(zeta) (Z(zeta) - 1) = 0
|
// L_0(zeta) (Z(zeta) - 1) = 0
|
||||||
z1_term := p.qe.MulExtension(
|
z1_term := p.qe.MulExtension(
|
||||||
l0Zeta,
|
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)
|
vanishingZ1Terms = append(vanishingZ1Terms, z1_term)
|
||||||
|
|
||||||
numeratorValues := make([]QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
numeratorValues := make([]QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||||
@@ -187,7 +213,7 @@ func (p *PlonkChip) Verify() {
|
|||||||
vanishingPolysZeta := p.evalVanishingPoly(zetaPowN)
|
vanishingPolysZeta := p.evalVanishingPoly(zetaPowN)
|
||||||
|
|
||||||
// Calculate Z(H)
|
// 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.
|
// `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)`
|
// 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) {
|
for i := 0; i < len(p.openings.QuotientPolys); i += int(p.commonData.QuotientDegreeFactor) {
|
||||||
prod := p.qe.MulExtension(
|
prod := p.qe.MulExtension(
|
||||||
zHZeta,
|
zHZeta,
|
||||||
reduceWithPowers(
|
p.qe.ReduceWithPowers(
|
||||||
p.qe,
|
|
||||||
p.openings.QuotientPolys[i:i+int(p.commonData.QuotientDegreeFactor)],
|
p.openings.QuotientPolys[i:i+int(p.commonData.QuotientDegreeFactor)],
|
||||||
zetaPowN,
|
zetaPowN,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type QuadraticExtensionAPI struct {
|
|||||||
W F
|
W F
|
||||||
DTH_ROOT F
|
DTH_ROOT F
|
||||||
|
|
||||||
ONE QuadraticExtension
|
ONE_QE QuadraticExtension
|
||||||
ZERO_QE QuadraticExtension
|
ZERO_QE QuadraticExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *Quadrat
|
|||||||
W: NewFieldElement(7),
|
W: NewFieldElement(7),
|
||||||
DTH_ROOT: NewFieldElement(18446744069414584320),
|
DTH_ROOT: NewFieldElement(18446744069414584320),
|
||||||
|
|
||||||
ONE: QuadraticExtension{ONE_F, ZERO_F},
|
ONE_QE: QuadraticExtension{ONE_F, ZERO_F},
|
||||||
ZERO_QE: QuadraticExtension{ZERO_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))
|
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
|
// TODO: Instead of calculating the inverse within the circuit, can witness the
|
||||||
// inverse and assert that a_inverse * a = 1. Should reduce # of constraints.
|
// inverse and assert that a_inverse * a = 1. Should reduce # of constraints.
|
||||||
func (c *QuadraticExtensionAPI) InverseExtension(a QuadraticExtension) QuadraticExtension {
|
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 {
|
func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent uint64) QuadraticExtension {
|
||||||
switch exponent {
|
switch exponent {
|
||||||
case 0:
|
case 0:
|
||||||
return c.ONE
|
return c.ONE_QE
|
||||||
case 1:
|
case 1:
|
||||||
return a
|
return a
|
||||||
case 2:
|
case 2:
|
||||||
@@ -94,7 +98,7 @@ func (c *QuadraticExtensionAPI) ExpU64Extension(a QuadraticExtension, exponent u
|
|||||||
}
|
}
|
||||||
|
|
||||||
current := a
|
current := a
|
||||||
product := c.ONE
|
product := c.ONE_QE
|
||||||
|
|
||||||
for i := 0; i < bits.Len64(exponent); i++ {
|
for i := 0; i < bits.Len64(exponent); i++ {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
@@ -125,6 +129,16 @@ func (c *QuadraticExtensionAPI) ReduceWithPowers(terms []QuadraticExtension, sca
|
|||||||
return sum
|
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 {
|
func (c *QuadraticExtensionAPI) Lookup2(b0 frontend.Variable, b1 frontend.Variable, qe0, qe1, qe2, qe3 QuadraticExtension) QuadraticExtension {
|
||||||
var retQE QuadraticExtension
|
var retQE QuadraticExtension
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user