Skip to content

Commit

Permalink
Prover/Complete Projection Query (#667)
Browse files Browse the repository at this point in the history
* added projection query

* compiler for projection added

* compiler added to arcane

* minor fix added

* fix lint error

* duplicate name fix

* removing cptHolter to math poly

* shifted the no lint command

* added bin file in gitignore

* removed gitignore change

* remove bin file

* code simplification as Alex suggested

* fix in lpp

* distributed projection query added

* more test cases added

* adding slice to accomodate multiple query per module

* param changed to support additive structure

* compiler code added (wip)

* check test added

* incorporate Alex suggestion on PR 585

* Added documentation

* vertical splitting wip

* feat: cumNumOnes added

* feat: vertical split verifier action added

* feat : added filter counting and hash computing functionality

* feat: vertical consistency check and cleanup

---------

Signed-off-by: Arijit Dutta <37040536+arijitdutta67@users.noreply.github.com>
  • Loading branch information
arijitdutta67 authored Feb 21, 2025
1 parent b4093d4 commit f97cd00
Show file tree
Hide file tree
Showing 18 changed files with 921 additions and 381 deletions.
71 changes: 71 additions & 0 deletions prover/protocol/accessors/from_distributedprojection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package accessors

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/linea-monorepo/prover/maths/field"
"github.com/consensys/linea-monorepo/prover/protocol/ifaces"
"github.com/consensys/linea-monorepo/prover/protocol/query"
"github.com/consensys/linea-monorepo/prover/symbolic"
)

const (
DISTRIBUTED_PROJECTION_ACCESSOR = "DISTRIBUTED_PROJECTION_ACCESSOR"
)

// FromDistributedProjectionAccessor implements [ifaces.Accessor] and accesses the result of
// a [query.DISTRIBUTED_PROJECTION].
type FromDistributedProjectionAccessor struct {
// Q is the underlying query whose parameters are accessed by the current
// [ifaces.Accessor].
Q query.DistributedProjection
}

// NewDistributedProjectionAccessor creates an [ifaces.Accessor] returning the opening
// point of a [query.DISTRIBUTED_PROJECTION].
func NewDistributedProjectionAccessor(q query.DistributedProjection) ifaces.Accessor {
return &FromDistributedProjectionAccessor{Q: q}
}

// Name implements [ifaces.Accessor]
func (l *FromDistributedProjectionAccessor) Name() string {
return fmt.Sprintf("%v_%v", DISTRIBUTED_PROJECTION_ACCESSOR, l.Q.ID)
}

// String implements [github.com/consensys/linea-monorepo/prover/symbolic.Metadata]
func (l *FromDistributedProjectionAccessor) String() string {
return l.Name()
}

// GetVal implements [ifaces.Accessor]
func (l *FromDistributedProjectionAccessor) GetVal(run ifaces.Runtime) field.Element {
params := run.GetParams(l.Q.ID).(query.DistributedProjectionParams)
return params.ScaledHorner
}

func (l *FromDistributedProjectionAccessor) GetValCumSumCurr(run ifaces.Runtime) field.Element {
params := run.GetParams(l.Q.ID).(query.DistributedProjectionParams)
return params.HashCumSumOneCurr
}

func (l *FromDistributedProjectionAccessor) GetValCumSumPrev(run ifaces.Runtime) field.Element {
params := run.GetParams(l.Q.ID).(query.DistributedProjectionParams)
return params.HashCumSumOnePrev
}

// GetFrontendVariable implements [ifaces.Accessor]
func (l *FromDistributedProjectionAccessor) GetFrontendVariable(_ frontend.API, circ ifaces.GnarkRuntime) frontend.Variable {
params := circ.GetParams(l.Q.ID).(query.GnarkDistributedProjectionParams)
return params.Sum
}

// AsVariable implements the [ifaces.Accessor] interface
func (l *FromDistributedProjectionAccessor) AsVariable() *symbolic.Expression {
return symbolic.NewVariable(l)
}

// Round implements the [ifaces.Accessor] interface
func (l *FromDistributedProjectionAccessor) Round() int {
return l.Q.Round
}
47 changes: 29 additions & 18 deletions prover/protocol/compiler/distributedprojection/compiler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package distributedprojection

