package gates import ( "github.com/consensys/gnark/frontend" "github.com/succinctlabs/gnark-plonky2-verifier/field" ) type EvaluateGatesChip struct { api frontend.API qeAPI *field.QuadraticExtensionAPI gates []Gate numGateConstraints uint64 selectorsInfo SelectorsInfo } func NewEvaluateGatesChip( api frontend.API, qeAPI *field.QuadraticExtensionAPI, gates []Gate, numGateConstraints uint64, selectorsInfo SelectorsInfo, ) *EvaluateGatesChip { return &EvaluateGatesChip{ api: api, qeAPI: qeAPI, gates: gates, numGateConstraints: numGateConstraints, selectorsInfo: selectorsInfo, } } func (g *EvaluateGatesChip) computeFilter( row uint64, groupRange Range, s field.QuadraticExtension, manySelector bool, ) field.QuadraticExtension { product := g.qeAPI.ONE_QE for i := groupRange.start; i < groupRange.end; i++ { if i == uint64(row) { continue } product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(i)), s)) } if manySelector { product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(UNUSED_SELECTOR)), s)) } return product } func (g *EvaluateGatesChip) evalFiltered( gate Gate, vars EvaluationVars, row uint64, selectorIndex uint64, groupRange Range, numSelectors uint64, ) []field.QuadraticExtension { filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1) vars.RemovePrefix(numSelectors) unfiltered := gate.EvalUnfiltered(g.api, g.qeAPI, vars) for i := range unfiltered { unfiltered[i] = g.qeAPI.MulExtension(unfiltered[i], filter) } return unfiltered } func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []field.QuadraticExtension { constraints := make([]field.QuadraticExtension, g.numGateConstraints) for i := range constraints { constraints[i] = g.qeAPI.ZERO_QE } for i, gate := range g.gates { selectorIndex := g.selectorsInfo.selectorIndices[i] gateConstraints := g.evalFiltered( gate, vars, uint64(i), selectorIndex, g.selectorsInfo.groups[selectorIndex], g.selectorsInfo.NumSelectors(), ) for i, constraint := range gateConstraints { if uint64(i) >= g.numGateConstraints { panic("num_constraints() gave too low of a number") } constraints[i] = g.qeAPI.AddExtension(constraints[i], constraint) } } return constraints }