package plonky2_verifier
|
|
|
|
import (
|
|
"fmt"
|
|
. "gnark-plonky2-verifier/field"
|
|
)
|
|
|
|
const (
|
|
WIRE_SUM = 0
|
|
START_LIMBS = 1
|
|
)
|
|
|
|
type BaseSumGate struct {
|
|
numLimbs uint64
|
|
base uint64
|
|
}
|
|
|
|
func NewBaseSumGate(numLimbs uint64, base uint64) *BaseSumGate {
|
|
return &BaseSumGate{
|
|
numLimbs: numLimbs,
|
|
base: base,
|
|
}
|
|
}
|
|
|
|
func (g *BaseSumGate) Id() string {
|
|
return fmt.Sprintf("BaseSumGate { num_ops: %d } + Base: %d", g.numLimbs, g.base)
|
|
}
|
|
|
|
func (g *BaseSumGate) limbs() []uint64 {
|
|
limbIndices := make([]uint64, g.numLimbs)
|
|
for i := uint64(0); i < g.numLimbs; i++ {
|
|
limbIndices[i] = uint64(START_LIMBS + i)
|
|
}
|
|
|
|
return limbIndices
|
|
}
|
|
|
|
func (g *BaseSumGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension {
|
|
sum := vars.localWires[WIRE_SUM]
|
|
limbs := make([]QuadraticExtension, g.numLimbs)
|
|
limbIndices := g.limbs()
|
|
for i, limbIdx := range limbIndices {
|
|
limbs[i] = vars.localWires[limbIdx]
|
|
}
|
|
|
|
base_qe := p.qeAPI.FieldToQE(NewFieldElement(g.base))
|
|
computedSum := p.qeAPI.ReduceWithPowers(
|
|
limbs,
|
|
base_qe,
|
|
)
|
|
|
|
var constraints []QuadraticExtension
|
|
constraints = append(constraints, p.qeAPI.SubExtension(computedSum, sum))
|
|
for _, limb := range limbs {
|
|
acc := p.qeAPI.ONE_QE
|
|
for i := uint64(0); i < g.base; i++ {
|
|
difference := p.qeAPI.SubExtension(limb, p.qeAPI.FieldToQE(NewFieldElement(i)))
|
|
acc = p.qeAPI.MulExtension(acc, difference)
|
|
}
|
|
constraints = append(constraints, acc)
|
|
}
|
|
|
|
return constraints
|
|
}
|