mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 00:51:33 +01:00
fix for V-SCT-VUL-007 and V-SCT-VUL-011
This commit is contained in:
36
fri/fri.go
36
fri/fri.go
@@ -238,9 +238,11 @@ func (f *Chip) friCombineInitial(
|
|||||||
numerator := f.gl.SubExtensionNoReduce(reducedEvals, reducedOpenings)
|
numerator := f.gl.SubExtensionNoReduce(reducedEvals, reducedOpenings)
|
||||||
denominator := f.gl.SubExtension(subgroupX_QE, point)
|
denominator := f.gl.SubExtension(subgroupX_QE, point)
|
||||||
sum = f.gl.MulExtension(f.gl.ExpExtension(friAlpha, uint64(len(evals))), sum)
|
sum = f.gl.MulExtension(f.gl.ExpExtension(friAlpha, uint64(len(evals))), sum)
|
||||||
|
inv, hasInv := f.gl.InverseExtension(denominator)
|
||||||
|
f.api.AssertIsEqual(hasInv, frontend.Variable(1))
|
||||||
sum = f.gl.MulAddExtension(
|
sum = f.gl.MulAddExtension(
|
||||||
numerator,
|
numerator,
|
||||||
f.gl.InverseExtension(denominator),
|
inv,
|
||||||
sum,
|
sum,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -272,17 +274,23 @@ func (f *Chip) interpolate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sum := gl.ZeroExtension()
|
sum := gl.ZeroExtension()
|
||||||
|
|
||||||
|
lookupFromPoints := frontend.Variable(1)
|
||||||
for i := 0; i < len(xPoints); i++ {
|
for i := 0; i < len(xPoints); i++ {
|
||||||
|
quotient, hasQuotient := f.gl.DivExtension(
|
||||||
|
barycentricWeights[i],
|
||||||
|
f.gl.SubExtension(
|
||||||
|
x,
|
||||||
|
xPoints[i],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
lookupFromPoints = f.api.Mul(hasQuotient, lookupFromPoints)
|
||||||
|
|
||||||
sum = f.gl.AddExtension(
|
sum = f.gl.AddExtension(
|
||||||
f.gl.MulExtension(
|
f.gl.MulExtension(
|
||||||
f.gl.DivExtension(
|
|
||||||
barycentricWeights[i],
|
|
||||||
f.gl.SubExtension(
|
|
||||||
x,
|
|
||||||
xPoints[i],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
yPoints[i],
|
yPoints[i],
|
||||||
|
quotient,
|
||||||
),
|
),
|
||||||
sum,
|
sum,
|
||||||
)
|
)
|
||||||
@@ -290,17 +298,17 @@ func (f *Chip) interpolate(
|
|||||||
|
|
||||||
interpolation := f.gl.MulExtension(lX, sum)
|
interpolation := f.gl.MulExtension(lX, sum)
|
||||||
|
|
||||||
returnField := interpolation
|
lookupVal := gl.ZeroExtension()
|
||||||
// Now check if x is already within the xPoints
|
// Now check if x is already within the xPoints
|
||||||
for i := 0; i < len(xPoints); i++ {
|
for i := 0; i < len(xPoints); i++ {
|
||||||
returnField = f.gl.Lookup(
|
lookupVal = f.gl.Lookup(
|
||||||
f.gl.IsZero(f.gl.SubExtension(x, xPoints[i])),
|
f.gl.IsZero(f.gl.SubExtension(x, xPoints[i])),
|
||||||
returnField,
|
lookupVal,
|
||||||
yPoints[i],
|
yPoints[i],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnField
|
return f.gl.Lookup(lookupFromPoints, lookupVal, interpolation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Chip) computeEvaluation(
|
func (f *Chip) computeEvaluation(
|
||||||
@@ -367,7 +375,9 @@ func (f *Chip) computeEvaluation(
|
|||||||
}
|
}
|
||||||
// Take the inverse of the barycentric weights
|
// Take the inverse of the barycentric weights
|
||||||
// OPTIMIZE: Can provide a witness to this value
|
// OPTIMIZE: Can provide a witness to this value
|
||||||
barycentricWeights[i] = f.gl.InverseExtension(barycentricWeights[i])
|
inv, hasInv := f.gl.InverseExtension(barycentricWeights[i])
|
||||||
|
f.api.AssertIsEqual(hasInv, frontend.Variable(1))
|
||||||
|
barycentricWeights[i] = inv
|
||||||
}
|
}
|
||||||
|
|
||||||
return f.interpolate(beta, xPoints, yPoints, barycentricWeights)
|
return f.interpolate(beta, xPoints, yPoints, barycentricWeights)
|
||||||
|
|||||||
@@ -237,18 +237,21 @@ func ReduceHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Computes the inverse of a field element x such that x * x^-1 = 1.
|
// Computes the inverse of a field element x such that x * x^-1 = 1.
|
||||||
func (p *Chip) Inverse(x Variable) Variable {
|
func (p *Chip) Inverse(x Variable) (Variable, frontend.Variable) {
|
||||||
result, err := p.api.Compiler().NewHint(InverseHint, 1, x.Limb)
|
result, err := p.api.Compiler().NewHint(InverseHint, 2, x.Limb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
inverse := NewVariable(result[0])
|
inverse := NewVariable(result[0])
|
||||||
|
hasInv := frontend.Variable(result[1])
|
||||||
p.RangeCheck(inverse)
|
p.RangeCheck(inverse)
|
||||||
|
|
||||||
product := p.Mul(inverse, x)
|
product := p.Mul(inverse, x)
|
||||||
p.api.AssertIsEqual(product.Limb, frontend.Variable(1))
|
productToCheck := p.api.Select(hasInv, product.Limb, frontend.Variable(1))
|
||||||
return inverse
|
p.api.AssertIsEqual(productToCheck, frontend.Variable(1))
|
||||||
|
|
||||||
|
return inverse, hasInv
|
||||||
}
|
}
|
||||||
|
|
||||||
// The hint used to compute Inverse.
|
// The hint used to compute Inverse.
|
||||||
@@ -264,11 +267,19 @@ func InverseHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error {
|
|||||||
|
|
||||||
inputGl := goldilocks.NewElement(input.Uint64())
|
inputGl := goldilocks.NewElement(input.Uint64())
|
||||||
resultGl := goldilocks.NewElement(0)
|
resultGl := goldilocks.NewElement(0)
|
||||||
|
|
||||||
|
// Will set resultGL if inputGL == 0
|
||||||
resultGl.Inverse(&inputGl)
|
resultGl.Inverse(&inputGl)
|
||||||
|
|
||||||
result := big.NewInt(0)
|
result := big.NewInt(0)
|
||||||
results[0] = resultGl.BigInt(result)
|
results[0] = resultGl.BigInt(result)
|
||||||
|
|
||||||
|
hasInvInt64 := int64(0)
|
||||||
|
if !inputGl.IsZero() {
|
||||||
|
hasInvInt64 = 1
|
||||||
|
}
|
||||||
|
results[1] = big.NewInt(hasInvInt64)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ func (p *Chip) InnerProductExtension(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Computes the inverse of a quadratic extension variable in the Goldilocks field.
|
// Computes the inverse of a quadratic extension variable in the Goldilocks field.
|
||||||
func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable {
|
func (p *Chip) InverseExtension(a QuadraticExtensionVariable) (QuadraticExtensionVariable, frontend.Variable) {
|
||||||
a0IsZero := p.api.IsZero(a[0].Limb)
|
a0IsZero := p.api.IsZero(a[0].Limb)
|
||||||
a1IsZero := p.api.IsZero(a[1].Limb)
|
a1IsZero := p.api.IsZero(a[1].Limb)
|
||||||
p.api.AssertIsEqual(p.api.Mul(a0IsZero, a1IsZero), frontend.Variable(0))
|
p.api.AssertIsEqual(p.api.Mul(a0IsZero, a1IsZero), frontend.Variable(0))
|
||||||
@@ -135,12 +135,15 @@ func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtension
|
|||||||
p.Mul(a[1], NewVariable(DTH_ROOT)),
|
p.Mul(a[1], NewVariable(DTH_ROOT)),
|
||||||
}
|
}
|
||||||
aPowR := p.MulExtension(aPowRMinus1, a)
|
aPowR := p.MulExtension(aPowRMinus1, a)
|
||||||
return p.ScalarMulExtension(aPowRMinus1, p.Inverse(aPowR[0]))
|
|
||||||
|
aPowRInv, hasInv := p.Inverse(aPowR[0])
|
||||||
|
return p.ScalarMulExtension(aPowRMinus1, aPowRInv), hasInv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divides two quadratic extension variables in the Goldilocks field.
|
// Divides two quadratic extension variables in the Goldilocks field.
|
||||||
func (p *Chip) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable {
|
func (p *Chip) DivExtension(a, b QuadraticExtensionVariable) (QuadraticExtensionVariable, frontend.Variable) {
|
||||||
return p.MulExtension(a, p.InverseExtension(b))
|
bInv, hasInv := p.InverseExtension(b)
|
||||||
|
return p.MulExtension(a, bInv), hasInv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exponentiates a quadratic extension variable to some exponent in the Golidlocks field.
|
// Exponentiates a quadratic extension variable to some exponent in the Golidlocks field.
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ type TestQuadraticExtensionDivCircuit struct {
|
|||||||
|
|
||||||
func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error {
|
func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error {
|
||||||
glAPI := New(api)
|
glAPI := New(api)
|
||||||
actualRes := glAPI.DivExtension(c.Operand1, c.Operand2)
|
actualRes, _ := glAPI.DivExtension(c.Operand1, c.Operand2)
|
||||||
glAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0])
|
glAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0])
|
||||||
glAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1])
|
glAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1])
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -71,10 +71,15 @@ func (p *PlonkChip) evalL0(x gl.QuadraticExtensionVariable, xPowN gl.QuadraticEx
|
|||||||
glApi.ScalarMulExtension(x, p.DEGREE),
|
glApi.ScalarMulExtension(x, p.DEGREE),
|
||||||
p.DEGREE_QE,
|
p.DEGREE_QE,
|
||||||
)
|
)
|
||||||
return glApi.DivExtension(
|
|
||||||
|
quotient, hasQuotient := glApi.DivExtension(
|
||||||
evalZeroPoly,
|
evalZeroPoly,
|
||||||
denominator,
|
denominator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
p.api.AssertIsEqual(hasQuotient, frontend.Variable(1))
|
||||||
|
|
||||||
|
return quotient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PlonkChip) checkPartialProducts(
|
func (p *PlonkChip) checkPartialProducts(
|
||||||
|
|||||||
Reference in New Issue
Block a user