gnark-plonky2-verifier/verifier/internal/gates/base_sum_gate.go
verifier/internal/gates/base_sum_gate.goRaw
1package gates
2
3import (
4 "fmt"
5 "regexp"
6 "strconv"
7
8 "github.com/consensys/gnark/frontend"
9 "github.com/succinctlabs/gnark-plonky2-verifier/field"
10)
11
12var baseSumGateRegex = regexp.MustCompile(`BaseSumGate { num_limbs: (?P<numLimbs>[0-9]+) } \+ Base: (?P<base>[0-9]+)`)
13
14func deserializeBaseSumGate(parameters map[string]string) Gate {
15
16 // Has the format "BaseSumGate { num_limbs: 32 } + Base: 2"
17 numLimbs, hasNumLimbs := parameters["numLimbs"]
18 base, hasBase := parameters["base"]
19 if !hasNumLimbs || !hasBase {
20 panic("Missing field num_limbs or base in BaseSumGate")
21 }
22
23 numLimbsInt, err := strconv.Atoi(numLimbs)
24 if err != nil {
25 panic("Invalid num_limbs field in BaseSumGate")
26 }
27
28 baseInt, err := strconv.Atoi(base)
29 if err != nil {
30 panic("Invalid base field in BaseSumGate")
31 }
32
33 return NewBaseSumGate(uint64(numLimbsInt), uint64(baseInt))
34}
35
36const (
37 BASESUM_GATE_WIRE_SUM = 0
38 BASESUM_GATE_START_LIMBS = 1
39)
40
41type BaseSumGate struct {
42 numLimbs uint64
43 base uint64
44}
45
46func NewBaseSumGate(numLimbs uint64, base uint64) *BaseSumGate {
47 return &BaseSumGate{
48 numLimbs: numLimbs,
49 base: base,
50 }
51}
52
53func (g *BaseSumGate) Id() string {
54 return fmt.Sprintf("BaseSumGate { num_ops: %d } + Base: %d", g.numLimbs, g.base)
55}
56
57func (g *BaseSumGate) limbs() []uint64 {
58 limbIndices := make([]uint64, g.numLimbs)
59 for i := uint64(0); i < g.numLimbs; i++ {
60 limbIndices[i] = uint64(BASESUM_GATE_START_LIMBS + i)
61 }
62
63 return limbIndices
64}
65
66func (g *BaseSumGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
67 sum := vars.localWires[BASESUM_GATE_WIRE_SUM]
68 limbs := make([]field.QuadraticExtension, g.numLimbs)
69 limbIndices := g.limbs()
70 for i, limbIdx := range limbIndices {
71 limbs[i] = vars.localWires[limbIdx]
72 }
73
74 base_qe := qeAPI.FieldToQE(field.NewFieldConst(g.base))
75 computedSum := qeAPI.ReduceWithPowers(
76 limbs,
77 base_qe,
78 )
79
80 var constraints []field.QuadraticExtension
81 constraints = append(constraints, qeAPI.SubExtension(computedSum, sum))
82 for _, limb := range limbs {
83 acc := qeAPI.ONE_QE
84 for i := uint64(0); i < g.base; i++ {
85 difference := qeAPI.SubExtension(limb, qeAPI.FieldToQE(field.NewFieldConst(i)))
86 acc = qeAPI.MulExtension(acc, difference)
87 }
88 constraints = append(constraints, acc)
89 }
90
91 return constraints
92}