mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 09:01:32 +01:00
reducing extension gate (#12)
This commit is contained in:
@@ -7,14 +7,14 @@ import (
|
|||||||
"github.com/consensys/gnark/std/math/emulated"
|
"github.com/consensys/gnark/std/math/emulated"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const D = 2
|
||||||
|
|
||||||
type EmulatedField = emulated.Goldilocks
|
type EmulatedField = emulated.Goldilocks
|
||||||
type F = emulated.Element[EmulatedField]
|
type F = emulated.Element[EmulatedField]
|
||||||
type QuadraticExtension = [2]F
|
type QuadraticExtension = [2]F
|
||||||
type QEAlgebra = [2]QuadraticExtension
|
type QEAlgebra = [D]QuadraticExtension
|
||||||
type Hash = [4]F
|
type Hash = [4]F
|
||||||
|
|
||||||
const D = 2
|
|
||||||
|
|
||||||
var TEST_CURVE = ecc.BN254
|
var TEST_CURVE = ecc.BN254
|
||||||
|
|
||||||
func NewFieldElement(x uint64) F {
|
func NewFieldElement(x uint64) F {
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ func (g *ArithmeticExtensionGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVa
|
|||||||
computed_output = p.qeAPI.AddExtensionAlgebra(computed_output, scaled_mul)
|
computed_output = p.qeAPI.AddExtensionAlgebra(computed_output, scaled_mul)
|
||||||
|
|
||||||
diff := p.qeAPI.SubExtensionAlgebra(output, computed_output)
|
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
|
return constraints
|
||||||
|
|||||||
@@ -122,6 +122,24 @@ func GateInstanceFromId(gateId string) gate {
|
|||||||
return NewMultiplicationExtensionGate(uint64(numOps))
|
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
|
return nil
|
||||||
//panic(fmt.Sprintf("Unknown gate ID %s", gateId))
|
//panic(fmt.Sprintf("Unknown gate ID %s", gateId))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -769,6 +769,7 @@ func TestGates(t *testing.T) {
|
|||||||
{&PoseidonGate{}, poseidonGateExpectedConstraints},
|
{&PoseidonGate{}, poseidonGateExpectedConstraints},
|
||||||
{&ArithmeticExtensionGate{numOps: 10}, arithmeticExtensionGateExpectedConstraints},
|
{&ArithmeticExtensionGate{numOps: 10}, arithmeticExtensionGateExpectedConstraints},
|
||||||
{&MultiplicationExtensionGate{numOps: 13}, mulExtensionGateExpectedConstraints},
|
{&MultiplicationExtensionGate{numOps: 13}, mulExtensionGateExpectedConstraints},
|
||||||
|
{&ReducingExtensionGate{numCoeffs: 33}, reducingExtensionGateExpectedConstraints},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range gateTests {
|
for _, test := range gateTests {
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ func (g *MultiplicationExtensionGate) EvalUnfiltered(p *PlonkChip, vars Evaluati
|
|||||||
computed_output := p.qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
computed_output := p.qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
||||||
|
|
||||||
diff := p.qeAPI.SubExtensionAlgebra(output, computed_output)
|
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
|
return constraints
|
||||||
|
|||||||
84
plonky2_verifier/reducing_extension_gate.go
Normal file
84
plonky2_verifier/reducing_extension_gate.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -16,9 +16,14 @@ func (e *EvaluationVars) RemovePrefix(numSelectors uint64) {
|
|||||||
|
|
||||||
func (e *EvaluationVars) GetLocalExtAlgebra(wireRange Range) QEAlgebra {
|
func (e *EvaluationVars) GetLocalExtAlgebra(wireRange Range) QEAlgebra {
|
||||||
// For now, only support degree 2
|
// For now, only support degree 2
|
||||||
if wireRange.end-wireRange.start != 2 {
|
if wireRange.end-wireRange.start != D {
|
||||||
panic("Only degree 2 supported")
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user