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