You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.3 KiB

package gates
import (
"fmt"
"regexp"
"strconv"
"github.com/consensys/gnark/frontend"
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
)
var baseSumGateRegex = regexp.MustCompile(`BaseSumGate { num_limbs: (?P<numLimbs>[0-9]+) } \+ Base: (?P<base>[0-9]+)`)
func deserializeBaseSumGate(parameters map[string]string) Gate {
// Has the format "BaseSumGate { num_limbs: 32 } + Base: 2"
numLimbs, hasNumLimbs := parameters["numLimbs"]
base, hasBase := parameters["base"]
if !hasNumLimbs || !hasBase {
panic("Missing field num_limbs or base in BaseSumGate")
}
numLimbsInt, err := strconv.Atoi(numLimbs)
if err != nil {
panic("Invalid num_limbs field in BaseSumGate")
}
baseInt, err := strconv.Atoi(base)
if err != nil {
panic("Invalid base field in BaseSumGate")
}
return NewBaseSumGate(uint64(numLimbsInt), uint64(baseInt))
}
const (
BASESUM_GATE_WIRE_SUM = 0
BASESUM_GATE_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_limbs: %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(BASESUM_GATE_START_LIMBS + i)
}
return limbIndices
}
func (g *BaseSumGate) EvalUnfiltered(
api frontend.API,
glApi gl.Chip,
vars EvaluationVars,
) []gl.QuadraticExtensionVariable {
sum := vars.localWires[BASESUM_GATE_WIRE_SUM]
limbs := make([]gl.QuadraticExtensionVariable, g.numLimbs)
limbIndices := g.limbs()
for i, limbIdx := range limbIndices {
limbs[i] = vars.localWires[limbIdx]
}
baseQe := gl.NewQuadraticExtensionVariable(gl.NewVariable(g.base), gl.Zero())
computedSum := glApi.ReduceWithPowers(
limbs,
baseQe,
)
var constraints []gl.QuadraticExtensionVariable
constraints = append(constraints, glApi.SubExtension(computedSum, sum))
for _, limb := range limbs {
acc := gl.OneExtension()
for i := uint64(0); i < g.base; i++ {
difference := glApi.SubExtension(limb, gl.NewQuadraticExtensionVariable(gl.NewVariable(i), gl.Zero()))
acc = glApi.MulExtension(acc, difference)
}
constraints = append(constraints, acc)
}
return constraints
}