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