arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonky2_verifier/gate.go
plonky2_verifier/gate.goRaw
 1package plonky2_verifier
 2
 3import (
 4	"fmt"
 5	. "gnark-plonky2-verifier/field"
 6	"regexp"
 7)
 8
 9type gate interface {
10	Id() string
11	EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension
12}
13
14var gateRegexHandlers = map[*regexp.Regexp]func(parameters map[string]string) gate{
15	aritheticGateRegex:          deserializeArithmeticGate,
16	aritheticExtensionGateRegex: deserializeExtensionArithmeticGate,
17	baseSumGateRegex:            deserializeBaseSumGate,
18	constantGateRegex:           deserializeConstantGate,
19	cosetInterpolationGateRegex: deserializeCosetInterpolationGate,
20	exponentiationGateRegex:     deserializeExponentiationGate,
21	mulExtensionGateRegex:       deserializeMulExtensionGate,
22	noopGateRegex:               deserializeNoopGate,
23	poseidonGateRegex:           deserializePoseidonGate,
24	publicInputGateRegex:        deserializePublicInputGate,
25	randomAccessGateRegex:       deserializeRandomAccessGate,
26	reducingExtensionGateRegex:  deserializeReducingExtensionGate,
27	reducingGateRegex:           deserializeReducingGate,
28}
29
30func GateInstanceFromId(gateId string) gate {
31	for regex, handler := range gateRegexHandlers {
32		matches := regex.FindStringSubmatch(gateId)
33		if matches != nil {
34			parameters := make(map[string]string)
35			for i, name := range regex.SubexpNames() {
36				if i != 0 && name != "" {
37					parameters[name] = matches[i]
38				}
39			}
40
41			if matches != nil {
42				return handler(parameters)
43			}
44		}
45	}
46	panic(fmt.Sprintf("Unknown gate ID %s", gateId))
47}
48
49func (p *PlonkChip) computeFilter(
50	row uint64,
51	groupRange Range,
52	s QuadraticExtension,
53	manySelector bool,
54) QuadraticExtension {
55	product := p.qeAPI.ONE_QE
56	for i := groupRange.start; i < groupRange.end; i++ {
57		if i == uint64(row) {
58			continue
59		}
60
61		product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(i)), s))
62	}
63
64	if manySelector {
65		product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(UNUSED_SELECTOR)), s))
66	}
67
68	return product
69}
70
71func (p *PlonkChip) evalFiltered(
72	g gate,
73	vars EvaluationVars,
74	row uint64,
75	selectorIndex uint64,
76	groupRange Range,
77	numSelectors uint64,
78) []QuadraticExtension {
79	filter := p.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1)
80
81	vars.RemovePrefix(numSelectors)
82
83	unfiltered := g.EvalUnfiltered(p, vars)
84	for i := range unfiltered {
85		unfiltered[i] = p.qeAPI.MulExtension(unfiltered[i], filter)
86	}
87	return unfiltered
88}