diff --git a/field/quadratic_extension.go b/field/quadratic_extension.go index ca2cb38..c999023 100644 --- a/field/quadratic_extension.go +++ b/field/quadratic_extension.go @@ -15,11 +15,21 @@ type QuadraticExtensionAPI struct { ONE_QE QuadraticExtension ZERO_QE QuadraticExtension + + ZERO_QE_ALGEBRA QEAlgebra } func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *QuadraticExtensionAPI { // TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64? + var ZERO_QE = QuadraticExtension{ZERO_F, ZERO_F} + + var ZERO_QE_ALGEBRA QEAlgebra + + for i := 0; i < D; i++ { + ZERO_QE_ALGEBRA[i] = ZERO_QE + } + return &QuadraticExtensionAPI{ fieldAPI: fieldAPI, @@ -27,7 +37,9 @@ func NewQuadraticExtensionAPI(fieldAPI frontend.API, degreeBits uint64) *Quadrat DTH_ROOT: NewFieldElement(18446744069414584320), ONE_QE: QuadraticExtension{ONE_F, ZERO_F}, - ZERO_QE: QuadraticExtension{ZERO_F, ZERO_F}, + ZERO_QE: ZERO_QE, + + ZERO_QE_ALGEBRA: ZERO_QE_ALGEBRA, } } diff --git a/plonky2_verifier/gate.go b/plonky2_verifier/gate.go index b0321d4..c215cd8 100644 --- a/plonky2_verifier/gate.go +++ b/plonky2_verifier/gate.go @@ -140,6 +140,24 @@ func GateInstanceFromId(gateId string) gate { return NewReducingExtensionGate(uint64(numCoeffs)) } + if strings.HasPrefix(gateId, "ReducingGate") { + // Has the format "ReducingGate { num_coeffs: 33 }" + + regEx := "ReducingGate { num_coeffs: (?P[0-9]+) }" + r, err := regexp.Compile(regEx) + if err != nil { + panic("Invalid ReducingGate regular expression") + } + + matches := getRegExMatches(r, gateId) + numCoeffs, hasNumCoeffs := matches["numCoeffs"] + if !hasNumCoeffs { + panic("Invalid ReducingGate ID") + } + + return NewReducingGate(uint64(numCoeffs)) + } + return nil //panic(fmt.Sprintf("Unknown gate ID %s", gateId)) } diff --git a/plonky2_verifier/gate_test.go b/plonky2_verifier/gate_test.go index ac40641..11d9470 100644 --- a/plonky2_verifier/gate_test.go +++ b/plonky2_verifier/gate_test.go @@ -415,7 +415,6 @@ var poseidonGateExpectedConstraints = []QuadraticExtension{ {NewFieldElement(3134481789780853760), NewFieldElement(10023938129020275945)}, } -// ReducingExtensionGate { num_coeffs: 33 } var reducingExtensionGateExpectedConstraints = []QuadraticExtension{ {NewFieldElement(12512260201049243975), NewFieldElement(5104620179714279781)}, {NewFieldElement(13013016297591764071), NewFieldElement(3905565448987160512)}, @@ -770,6 +769,7 @@ func TestGates(t *testing.T) { {&ArithmeticExtensionGate{numOps: 10}, arithmeticExtensionGateExpectedConstraints}, {&MultiplicationExtensionGate{numOps: 13}, mulExtensionGateExpectedConstraints}, {&ReducingExtensionGate{numCoeffs: 33}, reducingExtensionGateExpectedConstraints}, + {&ReducingGate{numCoeffs: 44}, reducingGateExpectedConstraints}, } for _, test := range gateTests { diff --git a/plonky2_verifier/reducing_extension_gate.go b/plonky2_verifier/reducing_extension_gate.go index fd504ed..7681d81 100644 --- a/plonky2_verifier/reducing_extension_gate.go +++ b/plonky2_verifier/reducing_extension_gate.go @@ -9,7 +9,7 @@ type ReducingExtensionGate struct { numCoeffs uint64 } -const START_COEFFS = 3 * D +const START_COEFFS_REDUCING_EXTENSION_GATE = 3 * D func NewReducingExtensionGate(numCoeffs uint64) *ReducingExtensionGate { return &ReducingExtensionGate{ @@ -34,11 +34,11 @@ func (g *ReducingExtensionGate) wiresOldAcc() Range { } func (g *ReducingExtensionGate) wiresCoeff(i uint64) Range { - return Range{START_COEFFS + D*i, START_COEFFS + D*(i+1)} + return Range{START_COEFFS_REDUCING_EXTENSION_GATE + D*i, START_COEFFS_REDUCING_EXTENSION_GATE + D*(i+1)} } func (g *ReducingExtensionGate) startAccs() uint64 { - return START_COEFFS + g.numCoeffs*D + return START_COEFFS_REDUCING_EXTENSION_GATE + g.numCoeffs*D } func (g *ReducingExtensionGate) wiresAccs(i uint64) Range { diff --git a/plonky2_verifier/reducing_gate.go b/plonky2_verifier/reducing_gate.go new file mode 100644 index 0000000..24240ae --- /dev/null +++ b/plonky2_verifier/reducing_gate.go @@ -0,0 +1,89 @@ +package plonky2_verifier + +import ( + "fmt" + . "gnark-plonky2-verifier/field" +) + +type ReducingGate struct { + numCoeffs uint64 +} + +const START_COEFFS_REDUCING_GATE = 3 * D + +func NewReducingGate(numCoeffs uint64) *ReducingGate { + return &ReducingGate{ + numCoeffs: numCoeffs, + } +} + +func (g *ReducingGate) Id() string { + return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs) +} + +func (g *ReducingGate) wiresOutput() Range { + return Range{0, D} +} + +func (g *ReducingGate) wiresAlpha() Range { + return Range{D, 2 * D} +} + +func (g *ReducingGate) wiresOldAcc() Range { + return Range{2 * D, 3 * D} +} + +func (g *ReducingGate) wiresCoeff() Range { + return Range{START_COEFFS_REDUCING_GATE, START_COEFFS_REDUCING_GATE + g.numCoeffs} +} + +func (g *ReducingGate) startAccs() uint64 { + return START_COEFFS_REDUCING_GATE + g.numCoeffs +} + +func (g *ReducingGate) wiresAccs(i uint64) Range { + if i >= g.numCoeffs { + panic("Accumulator index out of bounds") + } + + if i == g.numCoeffs-1 { + return g.wiresOutput() + } + + return Range{g.startAccs() + D*i, g.startAccs() + D*(i+1)} +} + +func (g *ReducingGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { + alpha := vars.GetLocalExtAlgebra(g.wiresAlpha()) + oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc()) + + coeffs := []QuadraticExtension{} + coeffsRange := g.wiresCoeff() + for i := coeffsRange.start; i < coeffsRange.end; i++ { + coeffs = append(coeffs, vars.localWires[i]) + } + + accs := []QEAlgebra{} + for i := uint64(0); i < g.numCoeffs; i++ { + accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i))) + } + + constraints := []QuadraticExtension{} + acc := oldAcc + for i := uint64(0); i < g.numCoeffs; i++ { + var coeff QEAlgebra + for j := 0; j < D; j++ { + coeff[j] = p.qeAPI.ZERO_QE + } + coeff[0] = coeffs[i] + tmp := p.qeAPI.MulExtensionAlgebra(acc, alpha) + tmp = p.qeAPI.AddExtensionAlgebra(tmp, coeff) + tmp = p.qeAPI.SubExtensionAlgebra(tmp, accs[i]) + for j := 0; j < D; j++ { + constraints = append(constraints, tmp[j]) + } + acc = accs[i] + } + + return constraints +}