gnark-plonky2-verifier/plonky2_verifier/reducing_gate.go
plonky2_verifier/reducing_gate.goRaw
1package plonky2_verifier
2
3import (
4 "fmt"
5 . "gnark-plonky2-verifier/field"
6 "regexp"
7 "strconv"
8)
9
10var reducingGateRegex = regexp.MustCompile("ReducingGate { num_coeffs: (?P<numCoeffs>[0-9]+) }")
11
12func deserializeReducingGate(parameters map[string]string) gate {
13 // Has the format "ReducingGate { num_coeffs: 33 }"
14 numCoeffs, hasNumCoeffs := parameters["numCoeffs"]
15 if !hasNumCoeffs {
16 panic("Missing field num_coeffs in ReducingGate")
17 }
18
19 numCoeffsInt, err := strconv.Atoi(numCoeffs)
20 if err != nil {
21 panic("Invalid num_coeffs field in ReducingGate")
22 }
23
24 return NewReducingGate(uint64(numCoeffsInt))
25}
26
27type ReducingGate struct {
28 numCoeffs uint64
29}
30
31const START_COEFFS_REDUCING_GATE = 3 * D
32
33func NewReducingGate(numCoeffs uint64) *ReducingGate {
34 return &ReducingGate{
35 numCoeffs: numCoeffs,
36 }
37}
38
39func (g *ReducingGate) Id() string {
40 return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
41}
42
43func (g *ReducingGate) wiresOutput() Range {
44 return Range{0, D}
45}
46
47func (g *ReducingGate) wiresAlpha() Range {
48 return Range{D, 2 * D}
49}
50
51func (g *ReducingGate) wiresOldAcc() Range {
52 return Range{2 * D, 3 * D}
53}
54
55func (g *ReducingGate) wiresCoeff() Range {
56 return Range{START_COEFFS_REDUCING_GATE, START_COEFFS_REDUCING_GATE + g.numCoeffs}
57}
58
59func (g *ReducingGate) startAccs() uint64 {
60 return START_COEFFS_REDUCING_GATE + g.numCoeffs
61}
62
63func (g *ReducingGate) wiresAccs(i uint64) Range {
64 if i >= g.numCoeffs {
65 panic("Accumulator index out of bounds")
66 }
67
68 if i == g.numCoeffs-1 {
69 return g.wiresOutput()
70 }
71
72 return Range{g.startAccs() + D*i, g.startAccs() + D*(i+1)}
73}
74
75func (g *ReducingGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension {
76 alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
77 oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
78
79 coeffs := []QuadraticExtension{}
80 coeffsRange := g.wiresCoeff()
81 for i := coeffsRange.start; i < coeffsRange.end; i++ {
82 coeffs = append(coeffs, vars.localWires[i])
83 }
84
85 accs := []QEAlgebra{}
86 for i := uint64(0); i < g.numCoeffs; i++ {
87 accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i)))
88 }
89
90 constraints := []QuadraticExtension{}
91 acc := oldAcc
92 for i := uint64(0); i < g.numCoeffs; i++ {
93 var coeff QEAlgebra
94 for j := 0; j < D; j++ {
95 coeff[j] = p.qeAPI.ZERO_QE
96 }
97 coeff[0] = coeffs[i]
98 tmp := p.qeAPI.MulExtensionAlgebra(acc, alpha)
99 tmp = p.qeAPI.AddExtensionAlgebra(tmp, coeff)
100 tmp = p.qeAPI.SubExtensionAlgebra(tmp, accs[i])
101 for j := 0; j < D; j++ {
102 constraints = append(constraints, tmp[j])
103 }
104 acc = accs[i]
105 }
106
107 return constraints
108}