gnark-plonky2-verifier/plonky2_verifier/gate.go
plonky2_verifier/gate.goRaw
1package plonky2_verifier
2
3import (
4 . "gnark-plonky2-verifier/field"
5 "strconv"
6 "strings"
7)
8
9type gate interface {
10 Id() string
11 EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension
12}
13
14func GateInstanceFromId(gateId string) gate {
15 if strings.HasPrefix(gateId, "ArithmeticGate") {
16 numOpsRaw := strings.Split(gateId, ":")[1]
17 numOpsRaw = strings.Split(numOpsRaw, "}")[0]
18 numOpsRaw = strings.TrimSpace(numOpsRaw)
19 numOps, err := strconv.Atoi(numOpsRaw)
20 if err != nil {
21 panic("Invalid gate ID for ArithmeticGate")
22 }
23 return NewArithmeticGate(uint64(numOps))
24 }
25
26 if gateId == "ConstantGate" {
27 numConstsRaw := strings.Split(gateId, ":")[1]
28 numConstsRaw = strings.Split(numConstsRaw, "}")[0]
29 numConstsRaw = strings.TrimSpace(numConstsRaw)
30 numConsts, err := strconv.Atoi(numConstsRaw)
31 if err != nil {
32 panic("Invalid gate ID")
33 }
34 return NewConstantGate(uint64(numConsts))
35 }
36
37 if gateId == "NoopGate" {
38 return NewNoopGate()
39 }
40
41 if gateId == "PublicInputGate" {
42 return NewPublicInputGate()
43 }
44
45 if strings.HasPrefix(gateId, "PoseidonGate") {
46 return NewPoseidonGate()
47 }
48
49 panic("Unknown gate ID")
50}
51
52func (p *PlonkChip) computeFilter(
53 row uint64,
54 groupRange Range,
55 s QuadraticExtension,
56 manySelector bool,
57) QuadraticExtension {
58 product := p.qeAPI.ONE_QE
59 for i := groupRange.start; i < groupRange.end; i++ {
60 if i == uint64(row) {
61 continue
62 }
63
64 product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(i)), s))
65 }
66
67 if manySelector {
68 product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(UNUSED_SELECTOR)), s))
69 }
70
71 return product
72}
73
74func (p *PlonkChip) evalFiltered(
75 g gate,
76 vars EvaluationVars,
77 row uint64,
78 selectorIndex uint64,
79 groupRange Range,
80 numSelectors uint64,
81) []QuadraticExtension {
82 filter := p.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1)
83
84 vars.RemovePrefix(numSelectors)
85
86 unfiltered := g.EvalUnfiltered(p, vars)
87 for i := range unfiltered {
88 unfiltered[i] = p.qeAPI.MulExtension(unfiltered[i], filter)
89 }
90 return unfiltered
91}