import (
"math/big"

"github.com/consensys/linea-monorepo/prover/maths/field"
"github.com/consensys/linea-monorepo/prover/protocol/coin"
"github.com/consensys/linea-monorepo/prover/protocol/ifaces"
"github.com/consensys/linea-monorepo/prover/protocol/query"
Expand All @@ -20,7 +23,6 @@ func CompileDistributedProjection(comp *wizard.CompiledIOP) {
// This ensures that the distributed projection query is not used again in the
// compilation process. We know that the query was not already ignored at the beginning
// because we are iterating over the unignored keys.
comp.QueriesParams.MarkAsIgnored(qName)
round := comp.QueriesParams.Round(qName)
compile(comp, round, distributedprojection)
}
Expand All @@ -29,29 +31,38 @@ func CompileDistributedProjection(comp *wizard.CompiledIOP) {
func compile(comp *wizard.CompiledIOP, round int, distributedprojection query.DistributedProjection) {
var (
pa = &distribuedProjectionProverAction{
Name: distributedprojection.ID,
FilterA: make([]*symbolic.Expression, len(distributedprojection.Inp)),
FilterB: make([]*symbolic.Expression, len(distributedprojection.Inp)),
ColumnA: make([]*symbolic.Expression, len(distributedprojection.Inp)),
ColumnB: make([]*symbolic.Expression, len(distributedprojection.Inp)),
HornerA: make([]ifaces.Column, len(distributedprojection.Inp)),
HornerB: make([]ifaces.Column, len(distributedprojection.Inp)),
HornerA0: make([]query.LocalOpening, len(distributedprojection.Inp)),
HornerB0: make([]query.LocalOpening, len(distributedprojection.Inp)),
EvalCoin: make([]coin.Info, len(distributedprojection.Inp)),
IsA: make([]bool, len(distributedprojection.Inp)),
IsB: make([]bool, len(distributedprojection.Inp)),
Name: distributedprojection.ID,
Query: distributedprojection,
FilterA: make([]*symbolic.Expression, len(distributedprojection.Inp)),
FilterB: make([]*symbolic.Expression, len(distributedprojection.Inp)),
ColumnA: make([]*symbolic.Expression, len(distributedprojection.Inp)),
ColumnB: make([]*symbolic.Expression, len(distributedprojection.Inp)),
HornerA: make([]ifaces.Column, len(distributedprojection.Inp)),
HornerB: make([]ifaces.Column, len(distributedprojection.Inp)),
HornerA0: make([]query.LocalOpening, len(distributedprojection.Inp)),
HornerB0: make([]query.LocalOpening, len(distributedprojection.Inp)),
EvalCoins: make([]coin.Info, len(distributedprojection.Inp)),
IsA: make([]bool, len(distributedprojection.Inp)),
IsB: make([]bool, len(distributedprojection.Inp)),
}
)
pa.Push(comp, distributedprojection)
pa.RegisterQueries(comp, round, distributedprojection)
comp.RegisterProverAction(round, pa)
comp.RegisterVerifierAction(round, &distributedProjectionVerifierAction{
Name: pa.Name,
HornerA0: pa.HornerA0,
HornerB0: pa.HornerB0,
isA: pa.IsA,
isB: pa.IsB,
Name: pa.Name,
Query: pa.Query,
HornerA0: pa.HornerA0,
HornerB0: pa.HornerB0,
IsA: pa.IsA,
IsB: pa.IsB,
EvalCoins: pa.EvalCoins,
FilterA: pa.FilterA,
FilterB: pa.FilterB,
CumNumOnesPrevSegmentsA: make([]big.Int, len(distributedprojection.Inp)),
CumNumOnesPrevSegmentsB: make([]big.Int, len(distributedprojection.Inp)),
NumOnesCurrSegmentA: make([]field.Element, len(distributedprojection.Inp)),
NumOnesCurrSegmentB: make([]field.Element, len(distributedprojection.Inp)),
})

}
24 changes: 11 additions & 13 deletions prover/protocol/compiler/distributedprojection/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import (

type distribuedProjectionProverAction struct {
Name ifaces.QueryID
Query query.DistributedProjection
FilterA, FilterB []*sym.Expression
ColumnA, ColumnB []*sym.Expression
HornerA, HornerB []ifaces.Column
HornerA0, HornerB0 []query.LocalOpening
EvalCoin []coin.Info
EvalCoins []coin.Info
IsA, IsB []bool
}

Expand All @@ -33,14 +34,14 @@ type distribuedProjectionProverAction struct {
// If IsA is false and IsB is true, it computes the Horner trace for column B only.
// If neither IsA nor IsB is true, it panics with an error message indicating an invalid prover assignment.
func (pa *distribuedProjectionProverAction) Run(run *wizard.ProverRuntime) {
for index := range pa.FilterA {
for index := range pa.Query.Inp {
if pa.IsA[index] && pa.IsB[index] {
var (
colA = column.EvalExprColumn(run, pa.ColumnA[index].Board()).IntoRegVecSaveAlloc()
fA = column.EvalExprColumn(run, pa.FilterA[index].Board()).IntoRegVecSaveAlloc()
colB = column.EvalExprColumn(run, pa.ColumnB[index].Board()).IntoRegVecSaveAlloc()
fB = column.EvalExprColumn(run, pa.FilterB[index].Board()).IntoRegVecSaveAlloc()
x = run.GetRandomCoinField(pa.EvalCoin[index].Name)
x = run.GetRandomCoinField(pa.EvalCoins[index].Name)
hornerA = poly.GetHornerTrace(colA, fA, x)
hornerB = poly.GetHornerTrace(colB, fB, x)
)
Expand All @@ -52,7 +53,7 @@ func (pa *distribuedProjectionProverAction) Run(run *wizard.ProverRuntime) {
var (
colA = column.EvalExprColumn(run, pa.ColumnA[index].Board()).IntoRegVecSaveAlloc()
fA = column.EvalExprColumn(run, pa.FilterA[index].Board()).IntoRegVecSaveAlloc()
x = run.GetRandomCoinField(pa.EvalCoin[index].Name)
x = run.GetRandomCoinField(pa.EvalCoins[index].Name)
hornerA = poly.GetHornerTrace(colA, fA, x)
)
run.AssignColumn(pa.HornerA[index].GetColID(), smartvectors.NewRegular(hornerA))
Expand All @@ -61,7 +62,7 @@ func (pa *distribuedProjectionProverAction) Run(run *wizard.ProverRuntime) {
var (
colB = column.EvalExprColumn(run, pa.ColumnB[index].Board()).IntoRegVecSaveAlloc()
fB = column.EvalExprColumn(run, pa.FilterB[index].Board()).IntoRegVecSaveAlloc()
x = run.GetRandomCoinField(pa.EvalCoin[index].Name)
x = run.GetRandomCoinField(pa.EvalCoins[index].Name)
hornerB = poly.GetHornerTrace(colB, fB, x)
)
run.AssignColumn(pa.HornerB[index].GetColID(), smartvectors.NewRegular(hornerB))
Expand All @@ -88,24 +89,21 @@ func (pa *distribuedProjectionProverAction) Push(comp *wizard.CompiledIOP, distr
pa.FilterB[index] = input.FilterB
pa.ColumnA[index] = input.ColumnA
pa.ColumnB[index] = input.ColumnB
pa.EvalCoin[index] = comp.Coins.Data(input.EvalCoin)
pa.EvalCoins[index] = comp.Coins.Data(input.EvalCoin)
pa.IsA[index] = true
pa.IsB[index] = true

} else if input.IsAInModule && !input.IsBInModule {
pa.FilterA[index] = input.FilterA
pa.ColumnA[index] = input.ColumnA
pa.EvalCoin[index] = comp.Coins.Data(input.EvalCoin)
pa.EvalCoins[index] = comp.Coins.Data(input.EvalCoin)
pa.IsA[index] = true
pa.IsB[index] = false

} else if !input.IsAInModule && input.IsBInModule {
pa.FilterB[index] = input.FilterB
pa.ColumnB[index] = input.ColumnB
pa.EvalCoin[index] = comp.Coins.Data(input.EvalCoin)
pa.EvalCoins[index] = comp.Coins.Data(input.EvalCoin)
pa.IsA[index] = false
pa.IsB[index] = true

} else {
logrus.Errorf("Invalid distributed projection query while pushing prover action entries: %v", distributedprojection.ID)
}
Expand Down Expand Up @@ -200,7 +198,7 @@ func (pa *distribuedProjectionProverAction) registerForCol(
sym.Add(
pa.ColumnA[index],
sym.Mul(
pa.EvalCoin[index],
pa.EvalCoins[index],
column.Shift(pa.HornerA[index], 1),
),
),
Expand Down Expand Up @@ -232,7 +230,7 @@ func (pa *distribuedProjectionProverAction) registerForCol(
),
sym.Mul(
pa.FilterB[index],
sym.Add(pa.ColumnB[index], sym.Mul(pa.EvalCoin[index], column.Shift(pa.HornerB[index], 1))),
sym.Add(pa.ColumnB[index], sym.Mul(pa.EvalCoins[index], column.Shift(pa.HornerB[index], 1))),
),
),
)
Expand Down
Loading

0 comments on commit f97cd00

Please sign in to comment.