arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonk/gates/evaluate_gates.go
plonk/gates/evaluate_gates.goRaw
  1package gates
  2
  3import (
  4	"github.com/consensys/gnark/frontend"
  5	gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
  6)
  7
  8type EvaluateGatesChip struct {
  9	api frontend.API
 10
 11	gates              []Gate
 12	numGateConstraints uint64
 13
 14	selectorsInfo SelectorsInfo
 15}
 16
 17func NewEvaluateGatesChip(
 18	api frontend.API,
 19	gates []Gate,
 20	numGateConstraints uint64,
 21	selectorsInfo SelectorsInfo,
 22) *EvaluateGatesChip {
 23	return &EvaluateGatesChip{
 24		api: api,
 25
 26		gates:              gates,
 27		numGateConstraints: numGateConstraints,
 28
 29		selectorsInfo: selectorsInfo,
 30	}
 31}
 32
 33func (g *EvaluateGatesChip) computeFilter(
 34	row uint64,
 35	groupRange Range,
 36	s gl.QuadraticExtensionVariable,
 37	manySelector bool,
 38) gl.QuadraticExtensionVariable {
 39	glApi := gl.NewChip(g.api)
 40	product := gl.OneExtension()
 41	for i := groupRange.start; i < groupRange.end; i++ {
 42		if i == uint64(row) {
 43			continue
 44		}
 45		tmp := gl.NewQuadraticExtensionVariable(gl.NewVariable(i), gl.Zero())
 46		product = glApi.MulExtension(product, glApi.SubExtension(tmp, s))
 47	}
 48
 49	if manySelector {
 50		tmp := gl.NewQuadraticExtensionVariable(gl.NewVariable(UNUSED_SELECTOR), gl.Zero())
 51		product = glApi.MulExtension(product, glApi.SubExtension(tmp, s))
 52	}
 53
 54	return product
 55}
 56
 57func (g *EvaluateGatesChip) evalFiltered(
 58	gate Gate,
 59	vars EvaluationVars,
 60	row uint64,
 61	selectorIndex uint64,
 62	groupRange Range,
 63	numSelectors uint64,
 64) []gl.QuadraticExtensionVariable {
 65	glApi := gl.NewChip(g.api)
 66	filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1)
 67
 68	vars.RemovePrefix(numSelectors)
 69
 70	unfiltered := gate.EvalUnfiltered(g.api, *glApi, vars)
 71	for i := range unfiltered {
 72		unfiltered[i] = glApi.MulExtension(unfiltered[i], filter)
 73	}
 74	return unfiltered
 75}
 76
 77func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []gl.QuadraticExtensionVariable {
 78	glApi := gl.NewChip(g.api)
 79	constraints := make([]gl.QuadraticExtensionVariable, g.numGateConstraints)
 80	for i := range constraints {
 81		constraints[i] = gl.ZeroExtension()
 82	}
 83
 84	for i, gate := range g.gates {
 85		selectorIndex := g.selectorsInfo.selectorIndices[i]
 86
 87		gateConstraints := g.evalFiltered(
 88			gate,
 89			vars,
 90			uint64(i),
 91			selectorIndex,
 92			g.selectorsInfo.groups[selectorIndex],
 93			g.selectorsInfo.NumSelectors(),
 94		)
 95
 96		for i, constraint := range gateConstraints {
 97			if uint64(i) >= g.numGateConstraints {
 98				panic("num_constraints() gave too low of a number")
 99			}
100			constraints[i] = glApi.AddExtension(constraints[i], constraint)
101		}
102	}
103
104	return constraints
105}