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