arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
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}