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