|
package goldilocks
|
|
|
|
import "github.com/consensys/gnark-crypto/field/goldilocks"
|
|
|
|
const D = 2
|
|
|
|
type QuadraticExtensionAlgebraVariable = [D]QuadraticExtensionVariable
|
|
|
|
func NewQuadraticExtensionAlgebraVariable(
|
|
a QuadraticExtensionVariable,
|
|
b QuadraticExtensionVariable,
|
|
) QuadraticExtensionAlgebraVariable {
|
|
return QuadraticExtensionAlgebraVariable{a, b}
|
|
}
|
|
|
|
func (p QuadraticExtensionVariable) ToQuadraticExtensionAlgebra() QuadraticExtensionAlgebraVariable {
|
|
return [2]QuadraticExtensionVariable{p, ZeroExtension()}
|
|
}
|
|
|
|
func ZeroExtensionAlgebra() QuadraticExtensionAlgebraVariable {
|
|
return ZeroExtension().ToQuadraticExtensionAlgebra()
|
|
}
|
|
|
|
func OneExtensionAlgebra() QuadraticExtensionAlgebraVariable {
|
|
return OneExtension().ToQuadraticExtensionAlgebra()
|
|
}
|
|
|
|
func (p *GoldilocksApi) AddExtensionAlgebra(
|
|
a QuadraticExtensionAlgebraVariable,
|
|
b QuadraticExtensionAlgebraVariable,
|
|
) QuadraticExtensionAlgebraVariable {
|
|
var sum QuadraticExtensionAlgebraVariable
|
|
for i := 0; i < D; i++ {
|
|
sum[i] = p.AddExtension(a[i], b[i])
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func (p *GoldilocksApi) SubExtensionAlgebra(
|
|
a QuadraticExtensionAlgebraVariable,
|
|
b QuadraticExtensionAlgebraVariable,
|
|
) QuadraticExtensionAlgebraVariable {
|
|
var diff QuadraticExtensionAlgebraVariable
|
|
for i := 0; i < D; i++ {
|
|
diff[i] = p.SubExtension(a[i], b[i])
|
|
}
|
|
return diff
|
|
}
|
|
|
|
func (p GoldilocksApi) MulExtensionAlgebra(
|
|
a QuadraticExtensionAlgebraVariable,
|
|
b QuadraticExtensionAlgebraVariable,
|
|
) QuadraticExtensionAlgebraVariable {
|
|
var inner [D][]QuadraticExtensionAlgebraVariable
|
|
var innerW [D][]QuadraticExtensionAlgebraVariable
|
|
|
|
for i := 0; i < D; i++ {
|
|
for j := 0; j < D-i; j++ {
|
|
idx := (i + j) % D
|
|
inner[idx] = append(inner[idx], QuadraticExtensionAlgebraVariable{a[i], b[j]})
|
|
}
|
|
for j := D - i; j < D; j++ {
|
|
idx := (i + j) % D
|
|
innerW[idx] = append(innerW[idx], QuadraticExtensionAlgebraVariable{a[i], b[j]})
|
|
}
|
|
}
|
|
|
|
var product QuadraticExtensionAlgebraVariable
|
|
for i := 0; i < D; i++ {
|
|
acc := p.InnerProductExtension(NewVariable(W), ZeroExtension(), innerW[i])
|
|
product[i] = p.InnerProductExtension(One(), acc, inner[i])
|
|
}
|
|
|
|
return product
|
|
}
|
|
|
|
func (p *GoldilocksApi) ScalarMulExtensionAlgebra(
|
|
a QuadraticExtensionVariable,
|
|
b QuadraticExtensionAlgebraVariable,
|
|
) QuadraticExtensionAlgebraVariable {
|
|
var product QuadraticExtensionAlgebraVariable
|
|
for i := 0; i < D; i++ {
|
|
product[i] = p.MulExtension(a, b[i])
|
|
}
|
|
return product
|
|
}
|
|
|
|
func (p *GoldilocksApi) PartialInterpolateExtAlgebra(
|
|
domain []goldilocks.Element,
|
|
values []QuadraticExtensionAlgebraVariable,
|
|
barycentricWeights []goldilocks.Element,
|
|
point QuadraticExtensionAlgebraVariable,
|
|
initialEval QuadraticExtensionAlgebraVariable,
|
|
initialPartialProd QuadraticExtensionAlgebraVariable,
|
|
) (QuadraticExtensionAlgebraVariable, QuadraticExtensionAlgebraVariable) {
|
|
n := len(values)
|
|
if n == 0 {
|
|
panic("Cannot interpolate with no values")
|
|
}
|
|
if n != len(domain) {
|
|
panic("Domain and values must have the same length")
|
|
}
|
|
if n != len(barycentricWeights) {
|
|
panic("Domain and barycentric weights must have the same length")
|
|
}
|
|
|
|
newEval := initialEval
|
|
newPartialProd := initialPartialProd
|
|
for i := 0; i < n; i++ {
|
|
val := values[i]
|
|
x := domain[i]
|
|
xField := NewVariable(x)
|
|
xQE := xField.ToQuadraticExtension()
|
|
xQEAlgebra := xQE.ToQuadraticExtensionAlgebra()
|
|
weight := NewVariable(barycentricWeights[i].Uint64()).ToQuadraticExtension()
|
|
term := p.SubExtensionAlgebra(point, xQEAlgebra)
|
|
weightedVal := p.ScalarMulExtensionAlgebra(weight, val)
|
|
newEval = p.MulExtensionAlgebra(newEval, term)
|
|
tmp := p.MulExtensionAlgebra(weightedVal, newPartialProd)
|
|
newEval = p.AddExtensionAlgebra(newEval, tmp)
|
|
newPartialProd = p.MulExtensionAlgebra(newPartialProd, term)
|
|
}
|
|
|
|
return newEval, newPartialProd
|
|
}
|