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.New(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.New(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.New(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}