Browse Source

reducing extension gate (#12)

main
Kevin Jue 2 years ago
committed by GitHub
parent
commit
2823cfbbcb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 8 deletions
  1. +3
    -3
      field/field.go
  2. +3
    -1
      plonky2_verifier/arithmetic_extension_gate.go
  3. +18
    -0
      plonky2_verifier/gate.go
  4. +1
    -0
      plonky2_verifier/gate_test.go
  5. +3
    -1
      plonky2_verifier/multiplication_extension_gate.go
  6. +84
    -0
      plonky2_verifier/reducing_extension_gate.go
  7. +8
    -3
      plonky2_verifier/vars.go

+ 3
- 3
field/field.go

@ -7,14 +7,14 @@ import (
"github.com/consensys/gnark/std/math/emulated"
)
const D = 2
type EmulatedField = emulated.Goldilocks
type F = emulated.Element[EmulatedField]
type QuadraticExtension = [2]F
type QEAlgebra = [2]QuadraticExtension
type QEAlgebra = [D]QuadraticExtension
type Hash = [4]F
const D = 2
var TEST_CURVE = ecc.BN254
func NewFieldElement(x uint64) F {

+ 3
- 1
plonky2_verifier/arithmetic_extension_gate.go

@ -52,7 +52,9 @@ func (g *ArithmeticExtensionGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVa
computed_output = p.qeAPI.AddExtensionAlgebra(computed_output, scaled_mul)
diff := p.qeAPI.SubExtensionAlgebra(output, computed_output)
constraints = append(constraints, diff[0], diff[1])
for j := 0; j < D; j++ {
constraints = append(constraints, diff[j])
}
}
return constraints

+ 18
- 0
plonky2_verifier/gate.go

@ -122,6 +122,24 @@ func GateInstanceFromId(gateId string) gate {
return NewMultiplicationExtensionGate(uint64(numOps))
}
if strings.HasPrefix(gateId, "ReducingExtensionGate") {
// Has the format "ReducingExtensionGate { num_coeffs: 33 }"
regEx := "ReducingExtensionGate { num_coeffs: (?P<numCoeffs>[0-9]+) }"
r, err := regexp.Compile(regEx)
if err != nil {
panic("Invalid ReducingExtensionGate regular expression")
}
matches := getRegExMatches(r, gateId)
numCoeffs, hasNumCoeffs := matches["numCoeffs"]
if !hasNumCoeffs {
panic("Invalid ReducingExtensionGate ID")
}
return NewReducingExtensionGate(uint64(numCoeffs))
}
return nil
//panic(fmt.Sprintf("Unknown gate ID %s", gateId))
}

+ 1
- 0
plonky2_verifier/gate_test.go

@ -769,6 +769,7 @@ func TestGates(t *testing.T) {
{&PoseidonGate{}, poseidonGateExpectedConstraints},
{&ArithmeticExtensionGate{numOps: 10}, arithmeticExtensionGateExpectedConstraints},
{&MultiplicationExtensionGate{numOps: 13}, mulExtensionGateExpectedConstraints},
{&ReducingExtensionGate{numCoeffs: 33}, reducingExtensionGateExpectedConstraints},
}
for _, test := range gateTests {

+ 3
- 1
plonky2_verifier/multiplication_extension_gate.go

@ -44,7 +44,9 @@ func (g *MultiplicationExtensionGate) EvalUnfiltered(p *PlonkChip, vars Evaluati
computed_output := p.qeAPI.ScalarMulExtensionAlgebra(const0, mul)
diff := p.qeAPI.SubExtensionAlgebra(output, computed_output)
constraints = append(constraints, diff[0], diff[1])
for j := 0; j < D; j++ {
constraints = append(constraints, diff[j])
}
}
return constraints

+ 84
- 0
plonky2_verifier/reducing_extension_gate.go

@ -0,0 +1,84 @@
package plonky2_verifier
import (
"fmt"
. "gnark-plonky2-verifier/field"
)
type ReducingExtensionGate struct {
numCoeffs uint64
}
const START_COEFFS = 3 * D
func NewReducingExtensionGate(numCoeffs uint64) *ReducingExtensionGate {
return &ReducingExtensionGate{
numCoeffs: numCoeffs,
}
}
func (g *ReducingExtensionGate) Id() string {
return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
}
func (g *ReducingExtensionGate) wiresOutput() Range {
return Range{0, D}
}
func (g *ReducingExtensionGate) wiresAlpha() Range {
return Range{D, 2 * D}
}
func (g *ReducingExtensionGate) wiresOldAcc() Range {
return Range{2 * D, 3 * D}
}
func (g *ReducingExtensionGate) wiresCoeff(i uint64) Range {
return Range{START_COEFFS + D*i, START_COEFFS + D*(i+1)}
}
func (g *ReducingExtensionGate) startAccs() uint64 {
return START_COEFFS + g.numCoeffs*D
}
func (g *ReducingExtensionGate) 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 *ReducingExtensionGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension {
alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
coeffs := []QEAlgebra{}
for i := uint64(0); i < g.numCoeffs; i++ {
coeffs = append(coeffs, vars.GetLocalExtAlgebra(g.wiresCoeff(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++ {
coeff := coeffs[i]
tmp := p.qeAPI.MulExtensionAlgebra(acc, alpha)
tmp = p.qeAPI.AddExtensionAlgebra(tmp, coeff)
tmp = p.qeAPI.SubExtensionAlgebra(tmp, accs[i])
for j := uint64(0); j < D; j++ {
constraints = append(constraints, tmp[j])
}
acc = accs[i]
}
return constraints
}

+ 8
- 3
plonky2_verifier/vars.go

@ -16,9 +16,14 @@ func (e *EvaluationVars) RemovePrefix(numSelectors uint64) {
func (e *EvaluationVars) GetLocalExtAlgebra(wireRange Range) QEAlgebra {
// For now, only support degree 2
if wireRange.end-wireRange.start != 2 {
panic("Only degree 2 supported")
if wireRange.end-wireRange.start != D {
panic("Range must be of size D")
}
return QEAlgebra{e.localWires[wireRange.start], e.localWires[wireRange.end-1]}
var ret QEAlgebra
for i := wireRange.start; i < wireRange.end; i++ {
ret[i-wireRange.start] = e.localWires[i]
}
return ret
}

Loading…
Cancel
Save