diff --git a/prover/backend/execution/prove.go b/prover/backend/execution/prove.go index ee69347a27b..6da2cd4f4ca 100644 --- a/prover/backend/execution/prove.go +++ b/prover/backend/execution/prove.go @@ -190,8 +190,7 @@ func mustProveAndPass( case config.ProverModeEncodeOnly: profiling.ProfileTrace("encode-decode-no-circuit", true, false, func() { - //nolint:gosec // Ignoring weak randomness error - filepath := "/tmp/wizard-assignment/blob-" + strconv.Itoa(rand.Int()) + ".bin" + filepath := "/tmp/wizard-assignment/blob-" + strconv.Itoa(rand.Int()) + ".bin" //nolint:gosec // Ignoring weak randomness error encodeOnlyZkEvm := zkevm.EncodeOnlyZkEvm(traces) numChunks := runtime.GOMAXPROCS(0) diff --git a/prover/go.mod b/prover/go.mod index c14ce840867..da59756474a 100644 --- a/prover/go.mod +++ b/prover/go.mod @@ -18,6 +18,7 @@ require ( github.com/iancoleman/strcase v0.3.0 github.com/icza/bitio v1.1.0 github.com/leanovate/gopter v0.2.11 + github.com/pierrec/lz4/v4 v4.1.21 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.1 github.com/rs/zerolog v1.33.0 @@ -76,7 +77,6 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect diff --git a/prover/maths/common/poly/poly.go b/prover/maths/common/poly/poly.go index 902ddc164e0..dfa685144cd 100644 --- a/prover/maths/common/poly/poly.go +++ b/prover/maths/common/poly/poly.go @@ -122,3 +122,31 @@ func EvaluateLagrangesAnyDomain(domain []field.Element, x field.Element) []field return lagrange } + +// CmptHorner computes a random Horner accumulation of the filtered elements +// starting from the last entry down to the first entry. The final value is +// stored in the last entry of the returned slice. +// Todo: send it to a common utility package +func CmptHorner(c, fC []field.Element, x field.Element) []field.Element { + + var ( + horner = make([]field.Element, len(c)) + prev field.Element + ) + + for i := len(horner) - 1; i >= 0; i-- { + + if !fC[i].IsZero() && !fC[i].IsOne() { + utils.Panic("we expected the filter to be binary") + } + + if fC[i].IsOne() { + prev.Mul(&prev, &x) + prev.Add(&prev, &c[i]) + } + + horner[i] = prev + } + + return horner +} diff --git a/prover/protocol/column/column.go b/prover/protocol/column/column.go index 41fa79bfa1b..bbad41d4812 100644 --- a/prover/protocol/column/column.go +++ b/prover/protocol/column/column.go @@ -189,3 +189,12 @@ func RandLinCombColAssignment(run ifaces.Runtime, coinVal field.Element, hs []if } return witnessCollapsed } + +// maximal round of declaration for a list of commitment +func MaxRound(handles ...ifaces.Column) int { + res := 0 + for _, handle := range handles { + res = utils.Max(res, handle.Round()) + } + return res +} diff --git a/prover/protocol/compiler/arcane.go b/prover/protocol/compiler/arcane.go index b1fbaa82c2c..6a245f726a3 100644 --- a/prover/protocol/compiler/arcane.go +++ b/prover/protocol/compiler/arcane.go @@ -8,6 +8,7 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/compiler/logdata" "github.com/consensys/linea-monorepo/prover/protocol/compiler/lookup" "github.com/consensys/linea-monorepo/prover/protocol/compiler/permutation" + "github.com/consensys/linea-monorepo/prover/protocol/compiler/projection" "github.com/consensys/linea-monorepo/prover/protocol/compiler/specialqueries" "github.com/consensys/linea-monorepo/prover/protocol/compiler/splitter" "github.com/consensys/linea-monorepo/prover/protocol/compiler/splitter/sticker" @@ -29,6 +30,7 @@ func Arcane(minStickSize, targetColSize int, noLog ...bool) func(comp *wizard.Co permutation.CompileGrandProduct(comp) lookup.CompileLogDerivative(comp) innerproduct.Compile(comp) + projection.CompileProjection(comp) if withLog_ { logdata.Log("after-expansion")(comp) } diff --git a/prover/protocol/compiler/mimc/manual.go b/prover/protocol/compiler/mimc/manual.go index 50885feb6cd..7560f8e41ad 100644 --- a/prover/protocol/compiler/mimc/manual.go +++ b/prover/protocol/compiler/mimc/manual.go @@ -25,7 +25,7 @@ func manualCheckMiMCBlock(comp *wizard.CompiledIOP, blocks, oldStates, newStates newStates: newStates, } - round := wizardutils.MaxRound(blocks, oldStates, newStates) + round := column.MaxRound(blocks, oldStates, newStates) // Creates an intermediate column for each round s := blocks diff --git a/prover/protocol/compiler/projection/compiler.go b/prover/protocol/compiler/projection/compiler.go new file mode 100644 index 00000000000..3b77b79f585 --- /dev/null +++ b/prover/protocol/compiler/projection/compiler.go @@ -0,0 +1,158 @@ +package projection + +import ( + "github.com/consensys/linea-monorepo/prover/protocol/coin" + "github.com/consensys/linea-monorepo/prover/protocol/column" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" + "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" + sym "github.com/consensys/linea-monorepo/prover/symbolic" +) + +// CompileProjection compiles [query.Projection] queries +func CompileProjection(comp *wizard.CompiledIOP) { + + for _, qName := range comp.QueriesNoParams.AllUnignoredKeys() { + // Filter out non projection queries + projection, ok := comp.QueriesNoParams.Data(qName).(query.Projection) + if !ok { + continue + } + + // This ensures that the 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.QueriesNoParams.MarkAsIgnored(qName) + round := comp.QueriesNoParams.Round(qName) + compile(comp, round, projection) + } + +} + +func compile(comp *wizard.CompiledIOP, round int, projection query.Projection) { + var ( + compRound = round + sizeA = projection.Inp.FilterA.Size() + sizeB = projection.Inp.FilterB.Size() + numCol = len(projection.Inp.ColumnA) + a, b, af, bf any + queryName = projection.ID + columnsA = projection.Inp.ColumnA + columnsB = projection.Inp.ColumnB + filterA = projection.Inp.FilterA + filterB = projection.Inp.FilterB + ) + + // a and b are storing the columns used to compute the linear combination + // of the columnsA and columnsB. The initial assignment is for the case + // where there is only a single column. If there is more than one column + // then they will store an expression computing a random linear + // combination of the columns. + a, b = projection.Inp.ColumnA[0], projection.Inp.ColumnB[0] + + // af and bf are as a and b but shifted by -1. They are initially + // assigned assuming the case where the number of column is 1 and + // replaced later by a random linear combination if not. They are meant + // to be used in the local constraints to point to the last entry of the + // "a" and "b". + af, bf = column.Shift(projection.Inp.ColumnA[0], -1), column.Shift(projection.Inp.ColumnB[0], -1) + + if numCol > 0 { + compRound++ + alpha := comp.InsertCoin(compRound, coin.Namef("%v_MERGING_COIN", queryName), coin.Field) + a = wizardutils.RandLinCombColSymbolic(alpha, columnsA) + b = wizardutils.RandLinCombColSymbolic(alpha, columnsB) + + afs := make([]ifaces.Column, numCol) + bfs := make([]ifaces.Column, numCol) + + for i := range afs { + afs[i] = column.Shift(columnsA[i], -1) + bfs[i] = column.Shift(columnsB[i], -1) + } + + af = wizardutils.RandLinCombColSymbolic(alpha, afs) + bf = wizardutils.RandLinCombColSymbolic(alpha, bfs) + } + + var ( + aExpr, _, _ = wizardutils.AsExpr(a) + bExpr, _, _ = wizardutils.AsExpr(b) + pa = projectionProverAction{ + Name: queryName, + EvalCoin: comp.InsertCoin(compRound, coin.Namef("%v_EVAL_COIN", queryName), coin.Field), + FilterA: filterA, + FilterB: filterB, + ColA: columnsA, + ColB: columnsB, + ABoard: aExpr.Board(), + BBoard: bExpr.Board(), + HornerA: comp.InsertCommit(compRound, ifaces.ColIDf("%v_HORNER_A", queryName), sizeA), + HornerB: comp.InsertCommit(compRound, ifaces.ColIDf("%v_HORNER_B", queryName), sizeB), + } + ) + + comp.InsertGlobal( + compRound, + ifaces.QueryIDf("%v_HORNER_A_GLOBAL", queryName), + sym.Sub( + pa.HornerA, + sym.Mul( + sym.Sub(1, pa.FilterA), + column.Shift(pa.HornerA, 1), + ), + sym.Mul( + pa.FilterA, + sym.Add( + a, + sym.Mul( + pa.EvalCoin, + column.Shift(pa.HornerA, 1), + ), + ), + ), + ), + ) + + comp.InsertGlobal( + compRound, + ifaces.QueryIDf("%v_HORNER_B_GLOBAL", queryName), + sym.Sub( + pa.HornerB, + sym.Mul( + sym.Sub(1, pa.FilterB), + column.Shift(pa.HornerB, 1), + ), + sym.Mul( + pa.FilterB, + sym.Add(b, sym.Mul(pa.EvalCoin, column.Shift(pa.HornerB, 1))), + ), + ), + ) + + comp.InsertLocal( + compRound, + ifaces.QueryIDf("%v_HORNER_A_LOCAL_END", queryName), + sym.Sub( + column.Shift(pa.HornerA, -1), + sym.Mul(column.Shift(pa.FilterA, -1), af), + ), + ) + + comp.InsertLocal( + compRound, + ifaces.QueryIDf("%v_HORNER_B_LOCAL_END", queryName), + sym.Sub( + column.Shift(pa.HornerB, -1), + sym.Mul(column.Shift(pa.FilterB, -1), bf), + ), + ) + + pa.HornerA0 = comp.InsertLocalOpening(compRound, ifaces.QueryIDf("%v_HORNER_A0", queryName), pa.HornerA) + pa.HornerB0 = comp.InsertLocalOpening(compRound, ifaces.QueryIDf("%v_HORNER_B0", queryName), pa.HornerB) + + comp.RegisterProverAction(compRound, pa) + comp.RegisterVerifierAction(compRound, &projectionVerifierAction{HornerA0: pa.HornerA0, HornerB0: pa.HornerB0, Name: queryName}) + +} diff --git a/prover/protocol/dedicated/projection/projection_test.go b/prover/protocol/compiler/projection/compiler_test.go similarity index 82% rename from prover/protocol/dedicated/projection/projection_test.go rename to prover/protocol/compiler/projection/compiler_test.go index e8780096b62..20c9e8de396 100644 --- a/prover/protocol/dedicated/projection/projection_test.go +++ b/prover/protocol/compiler/projection/compiler_test.go @@ -1,4 +1,4 @@ -package projection +package projection_test import ( "testing" @@ -6,7 +6,9 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/compiler/dummy" + "github.com/consensys/linea-monorepo/prover/protocol/compiler/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/stretchr/testify/assert" ) @@ -25,8 +27,7 @@ func makeTestCaseProjection() ( flagB = comp.InsertCommit(round, ifaces.ColID("FliterB"), flagSizeB) columnA = comp.InsertCommit(round, ifaces.ColID("ColumnA"), flagSizeA) columnB = comp.InsertCommit(round, ifaces.ColID("ColumnB"), flagSizeB) - InsertProjection(comp, ifaces.QueryIDf("OrderPreserving"), - []ifaces.Column{columnA}, []ifaces.Column{columnB}, flagA, flagB) + comp.InsertProjection("Projection_Compilation_Test", query.ProjectionInput{ColumnA: []ifaces.Column{columnA}, ColumnB: []ifaces.Column{columnB}, FilterA: flagA, FilterB: flagB}) } prover = func(run *wizard.ProverRuntime) { @@ -54,7 +55,7 @@ func makeTestCaseProjection() ( func TestProjectionQuery(t *testing.T) { define, prover := makeTestCaseProjection() - comp := wizard.Compile(define, dummy.Compile) + comp := wizard.Compile(define, projection.CompileProjection, dummy.CompileAtProverLvl) proof := wizard.Prove(comp, prover) assert.NoErrorf(t, wizard.Verify(comp, proof), "invalid proof") diff --git a/prover/protocol/compiler/projection/prover.go b/prover/protocol/compiler/projection/prover.go new file mode 100644 index 00000000000..7726a0d3ec4 --- /dev/null +++ b/prover/protocol/compiler/projection/prover.go @@ -0,0 +1,129 @@ +package projection + +import ( + "fmt" + "strings" + + "github.com/consensys/linea-monorepo/prover/maths/common/poly" + "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" + "github.com/consensys/linea-monorepo/prover/maths/field" + "github.com/consensys/linea-monorepo/prover/protocol/coin" + "github.com/consensys/linea-monorepo/prover/protocol/column" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" + sym "github.com/consensys/linea-monorepo/prover/symbolic" + "github.com/sirupsen/logrus" +) + +// projectionProverAction is a compilation artefact generated during the +// execution of the [InsertProjection] and which implements the +// [wizard.ProverAction]. It is meant to compute to assign the "Horner" columns +// and their respective local opening queries. +type projectionProverAction struct { + Name ifaces.QueryID + FilterA, FilterB ifaces.Column + ColA, ColB []ifaces.Column + ABoard, BBoard sym.ExpressionBoard + EvalCoin coin.Info + HornerA, HornerB ifaces.Column + HornerA0, HornerB0 query.LocalOpening +} + +// Run implements the [wizard.ProverAction] interface. +func (pa projectionProverAction) Run(run *wizard.ProverRuntime) { + + var ( + a = column.EvalExprColumn(run, pa.ABoard).IntoRegVecSaveAlloc() + b = column.EvalExprColumn(run, pa.BBoard).IntoRegVecSaveAlloc() + fA = pa.FilterA.GetColAssignment(run).IntoRegVecSaveAlloc() + fB = pa.FilterB.GetColAssignment(run).IntoRegVecSaveAlloc() + x = run.GetRandomCoinField(pa.EvalCoin.Name) + hornerA = poly.CmptHorner(a, fA, x) + hornerB = poly.CmptHorner(b, fB, x) + ) + + run.AssignColumn(pa.HornerA.GetColID(), smartvectors.NewRegular(hornerA)) + run.AssignColumn(pa.HornerB.GetColID(), smartvectors.NewRegular(hornerB)) + run.AssignLocalPoint(pa.HornerA0.ID, hornerA[0]) + run.AssignLocalPoint(pa.HornerB0.ID, hornerB[0]) + + if hornerA[0] != hornerB[0] { + + var ( + colA = make([][]field.Element, len(pa.ColA)) + colB = make([][]field.Element, len(pa.ColB)) + cntA = 0 + cntB = 0 + rowsA = [][]string{} + rowsB = [][]string{} + ) + + for c := range pa.ColA { + colA[c] = pa.ColA[c].GetColAssignment(run).IntoRegVecSaveAlloc() + colB[c] = pa.ColB[c].GetColAssignment(run).IntoRegVecSaveAlloc() + } + + for i := range fA { + + if fA[i].IsZero() { + continue + } + + row := make([]string, len(pa.ColA)) + + for c := range pa.ColA { + fString := colA[c][i].Text(16) + if colA[c][i].IsUint64() && colA[c][i].Uint64() < 1000000 { + fString = colA[c][i].String() + } + row[c] = fmt.Sprintf("%v=%v", pa.ColA[c].GetColID(), fString) + } + + rowsA = append(rowsA, row) + cntA++ + } + + for i := range fB { + + if fB[i].IsZero() { + continue + } + + row := make([]string, len(pa.ColB)) + + for c := range pa.ColB { + fString := colB[c][i].Text(16) + if colB[c][i].IsUint64() && colB[c][i].Uint64() < 1000000 { + fString = colB[c][i].String() + } + row[c] = fmt.Sprintf("%v=%v", pa.ColB[c].GetColID(), fString) + } + + rowsB = append(rowsB, row) + cntB++ + } + + larger := max(len(rowsA), len(rowsB)) + + for i := 0; i < larger; i++ { + + var ( + fa = "* * * * * *" + fb = "* * * * * *" + ) + + if i < len(rowsA) { + fa = strings.Join(rowsA[i], " ") + } + + if i < len(rowsB) { + fb = strings.Join(rowsB[i], " ") + } + + fmt.Printf("row=%v %v %v\n", i, fa, fb) + } + + logrus.Errorf("projection query %v failed", pa.Name) + } +} diff --git a/prover/protocol/compiler/projection/verifier.go b/prover/protocol/compiler/projection/verifier.go new file mode 100644 index 00000000000..59b4f4d0d5d --- /dev/null +++ b/prover/protocol/compiler/projection/verifier.go @@ -0,0 +1,54 @@ +package projection + +import ( + "fmt" + + "github.com/consensys/gnark/frontend" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" +) + +// projectionVerifierAction is a compilation artifact generated during the +// execution of the [InsertProjection] and which implements the [wizard.VerifierAction] +// interface. It is meant to perform the verifier checks that the first values +// of the two Horner are equals. +type projectionVerifierAction struct { + Name ifaces.QueryID + HornerA0, HornerB0 query.LocalOpening + skipped bool +} + +// Run implements the [wizard.VerifierAction] interface. +func (va *projectionVerifierAction) Run(run *wizard.VerifierRuntime) error { + + var ( + a = run.GetLocalPointEvalParams(va.HornerA0.ID).Y + b = run.GetLocalPointEvalParams(va.HornerB0.ID).Y + ) + + if a != b { + return fmt.Errorf("the horner check of the projection query `%v` did not pass", va.Name) + } + + return nil +} + +// RunGnark implements the [wizard.VerifierAction] interface. +func (va *projectionVerifierAction) RunGnark(api frontend.API, run *wizard.WizardVerifierCircuit) { + + var ( + a = run.GetLocalPointEvalParams(va.HornerA0.ID).Y + b = run.GetLocalPointEvalParams(va.HornerB0.ID).Y + ) + + api.AssertIsEqual(a, b) +} + +func (va *projectionVerifierAction) Skip() { + va.skipped = true +} + +func (va *projectionVerifierAction) IsSkipped() bool { + return va.skipped +} diff --git a/prover/protocol/dedicated/byte32cmp/byte32cmp.go b/prover/protocol/dedicated/byte32cmp/byte32cmp.go index 0a51d704391..dc161ae93cd 100644 --- a/prover/protocol/dedicated/byte32cmp/byte32cmp.go +++ b/prover/protocol/dedicated/byte32cmp/byte32cmp.go @@ -1,9 +1,9 @@ package byte32cmp import ( + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/symbolic" ) @@ -20,7 +20,7 @@ func Bytes32Cmp( activeRow *symbolic.Expression, ) { bcp := BytesCmpCtx{} - round := wizardutils.MaxRound(columnA, columnB) + round := column.MaxRound(columnA, columnB) bcp.round = round bcp.columnA = columnA bcp.columnB = columnB diff --git a/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go b/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go index 35d96e11db0..5b7450a49cd 100644 --- a/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go +++ b/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go @@ -10,7 +10,6 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/dedicated" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" "github.com/consensys/linea-monorepo/prover/utils/parallel" @@ -96,8 +95,8 @@ func CmpMultiLimbs(comp *wizard.CompiledIOP, a, b LimbColumns) (isGreater, isEqu var ( isBigEndian = a.IsBigEndian - roundA = wizardutils.MaxRound(a.Limbs...) - round = max(roundA, wizardutils.MaxRound(b.Limbs...)) + roundA = column.MaxRound(a.Limbs...) + round = max(roundA, column.MaxRound(b.Limbs...)) numLimbs = len(a.Limbs) numBitsPerLimbs = a.LimbBitSize ctx = &multiLimbCmp{ diff --git a/prover/protocol/dedicated/merkle/merkle.go b/prover/protocol/dedicated/merkle/merkle.go index ff794e92c5a..76f495aac86 100644 --- a/prover/protocol/dedicated/merkle/merkle.go +++ b/prover/protocol/dedicated/merkle/merkle.go @@ -4,9 +4,9 @@ import ( "github.com/consensys/linea-monorepo/prover/crypto/state-management/smt" "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/utils" ) @@ -63,7 +63,7 @@ func merkleProofCheck( useNextProof bool, ) { - round := wizardutils.MaxRound(proofs, roots, leaves, pos) + round := column.MaxRound(proofs, roots, leaves, pos) // define the compute module cm := ComputeMod{} cm.Cols.Proof = proofs diff --git a/prover/protocol/dedicated/plonk/alignment.go b/prover/protocol/dedicated/plonk/alignment.go index 59ef0deae8e..2ac362c49c6 100644 --- a/prover/protocol/dedicated/plonk/alignment.go +++ b/prover/protocol/dedicated/plonk/alignment.go @@ -10,7 +10,6 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" @@ -273,7 +272,7 @@ func (a *Alignment) csIsActive(comp *wizard.CompiledIOP) { // csProjection ensures the data in the [Alignment.Data] column is the same as // the data provided by the [Alignment.CircuitInput]. func (a *Alignment) csProjection(comp *wizard.CompiledIOP) { - projection.InsertProjection(comp, ifaces.QueryIDf("%v_PROJECTION", a.Name), []ifaces.Column{a.DataToCircuit}, []ifaces.Column{a.CircuitInput}, a.DataToCircuitMask, a.ActualCircuitInputMask) + comp.InsertProjection(ifaces.QueryIDf("%v_PROJECTION", a.Name), query.ProjectionInput{ColumnA: []ifaces.Column{a.DataToCircuit}, ColumnB: []ifaces.Column{a.CircuitInput}, FilterA: a.DataToCircuitMask, FilterB: a.ActualCircuitInputMask}) } // csProjectionSelector constraints that the projection selection diff --git a/prover/protocol/dedicated/projection/projection.go b/prover/protocol/dedicated/projection/projection.go deleted file mode 100644 index 4edd80fa377..00000000000 --- a/prover/protocol/dedicated/projection/projection.go +++ /dev/null @@ -1,376 +0,0 @@ -/* -Package projection implements the utilities for the projection query. - -A projection query between sets (columnsA,filterA) and (columnsB,filterB) asserts -whether the columnsA filtered by filterA is the same as columnsB filtered by -filterB, preserving the order. - -Example: - -FilterA = (1,0,0,1,1), ColumnA := (aO,a1,a2,a3,a4) - -FiletrB := (0,0,1,0,0,0,0,0,1,1), ColumnB :=(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) - -Thus we have, - -ColumnA filtered by FilterA = (a0,a3,a4) - -ColumnB filtered by FilterB = (b2,b8,b9) - -The projection query checks if a0 = b2, a3 = b8, a4 = b9 - -Note that the query imposes that: - - the number of 1 in the filters are equal - - the order of filtered elements is preserved -*/ -package projection - -import ( - "fmt" - "strings" - - "github.com/consensys/gnark/frontend" - "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" - "github.com/consensys/linea-monorepo/prover/maths/field" - "github.com/consensys/linea-monorepo/prover/protocol/coin" - "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/ifaces" - "github.com/consensys/linea-monorepo/prover/protocol/query" - "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" - sym "github.com/consensys/linea-monorepo/prover/symbolic" - "github.com/consensys/linea-monorepo/prover/utils" - "github.com/sirupsen/logrus" -) - -// projectionProverAction is a compilation artefact generated during the -// execution of the [InsertProjection] and which implements the -// [wizard.ProverAction]. It is meant to compute to assign the "Horner" columns -// and their respective local opening queries. -type projectionProverAction struct { - Name ifaces.QueryID - FilterA, FilterB ifaces.Column - ColA, ColB []ifaces.Column - ABoard, BBoard sym.ExpressionBoard - EvalCoin coin.Info - HornerA, HornerB ifaces.Column - HornerA0, HornerB0 query.LocalOpening -} - -// projectionVerifierAction is a compilation artifact generated during the -// execution of the [InsertProjection] and which implements the [wizard.VerifierAction] -// interface. It is meant to perform the verifier checks that the first values -// of the two Horner are equals. -type projectionVerifierAction struct { - Name ifaces.QueryID - HornerA0, HornerB0 query.LocalOpening - skipped bool -} - -// InsertProjection applies a projection query between sets (columnsA, filterA) -// and (columnsB,filterB). -// -// Note: The filters are supposed to be binary. -// These binary constraints are not handled here and should have been imposed -// before calling the function. -func InsertProjection( - comp *wizard.CompiledIOP, - queryName ifaces.QueryID, - columnsA, columnsB []ifaces.Column, - filterA, filterB ifaces.Column, -) { - - var ( - sizeA = filterA.Size() - sizeB = filterB.Size() - numCol = len(columnsA) - round = max( - wizardutils.MaxRound(columnsA...), - wizardutils.MaxRound(columnsB...), - filterA.Round(), - filterB.Round(), - ) - - // a and b are storing the columns used to compute the linear combination - // of the columnsA and columnsB. The initial assignment is for the case - // where there is only a single column. If there is more than one column - // then they will store an expression computing a random linear - // combination of the columns. - a, b any = columnsA[0], columnsB[0] - - // af and bf are as a and b but shifted by -1. They are initially - // assigned assuming the case where the number of column is 1 and - // replaced later by a random linear combination if not. They are meant - // to be used in the local constraints to point to the last entry of the - // "a" and "b". - af, bf any = column.Shift(columnsA[0], -1), column.Shift(columnsB[0], -1) - ) - - if len(columnsB) != numCol { - utils.Panic("A and B must have the same number of columns") - } - - if ifaces.AssertSameLength(columnsA...) != sizeA { - utils.Panic("A and its filter do not have the same column sizes") - } - - if ifaces.AssertSameLength(columnsB...) != sizeB { - utils.Panic("B and its filter do not have the same column sizes") - } - - if numCol > 0 { - round++ - alpha := comp.InsertCoin(round, coin.Namef("%v_MERGING_COIN", queryName), coin.Field) - a = wizardutils.RandLinCombColSymbolic(alpha, columnsA) - b = wizardutils.RandLinCombColSymbolic(alpha, columnsB) - - afs := make([]ifaces.Column, numCol) - bfs := make([]ifaces.Column, numCol) - - for i := range afs { - afs[i] = column.Shift(columnsA[i], -1) - bfs[i] = column.Shift(columnsB[i], -1) - } - - af = wizardutils.RandLinCombColSymbolic(alpha, afs) - bf = wizardutils.RandLinCombColSymbolic(alpha, bfs) - } - - var ( - aExpr, _, _ = wizardutils.AsExpr(a) - bExpr, _, _ = wizardutils.AsExpr(b) - pa = projectionProverAction{ - Name: queryName, - EvalCoin: comp.InsertCoin(round, coin.Namef("%v_EVAL_COIN", queryName), coin.Field), - FilterA: filterA, - FilterB: filterB, - ColA: columnsA, - ColB: columnsB, - ABoard: aExpr.Board(), - BBoard: bExpr.Board(), - HornerA: comp.InsertCommit(round, ifaces.ColIDf("%v_HORNER_A", queryName), sizeA), - HornerB: comp.InsertCommit(round, ifaces.ColIDf("%v_HORNER_B", queryName), sizeB), - } - ) - - comp.InsertGlobal( - 0, - ifaces.QueryIDf("%v_HORNER_A_GLOBAL", queryName), - sym.Sub( - pa.HornerA, - sym.Mul( - sym.Sub(1, pa.FilterA), - column.Shift(pa.HornerA, 1), - ), - sym.Mul( - pa.FilterA, - sym.Add( - a, - sym.Mul( - pa.EvalCoin, - column.Shift(pa.HornerA, 1), - ), - ), - ), - ), - ) - - comp.InsertGlobal( - 0, - ifaces.QueryIDf("%v_HORNER_B_GLOBAL", queryName), - sym.Sub( - pa.HornerB, - sym.Mul( - sym.Sub(1, pa.FilterB), - column.Shift(pa.HornerB, 1), - ), - sym.Mul( - pa.FilterB, - sym.Add(b, sym.Mul(pa.EvalCoin, column.Shift(pa.HornerB, 1))), - ), - ), - ) - - comp.InsertLocal( - 0, - ifaces.QueryIDf("%v_HORNER_A_LOCAL_END", queryName), - sym.Sub( - column.Shift(pa.HornerA, -1), - sym.Mul(column.Shift(pa.FilterA, -1), af), - ), - ) - - comp.InsertLocal( - 0, - ifaces.QueryIDf("%v_HORNER_B_LOCAL_END", queryName), - sym.Sub( - column.Shift(pa.HornerB, -1), - sym.Mul(column.Shift(pa.FilterB, -1), bf), - ), - ) - - pa.HornerA0 = comp.InsertLocalOpening(round, ifaces.QueryIDf("%v_HORNER_A0", queryName), pa.HornerA) - pa.HornerB0 = comp.InsertLocalOpening(round, ifaces.QueryIDf("%v_HORNER_B0", queryName), pa.HornerB) - - comp.RegisterProverAction(round, pa) - comp.RegisterVerifierAction(round, &projectionVerifierAction{HornerA0: pa.HornerA0, HornerB0: pa.HornerB0, Name: queryName}) -} - -// Run implements the [wizard.ProverAction] interface. -func (pa projectionProverAction) Run(run *wizard.ProverRuntime) { - - var ( - a = column.EvalExprColumn(run, pa.ABoard).IntoRegVecSaveAlloc() - b = column.EvalExprColumn(run, pa.BBoard).IntoRegVecSaveAlloc() - fA = pa.FilterA.GetColAssignment(run).IntoRegVecSaveAlloc() - fB = pa.FilterB.GetColAssignment(run).IntoRegVecSaveAlloc() - x = run.GetRandomCoinField(pa.EvalCoin.Name) - hornerA = cmptHorner(a, fA, x) - hornerB = cmptHorner(b, fB, x) - ) - - run.AssignColumn(pa.HornerA.GetColID(), smartvectors.NewRegular(hornerA)) - run.AssignColumn(pa.HornerB.GetColID(), smartvectors.NewRegular(hornerB)) - run.AssignLocalPoint(pa.HornerA0.ID, hornerA[0]) - run.AssignLocalPoint(pa.HornerB0.ID, hornerB[0]) - - if hornerA[0] != hornerB[0] { - - var ( - colA = make([][]field.Element, len(pa.ColA)) - colB = make([][]field.Element, len(pa.ColB)) - cntA = 0 - cntB = 0 - rowsA = [][]string{} - rowsB = [][]string{} - ) - - for c := range pa.ColA { - colA[c] = pa.ColA[c].GetColAssignment(run).IntoRegVecSaveAlloc() - colB[c] = pa.ColB[c].GetColAssignment(run).IntoRegVecSaveAlloc() - } - - for i := range fA { - - if fA[i].IsZero() { - continue - } - - row := make([]string, len(pa.ColA)) - - for c := range pa.ColA { - fString := colA[c][i].Text(16) - if colA[c][i].IsUint64() && colA[c][i].Uint64() < 1000000 { - fString = colA[c][i].String() - } - row[c] = fmt.Sprintf("%v=%v", pa.ColA[c].GetColID(), fString) - } - - rowsA = append(rowsA, row) - cntA++ - } - - for i := range fB { - - if fB[i].IsZero() { - continue - } - - row := make([]string, len(pa.ColB)) - - for c := range pa.ColB { - fString := colB[c][i].Text(16) - if colB[c][i].IsUint64() && colB[c][i].Uint64() < 1000000 { - fString = colB[c][i].String() - } - row[c] = fmt.Sprintf("%v=%v", pa.ColB[c].GetColID(), fString) - } - - rowsB = append(rowsB, row) - cntB++ - } - - larger := max(len(rowsA), len(rowsB)) - - for i := 0; i < larger; i++ { - - var ( - fa = "* * * * * *" - fb = "* * * * * *" - ) - - if i < len(rowsA) { - fa = strings.Join(rowsA[i], " ") - } - - if i < len(rowsB) { - fb = strings.Join(rowsB[i], " ") - } - - fmt.Printf("row=%v %v %v\n", i, fa, fb) - } - - logrus.Errorf("projection query %v failed", pa.Name) - } -} - -// Run implements the [wizard.VerifierAction] interface. -func (va *projectionVerifierAction) Run(run *wizard.VerifierRuntime) error { - - var ( - a = run.GetLocalPointEvalParams(va.HornerA0.ID).Y - b = run.GetLocalPointEvalParams(va.HornerB0.ID).Y - ) - - if a != b { - return fmt.Errorf("the horner check of the projection query `%v` did not pass", va.Name) - } - - return nil -} - -// RunGnark implements the [wizard.VerifierAction] interface. -func (va *projectionVerifierAction) RunGnark(api frontend.API, run *wizard.WizardVerifierCircuit) { - - var ( - a = run.GetLocalPointEvalParams(va.HornerA0.ID).Y - b = run.GetLocalPointEvalParams(va.HornerB0.ID).Y - ) - - api.AssertIsEqual(a, b) -} - -func (va *projectionVerifierAction) Skip() { - va.skipped = true -} - -func (va *projectionVerifierAction) IsSkipped() bool { - return va.skipped -} - -// cmptHorner computes a random Horner accumulation of the filtered elements -// starting from the last entry down to the first entry. The final value is -// stored in the last entry of the returned slice. -func cmptHorner(c, fC []field.Element, x field.Element) []field.Element { - - var ( - horner = make([]field.Element, len(c)) - prev field.Element - ) - - for i := len(horner) - 1; i >= 0; i-- { - - if !fC[i].IsZero() && !fC[i].IsOne() { - utils.Panic("we expected the filter to be binary") - } - - if fC[i].IsOne() { - prev.Mul(&prev, &x) - prev.Add(&prev, &c[i]) - } - - horner[i] = prev - } - - return horner -} diff --git a/prover/protocol/distributed/lpp/lpp.go b/prover/protocol/distributed/lpp/lpp.go index ed9fbf14236..55ebf510ca2 100644 --- a/prover/protocol/distributed/lpp/lpp.go +++ b/prover/protocol/distributed/lpp/lpp.go @@ -148,9 +148,9 @@ func getLPPColumns(c *wizard.CompiledIOP) []ifaces.Column { lppColumns = append(lppColumns, v.B[i]...) } case query.Projection: - lppColumns = append(lppColumns, v.ColumnsA...) - lppColumns = append(lppColumns, v.ColumnsB...) - lppColumns = append(lppColumns, v.FilterA, v.FilterB) + lppColumns = append(lppColumns, v.Inp.ColumnA...) + lppColumns = append(lppColumns, v.Inp.ColumnB...) + lppColumns = append(lppColumns, v.Inp.FilterA, v.Inp.FilterB) default: //do noting diff --git a/prover/protocol/query/projection.go b/prover/protocol/query/projection.go index 3197089197c..45f88eb0f80 100644 --- a/prover/protocol/query/projection.go +++ b/prover/protocol/query/projection.go @@ -1,35 +1,103 @@ package query import ( + "fmt" + "github.com/consensys/gnark/frontend" + "github.com/consensys/linea-monorepo/prover/maths/common/poly" + "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/utils" ) +type ProjectionInput struct { + ColumnA, ColumnB []ifaces.Column + FilterA, FilterB ifaces.Column +} type Projection struct { - ID ifaces.QueryID - ColumnsA, ColumnsB []ifaces.Column - FilterA, FilterB ifaces.Column + Round int + ID ifaces.QueryID + Inp ProjectionInput } -// NewInclusion constructs an inclusion. Will panic if it is mal-formed +// NewProjection constructs a projection. Will panic if it is mal-formed func NewProjection( + round int, id ifaces.QueryID, - columnsA, columnsB []ifaces.Column, - filterA, filterB ifaces.Column, + inp ProjectionInput, ) Projection { + var ( + sizeA = inp.FilterA.Size() + sizeB = inp.FilterB.Size() + numCol = len(inp.ColumnA) + ) + if len(inp.ColumnB) != numCol { + utils.Panic("A and B must have the same number of columns") + } + + if ifaces.AssertSameLength(inp.ColumnA...) != sizeA { + utils.Panic("A and its filter do not have the same column sizes") + } - return Projection{ColumnsA: columnsA, ColumnsB: columnsB, ID: id, FilterA: filterA, FilterB: filterB} + if ifaces.AssertSameLength(inp.ColumnB...) != sizeB { + utils.Panic("B and its filter do not have the same column sizes") + } + return Projection{Round: round, ID: id, Inp: inp} } // Name implements the [ifaces.Query] interface -func (r Projection) Name() ifaces.QueryID { - return r.ID +func (p Projection) Name() ifaces.QueryID { + return p.ID } // Check implements the [ifaces.Query] interface -func (r Projection) Check(run ifaces.Runtime) error { +func (p Projection) Check(run ifaces.Runtime) error { + var ( + numCols = len(p.Inp.ColumnA) + sizeA = p.Inp.ColumnA[0].Size() + sizeB = p.Inp.ColumnB[0].Size() + linCombRand, evalRand field.Element + a = make([]ifaces.ColAssignment, numCols) + b = make([]ifaces.ColAssignment, numCols) + fA = p.Inp.FilterA.GetColAssignment(run).IntoRegVecSaveAlloc() + fB = p.Inp.FilterB.GetColAssignment(run).IntoRegVecSaveAlloc() + aLinComb = make([]field.Element, sizeA) + bLinComb = make([]field.Element, sizeB) + ) + _, errAlpha := linCombRand.SetRandom() + _, errBeta := evalRand.SetRandom() + if errAlpha != nil { + // Cannot happen unless the entropy was exhausted + panic(errAlpha) + } + if errBeta != nil { + // Cannot happen unless the entropy was exhausted + panic(errBeta) + } + // Populate a + for colIndex, pol := range p.Inp.ColumnA { + a[colIndex] = pol.GetColAssignment(run) + } + // Populate b + for colIndex, pol := range p.Inp.ColumnB { + b[colIndex] = pol.GetColAssignment(run) + } + // Compute the linear combination of the columns of a and b + for row := 0; row < sizeA; row++ { + aLinComb[row] = rowLinComb(linCombRand, row, a) + } + for row := 0; row < sizeB; row++ { + bLinComb[row] = rowLinComb(linCombRand, row, b) + } + var ( + hornerA = poly.CmptHorner(aLinComb, fA, evalRand) + hornerB = poly.CmptHorner(bLinComb, fB, evalRand) + ) + if hornerA[0] != hornerB[0] { + return fmt.Errorf("the projection query %v check is not satisfied", p.ID) + } - panic("unimplemented") + return nil } // GnarkCheck implements the [ifaces.Query] interface. It will panic in this diff --git a/prover/protocol/query/projection_test.go b/prover/protocol/query/projection_test.go new file mode 100644 index 00000000000..bd1a307fad5 --- /dev/null +++ b/prover/protocol/query/projection_test.go @@ -0,0 +1,62 @@ +package query_test + +import ( + "testing" + + "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" + "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/protocol/wizard" +) + +func TestProjection(t *testing.T) { + var ( + runS *wizard.ProverRuntime + P ifaces.Query + round = 0 + flagSizeA = 512 + flagSizeB = 256 + flagA, flagB, columnA, columnB ifaces.Column + ) + + define := func(build *wizard.Builder) { + comp := build.CompiledIOP + flagA = comp.InsertCommit(round, ifaces.ColID("FilterA"), flagSizeA) + flagB = comp.InsertCommit(round, ifaces.ColID("FliterB"), flagSizeB) + columnA = comp.InsertCommit(round, ifaces.ColID("ColumnA"), flagSizeA) + columnB = comp.InsertCommit(round, ifaces.ColID("ColumnB"), flagSizeB) + P = comp.InsertProjection("ProjectionTest", + query.ProjectionInput{ColumnA: []ifaces.Column{columnA}, ColumnB: []ifaces.Column{columnB}, FilterA: flagA, FilterB: flagB}) + + } + prover := func(run *wizard.ProverRuntime) { + runS = run + // assign filters and columns + flagAWit := make([]field.Element, flagSizeA) + columnAWit := make([]field.Element, flagSizeA) + flagBWit := make([]field.Element, flagSizeB) + columnBWit := make([]field.Element, flagSizeB) + for i := 0; i < 10; i++ { + flagAWit[i] = field.One() + columnAWit[i] = field.NewElement(uint64(i)) + } + for i := flagSizeB - 10; i < flagSizeB; i++ { + flagBWit[i] = field.One() + columnBWit[i] = field.NewElement(uint64(i - (flagSizeB - 10))) + } + run.AssignColumn(flagA.GetColID(), smartvectors.RightZeroPadded(flagAWit, flagSizeA)) + run.AssignColumn(flagB.GetColID(), smartvectors.RightZeroPadded(flagBWit, flagSizeB)) + run.AssignColumn(columnB.GetColID(), smartvectors.RightZeroPadded(columnBWit, flagSizeB)) + run.AssignColumn(columnA.GetColID(), smartvectors.RightZeroPadded(columnAWit, flagSizeA)) + } + var ( + comp_ = wizard.Compile(define) + _ = wizard.Prove(comp_, prover) + errG = P.Check(runS) + ) + + if errG != nil { + t.Fatalf("error verifying the projection query: %v", errG.Error()) + } +} diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index af3c80f74fe..b24f861bd24 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -653,3 +653,41 @@ func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, in map[in c.QueriesParams.AddToRound(round, q.Name(), q) return q } + +/* +A projection query between sets (columnsA,filterA) and (columnsB,filterB) asserts +whether the columnsA filtered by filterA is the same as columnsB filtered by +filterB, preserving the order. + +Example: + +FilterA = (1,0,0,1,1), ColumnA := (aO,a1,a2,a3,a4) + +FiletrB := (0,0,1,0,0,0,0,0,1,1), ColumnB :=(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) + +Thus we have, + +ColumnA filtered by FilterA = (a0,a3,a4) + +ColumnB filtered by FilterB = (b2,b8,b9) + +The projection query checks if a0 = b2, a3 = b8, a4 = b9 + +Note that the query imposes that: + - the number of 1 in the filters are equal + - the order of filtered elements is preserved +*/ +func (c *CompiledIOP) InsertProjection(id ifaces.QueryID, in query.ProjectionInput) query.Projection { + var ( + round = max( + column.MaxRound(in.ColumnA...), + column.MaxRound(in.ColumnB...), + in.FilterA.Round(), + in.FilterB.Round()) + ) + c.assertConsistentRound(round) + q := query.NewProjection(round, id, in) + // Finally registers the query + c.QueriesNoParams.AddToRound(round, q.Name(), q) + return q +} diff --git a/prover/protocol/wizardutils/utils.go b/prover/protocol/wizardutils/utils.go index 764092a1f3e..9694c6f63d0 100644 --- a/prover/protocol/wizardutils/utils.go +++ b/prover/protocol/wizardutils/utils.go @@ -42,15 +42,6 @@ func LastRoundToEval(expr *symbolic.Expression) int { return maxRound } -// maximal round of declaration for a list of commitment -func MaxRound(handles ...ifaces.Column) int { - res := 0 - for _, handle := range handles { - res = utils.Max(res, handle.Round()) - } - return res -} - // DeriveName is used to construct either [ifaces.QueryID] or [ifaces.ColID] or // [coin.Name]. The function will format [ifaces.Query], [ifaces.Column] or // [coin.Info] using their names or IDs, in the other cases it will use the diff --git a/prover/zkevm/prover/common/hashing.go b/prover/zkevm/prover/common/hashing.go index a82cdbb3261..14584476fee 100644 --- a/prover/zkevm/prover/common/hashing.go +++ b/prover/zkevm/prover/common/hashing.go @@ -4,10 +4,10 @@ import ( "github.com/consensys/linea-monorepo/prover/crypto/mimc" "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/column/verifiercol" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/utils" "github.com/consensys/linea-monorepo/prover/utils/parallel" ) @@ -34,7 +34,7 @@ func HashOf(comp *wizard.CompiledIOP, inputCols []ifaces.Column) (ifaces.Column, InputCols: inputCols, IntermediateHashes: make([]ifaces.Column, len(inputCols)), } - round = wizardutils.MaxRound(inputCols...) + round = column.MaxRound(inputCols...) ctxID = len(comp.ListCommitments()) numRows = ifaces.AssertSameLength(inputCols...) prevState = verifiercol.NewConstantCol(field.Zero(), numRows) diff --git a/prover/zkevm/prover/ecdsa/adress.go b/prover/zkevm/prover/ecdsa/adress.go index ef658158c15..b2d4a11d50f 100644 --- a/prover/zkevm/prover/ecdsa/adress.go +++ b/prover/zkevm/prover/ecdsa/adress.go @@ -8,8 +8,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" "github.com/consensys/linea-monorepo/prover/protocol/dedicated/byte32cmp" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/zkevm/prover/common" @@ -99,26 +99,29 @@ func newAddress(comp *wizard.CompiledIOP, size int, ecRec *EcRecover, ac *antich // projection from ecRecover to address columns // ecdata is already projected over our ecRecover. Thus, we only project from our ecrecover. - projection.InsertProjection(comp, ifaces.QueryIDf("Project_AddressHi_EcRec"), - []ifaces.Column{ecRec.Limb}, []ifaces.Column{addr.addressHi}, - addr.isAddressHiEcRec, addr.isAddressFromEcRec, - ) + comp.InsertProjection(ifaces.QueryIDf("Project_AddressHi_EcRec"), query.ProjectionInput{ColumnA: []ifaces.Column{ecRec.Limb}, + ColumnB: []ifaces.Column{addr.addressHi}, + FilterA: addr.isAddressHiEcRec, + FilterB: addr.isAddressFromEcRec}) - projection.InsertProjection(comp, ifaces.QueryIDf("Project_AddressLo_EcRec"), - []ifaces.Column{ecRec.Limb}, []ifaces.Column{addr.addressLo}, - column.Shift(addr.isAddressHiEcRec, -1), addr.isAddressFromEcRec, - ) + comp.InsertProjection(ifaces.QueryIDf("Project_AddressLo_EcRec"), + query.ProjectionInput{ColumnA: []ifaces.Column{ecRec.Limb}, + ColumnB: []ifaces.Column{addr.addressLo}, + FilterA: column.Shift(addr.isAddressHiEcRec, -1), + FilterB: addr.isAddressFromEcRec}) // projection from txn-data to address columns - projection.InsertProjection(comp, ifaces.QueryIDf("Project_AddressHi_TxnData"), - []ifaces.Column{td.fromHi}, []ifaces.Column{addr.addressHi}, - td.isFrom, addr.isAddressFromTxnData, - ) - - projection.InsertProjection(comp, ifaces.QueryIDf("Project_AddressLO_TxnData"), - []ifaces.Column{td.fromLo}, []ifaces.Column{addr.addressLo}, - td.isFrom, addr.isAddressFromTxnData, - ) + comp.InsertProjection(ifaces.QueryIDf("Project_AddressHi_TxnData"), + query.ProjectionInput{ColumnA: []ifaces.Column{td.fromHi}, + ColumnB: []ifaces.Column{addr.addressHi}, + FilterA: td.isFrom, + FilterB: addr.isAddressFromTxnData}) + + comp.InsertProjection(ifaces.QueryIDf("Project_AddressLO_TxnData"), + query.ProjectionInput{ColumnA: []ifaces.Column{td.fromLo}, + ColumnB: []ifaces.Column{addr.addressLo}, + FilterA: td.isFrom, + FilterB: addr.isAddressFromTxnData}) // impose that hashNum = ac.ID + 1 comp.InsertGlobal(0, ifaces.QueryIDf("Hash_NUM_IS_ID"), diff --git a/prover/zkevm/prover/ecdsa/ecdata.go b/prover/zkevm/prover/ecdsa/ecdata.go index b54965f88e3..c1b2f335bf0 100644 --- a/prover/zkevm/prover/ecdsa/ecdata.go +++ b/prover/zkevm/prover/ecdsa/ecdata.go @@ -3,8 +3,8 @@ package ecdsa import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" commoncs "github.com/consensys/linea-monorepo/prover/zkevm/prover/common/common_constraints" @@ -166,11 +166,11 @@ func (ec *EcRecover) assignFromEcDataSource(run *wizard.ProverRuntime, src *ecDa } func (ec *EcRecover) csEcDataProjection(comp *wizard.CompiledIOP, src *ecDataSource) { - projection.InsertProjection(comp, ifaces.QueryIDf("%v_PROJECT_ECDATA", NAME_ECRECOVER), - []ifaces.Column{ec.EcRecoverID, ec.Limb, ec.SuccessBit, ec.EcRecoverIndex, ec.EcRecoverIsData, ec.EcRecoverIsRes}, - []ifaces.Column{src.ID, src.Limb, src.SuccessBit, src.Index, src.IsData, src.IsRes}, - ec.AuxProjectionMask, src.CsEcrecover, - ) + comp.InsertProjection(ifaces.QueryIDf("%v_PROJECT_ECDATA", NAME_ECRECOVER), + query.ProjectionInput{ColumnA: []ifaces.Column{ec.EcRecoverID, ec.Limb, ec.SuccessBit, ec.EcRecoverIndex, ec.EcRecoverIsData, ec.EcRecoverIsRes}, + ColumnB: []ifaces.Column{src.ID, src.Limb, src.SuccessBit, src.Index, src.IsData, src.IsRes}, + FilterA: ec.AuxProjectionMask, + FilterB: src.CsEcrecover}) } func (ec *EcRecover) csConstraintAuxProjectionMask(comp *wizard.CompiledIOP) { diff --git a/prover/zkevm/prover/ecdsa/unaligned_gnark.go b/prover/zkevm/prover/ecdsa/unaligned_gnark.go index 0396eca4e57..7b63fbef7b8 100644 --- a/prover/zkevm/prover/ecdsa/unaligned_gnark.go +++ b/prover/zkevm/prover/ecdsa/unaligned_gnark.go @@ -8,8 +8,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -349,14 +349,12 @@ func (d *UnalignedGnarkData) csProjectionEcRecover(comp *wizard.CompiledIOP, src )), ) // that we have projected correctly ecrecover - projection.InsertProjection( - comp, + comp.InsertProjection( ifaces.QueryIDf("%v_PROJECT_ECRECOVER", NAME_UNALIGNED_GNARKDATA), - []ifaces.Column{src.Limb}, - []ifaces.Column{d.GnarkData}, - d.isEcrecoverAndFetching, - d.isNotPublicKeyAndPushing, - ) + query.ProjectionInput{ColumnA: []ifaces.Column{src.Limb}, + ColumnB: []ifaces.Column{d.GnarkData}, + FilterA: d.isEcrecoverAndFetching, + FilterB: d.isNotPublicKeyAndPushing}) } func (d *UnalignedGnarkData) csTxHash(comp *wizard.CompiledIOP, src *unalignedGnarkDataSource) { diff --git a/prover/zkevm/prover/ecpair/ecpair_constraints.go b/prover/zkevm/prover/ecpair/ecpair_constraints.go index 932cca48219..789a3745e24 100644 --- a/prover/zkevm/prover/ecpair/ecpair_constraints.go +++ b/prover/zkevm/prover/ecpair/ecpair_constraints.go @@ -5,8 +5,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/column/verifiercol" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" common "github.com/consensys/linea-monorepo/prover/zkevm/prover/common/common_constraints" @@ -53,19 +53,18 @@ func (ec *ECPair) csOffWhenInactive(comp *wizard.CompiledIOP) { func (ec *ECPair) csProjections(comp *wizard.CompiledIOP) { // we project data from the arithmetization correctly to the unaligned part of the circuit - projection.InsertProjection( - comp, ifaces.QueryIDf("%v_PROJECTION_PAIRING", nameECPair), - []ifaces.Column{ec.ECPairSource.Limb, ec.ECPairSource.AccPairings, ec.ECPairSource.TotalPairings, ec.ECPairSource.ID}, - []ifaces.Column{ec.UnalignedPairingData.Limb, ec.UnalignedPairingData.PairID, ec.UnalignedPairingData.TotalPairs, ec.UnalignedPairingData.InstanceID}, - ec.ECPairSource.CsEcpairing, - ec.UnalignedPairingData.IsPulling, - ) - projection.InsertProjection( - comp, ifaces.QueryIDf("%v_PROJECTION_MEMBERSHIP", nameECPair), - []ifaces.Column{ec.ECPairSource.Limb, ec.ECPairSource.SuccessBit}, - []ifaces.Column{ec.UnalignedG2MembershipData.Limb, ec.UnalignedG2MembershipData.SuccessBit}, - ec.ECPairSource.CsG2Membership, ec.UnalignedG2MembershipData.IsPulling, - ) + comp.InsertProjection(ifaces.QueryIDf("%v_PROJECTION_PAIRING", nameECPair), + query.ProjectionInput{ColumnA: []ifaces.Column{ec.ECPairSource.Limb, ec.ECPairSource.AccPairings, ec.ECPairSource.TotalPairings, ec.ECPairSource.ID}, + ColumnB: []ifaces.Column{ec.UnalignedPairingData.Limb, ec.UnalignedPairingData.PairID, ec.UnalignedPairingData.TotalPairs, ec.UnalignedPairingData.InstanceID}, + FilterA: ec.ECPairSource.CsEcpairing, + FilterB: ec.UnalignedPairingData.IsPulling}) + + comp.InsertProjection( + ifaces.QueryIDf("%v_PROJECTION_MEMBERSHIP", nameECPair), + query.ProjectionInput{ColumnA: []ifaces.Column{ec.ECPairSource.Limb, ec.ECPairSource.SuccessBit}, + ColumnB: []ifaces.Column{ec.UnalignedG2MembershipData.Limb, ec.UnalignedG2MembershipData.SuccessBit}, + FilterA: ec.ECPairSource.CsG2Membership, + FilterB: ec.UnalignedG2MembershipData.IsPulling}) } func (ec *ECPair) csMembershipComputedResult(comp *wizard.CompiledIOP) { @@ -151,12 +150,12 @@ func (ec *ECPair) csAccumulatorInit(comp *wizard.CompiledIOP) { func (ec *ECPair) csAccumulatorConsistency(comp *wizard.CompiledIOP) { // that the accumulator between pairs is consistent - projection.InsertProjection( - comp, + comp.InsertProjection( ifaces.QueryIDf("%v_ACCUMULATOR_CONSISTENCY", nameECPair), - []ifaces.Column{ec.UnalignedPairingData.Limb}, []ifaces.Column{ec.UnalignedPairingData.Limb}, - ec.UnalignedPairingData.IsAccumulatorCurr, ec.UnalignedPairingData.IsAccumulatorPrev, - ) + query.ProjectionInput{ColumnA: []ifaces.Column{ec.UnalignedPairingData.Limb}, + ColumnB: []ifaces.Column{ec.UnalignedPairingData.Limb}, + FilterA: ec.UnalignedPairingData.IsAccumulatorCurr, + FilterB: ec.UnalignedPairingData.IsAccumulatorPrev}) } func (ec *ECPair) csLastPairToFinalExp(comp *wizard.CompiledIOP) { diff --git a/prover/zkevm/prover/hash/importpad/import_pad.go b/prover/zkevm/prover/hash/importpad/import_pad.go index 80d3bcd38b2..63b8cef80b6 100644 --- a/prover/zkevm/prover/hash/importpad/import_pad.go +++ b/prover/zkevm/prover/hash/importpad/import_pad.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/zkevm/prover/common" @@ -184,14 +184,12 @@ func ImportAndPad(comp *wizard.CompiledIOP, inp ImportAndPadInputs, numRows int) res.IsPadded, ) - projection.InsertProjection( - comp, + comp.InsertProjection( ifaces.QueryIDf("%v_IMPORT_PAD_PROJECTION", inp.Name), - []ifaces.Column{inp.Src.Data.HashNum, inp.Src.Data.Limb, inp.Src.Data.NBytes, inp.Src.Data.Index}, - []ifaces.Column{res.HashNum, res.Limbs, res.NBytes, res.Index}, - inp.Src.Data.ToHash, - res.IsInserted, - ) + query.ProjectionInput{ColumnA: []ifaces.Column{inp.Src.Data.HashNum, inp.Src.Data.Limb, inp.Src.Data.NBytes, inp.Src.Data.Index}, + ColumnB: []ifaces.Column{res.HashNum, res.Limbs, res.NBytes, res.Index}, + FilterA: inp.Src.Data.ToHash, + FilterB: res.IsInserted}) return res } diff --git a/prover/zkevm/prover/hash/keccak/acc_module/data_acc.go b/prover/zkevm/prover/hash/keccak/acc_module/data_acc.go index 8019ff20a02..0ab376f03cd 100644 --- a/prover/zkevm/prover/hash/keccak/acc_module/data_acc.go +++ b/prover/zkevm/prover/hash/keccak/acc_module/data_acc.go @@ -5,8 +5,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/common/vector" "github.com/consensys/linea-monorepo/prover/maths/field" - projection "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -70,12 +70,12 @@ func NewGenericDataAccumulator(comp *wizard.CompiledIOP, inp GenericAccumulatorI // projection among providers and stitched module for i, gbm := range d.Inputs.ProvidersData { - projection.InsertProjection(comp, ifaces.QueryIDf("Stitch_Modules_%v", i), - []ifaces.Column{gbm.HashNum, gbm.Limb, gbm.NBytes, gbm.Index}, - []ifaces.Column{d.Provider.HashNum, d.Provider.Limb, d.Provider.NBytes, d.Provider.Index}, - gbm.ToHash, - d.sFilters[i], - ) + comp.InsertProjection(ifaces.QueryIDf("Stitch_Modules_%v", i), + query.ProjectionInput{ColumnA: []ifaces.Column{gbm.HashNum, gbm.Limb, gbm.NBytes, gbm.Index}, + ColumnB: []ifaces.Column{d.Provider.HashNum, d.Provider.Limb, d.Provider.NBytes, d.Provider.Index}, + FilterA: gbm.ToHash, + FilterB: d.sFilters[i]}) + } return d diff --git a/prover/zkevm/prover/hash/keccak/acc_module/info_acc.go b/prover/zkevm/prover/hash/keccak/acc_module/info_acc.go index 90dec74f666..bff6687ac76 100644 --- a/prover/zkevm/prover/hash/keccak/acc_module/info_acc.go +++ b/prover/zkevm/prover/hash/keccak/acc_module/info_acc.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/common/vector" "github.com/consensys/linea-monorepo/prover/maths/field" - projection "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -59,19 +59,17 @@ func NewGenericInfoAccumulator(comp *wizard.CompiledIOP, inp GenericAccumulatorI // projection among providers and stitched module for i, gbm := range info.Inputs.ProvidersInfo { - projection.InsertProjection(comp, ifaces.QueryIDf("Stitch_Modules_Hi_%v", i), - []ifaces.Column{gbm.HashHi}, - []ifaces.Column{info.Provider.HashHi}, - gbm.IsHashHi, - info.sFilters[i], - ) - - projection.InsertProjection(comp, ifaces.QueryIDf("Stitch_Modules_Lo_%v", i), - []ifaces.Column{gbm.HashLo}, - []ifaces.Column{info.Provider.HashLo}, - gbm.IsHashLo, - info.sFilters[i], - ) + comp.InsertProjection(ifaces.QueryIDf("Stitch_Modules_Hi_%v", i), + query.ProjectionInput{ColumnA: []ifaces.Column{gbm.HashHi}, + ColumnB: []ifaces.Column{info.Provider.HashHi}, + FilterA: gbm.IsHashHi, + FilterB: info.sFilters[i]}) + + comp.InsertProjection(ifaces.QueryIDf("Stitch_Modules_Lo_%v", i), + query.ProjectionInput{ColumnA: []ifaces.Column{gbm.HashLo}, + ColumnB: []ifaces.Column{info.Provider.HashLo}, + FilterA: gbm.IsHashLo, + FilterB: info.sFilters[i]}) } return info } diff --git a/prover/zkevm/prover/hash/keccak/keccak_single_provider.go b/prover/zkevm/prover/hash/keccak/keccak_single_provider.go index 931f652f0a8..622a617a7fb 100644 --- a/prover/zkevm/prover/hash/keccak/keccak_single_provider.go +++ b/prover/zkevm/prover/hash/keccak/keccak_single_provider.go @@ -4,8 +4,8 @@ package keccak import ( - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/utils" "github.com/consensys/linea-monorepo/prover/zkevm/prover/hash/generic" @@ -82,18 +82,17 @@ func NewKeccakSingleProvider(comp *wizard.CompiledIOP, inp KeccakSingleProviderI cKeccak = NewKeccakOverBlocks(comp, cKeccakInp) ) - projection.InsertProjection(comp, "KECCAK_RES_HI", - []ifaces.Column{cKeccak.HashHi}, - []ifaces.Column{inp.Provider.Info.HashHi}, - cKeccak.IsActive, - inp.Provider.Info.IsHashHi, - ) - projection.InsertProjection(comp, "KECCAK_RES_LO", - []ifaces.Column{cKeccak.HashLo}, - []ifaces.Column{inp.Provider.Info.HashLo}, - cKeccak.IsActive, - inp.Provider.Info.IsHashLo, - ) + comp.InsertProjection("KECCAK_RES_HI", + query.ProjectionInput{ColumnA: []ifaces.Column{cKeccak.HashHi}, + ColumnB: []ifaces.Column{inp.Provider.Info.HashHi}, + FilterA: cKeccak.IsActive, + FilterB: inp.Provider.Info.IsHashHi}) + + comp.InsertProjection("KECCAK_RES_LO", + query.ProjectionInput{ColumnA: []ifaces.Column{cKeccak.HashLo}, + ColumnB: []ifaces.Column{inp.Provider.Info.HashLo}, + FilterA: cKeccak.IsActive, + FilterB: inp.Provider.Info.IsHashLo}) // set the module m := &KeccakSingleProvider{ diff --git a/prover/zkevm/prover/hash/keccak/keccakf/io.go b/prover/zkevm/prover/hash/keccak/keccakf/io.go index 4cd848aec9c..0151cd04e2f 100644 --- a/prover/zkevm/prover/hash/keccak/keccakf/io.go +++ b/prover/zkevm/prover/hash/keccak/keccakf/io.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/linea-monorepo/prover/crypto/keccak" "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -229,11 +229,11 @@ func (io *InputOutput) csHashOutput(comp *wizard.CompiledIOP) { colB = append(colB, io.HashOutputSlicesBaseB[2][:]...) colB = append(colB, io.HashOutputSlicesBaseB[3][:]...) - projection.InsertProjection(comp, ifaces.QueryIDf("HashOutput_Projection"), - colB, colA, - io.IsActive, - io.IsHashOutPut, - ) + comp.InsertProjection(ifaces.QueryIDf("HashOutput_Projection"), + query.ProjectionInput{ColumnA: colB, + ColumnB: colA, + FilterA: io.IsActive, + FilterB: io.IsHashOutPut}) } // It assigns the columns specific to the submodule. diff --git a/prover/zkevm/prover/hash/packing/lane.go b/prover/zkevm/prover/hash/packing/lane.go index 49795ffb22c..995a342bc57 100644 --- a/prover/zkevm/prover/hash/packing/lane.go +++ b/prover/zkevm/prover/hash/packing/lane.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -81,11 +81,11 @@ func newLane(comp *wizard.CompiledIOP, spaghetti spaghettiCtx, pckInp PackingInp // constraints over isFirstLaneOfNewHash // Project the isFirstLaneOfNewHash from isFirstSliceOfNewHash - projection.InsertProjection(comp, ifaces.QueryIDf("Project_IsFirstLaneOfHash_"+pckInp.Name), - []ifaces.Column{isFirstSliceOfNewHash}, - []ifaces.Column{l.IsFirstLaneOfNewHash}, - l.isLaneComplete, l.IsLaneActive) - + comp.InsertProjection(ifaces.QueryIDf("Project_IsFirstLaneOfHash_"+pckInp.Name), + query.ProjectionInput{ColumnA: []ifaces.Column{isFirstSliceOfNewHash}, + ColumnB: []ifaces.Column{l.IsFirstLaneOfNewHash}, + FilterA: l.isLaneComplete, + FilterB: l.IsLaneActive}) return l } @@ -135,12 +135,11 @@ func (l *laneRepacking) csRecomposeToLanes(comp *wizard.CompiledIOP, s spaghetti ) // Project the lanes from ipTracker over the Lane column. - projection.InsertProjection(comp, ifaces.QueryIDf("%v_ProjectOverLanes", l.Inputs.pckInp.Name), - []ifaces.Column{ipTracker}, - []ifaces.Column{l.Lanes}, - l.isLaneComplete, l.IsLaneActive, - ) - + comp.InsertProjection(ifaces.QueryIDf("%v_ProjectOverLanes", l.Inputs.pckInp.Name), + query.ProjectionInput{ColumnA: []ifaces.Column{ipTracker}, + ColumnB: []ifaces.Column{l.Lanes}, + FilterA: l.isLaneComplete, + FilterB: l.IsLaneActive}) } // It assigns the columns specific to the submodule diff --git a/prover/zkevm/prover/hash/sha2/sha2.go b/prover/zkevm/prover/hash/sha2/sha2.go index 6e16837a217..b7c3169a81f 100644 --- a/prover/zkevm/prover/hash/sha2/sha2.go +++ b/prover/zkevm/prover/hash/sha2/sha2.go @@ -4,8 +4,8 @@ package sha2 import ( "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/utils" "github.com/consensys/linea-monorepo/prover/zkevm/prover/hash/generic" @@ -112,18 +112,17 @@ func newSha2SingleProvider(comp *wizard.CompiledIOP, inp Sha2SingleProviderInput cSha2 = newSha2BlockModule(comp, cSha2Inp).WithCircuit(comp) ) - projection.InsertProjection(comp, "SHA2_RES_HI", - []ifaces.Column{cSha2.HashHi}, - []ifaces.Column{inp.Provider.Info.HashHi}, - cSha2.IsEffFirstLaneOfNewHash, - inp.Provider.Info.IsHashHi, - ) - projection.InsertProjection(comp, "SHA2_RES_LO", - []ifaces.Column{cSha2.HashLo}, - []ifaces.Column{inp.Provider.Info.HashLo}, - cSha2.IsEffFirstLaneOfNewHash, - inp.Provider.Info.IsHashLo, - ) + comp.InsertProjection("SHA2_RES_HI", + query.ProjectionInput{ColumnA: []ifaces.Column{cSha2.HashHi}, + ColumnB: []ifaces.Column{inp.Provider.Info.HashHi}, + FilterA: cSha2.IsEffFirstLaneOfNewHash, + FilterB: inp.Provider.Info.IsHashHi}) + + comp.InsertProjection("SHA2_RES_LO", + query.ProjectionInput{ColumnA: []ifaces.Column{cSha2.HashLo}, + ColumnB: []ifaces.Column{inp.Provider.Info.HashLo}, + FilterA: cSha2.IsEffFirstLaneOfNewHash, + FilterB: inp.Provider.Info.IsHashLo}) // set the module m := &Sha2SingleProvider{ diff --git a/prover/zkevm/prover/hash/sha2/sha2_block.go b/prover/zkevm/prover/hash/sha2/sha2_block.go index aab5bafd626..bd5c05749f9 100644 --- a/prover/zkevm/prover/hash/sha2/sha2_block.go +++ b/prover/zkevm/prover/hash/sha2/sha2_block.go @@ -6,8 +6,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" "github.com/consensys/linea-monorepo/prover/protocol/dedicated/plonk" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -290,20 +290,14 @@ func newSha2BlockModule(comp *wizard.CompiledIOP, inp *sha2BlocksInputs) *sha2Bl // The following query ensures that the data in limbs corresponding to // limbs are exactly those provided by the input module. - projection.InsertProjection( - comp, + comp.InsertProjection( ifaces.QueryIDf("%v_PROJECTION_INPUT", inp.Name), - []ifaces.Column{ - res.Inputs.IsFirstLaneOfNewHash, - res.Inputs.PackedUint32, - }, - []ifaces.Column{ - column.Shift(res.IsEffFirstLaneOfNewHash, -2), - res.Limbs, - }, - res.Inputs.Selector, - res.IsEffBlock, - ) + query.ProjectionInput{ColumnA: []ifaces.Column{res.Inputs.IsFirstLaneOfNewHash, + res.Inputs.PackedUint32}, + ColumnB: []ifaces.Column{column.Shift(res.IsEffFirstLaneOfNewHash, -2), + res.Limbs}, + FilterA: res.Inputs.Selector, + FilterB: res.IsEffBlock}) // As per the padding technique we use, the HashHi and HashLo should not // be zero when isActive. diff --git a/prover/zkevm/prover/modexp/module.go b/prover/zkevm/prover/modexp/module.go index fbe05a69b2b..b384529fa86 100644 --- a/prover/zkevm/prover/modexp/module.go +++ b/prover/zkevm/prover/modexp/module.go @@ -5,8 +5,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated/plonk" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/variables" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" @@ -96,15 +96,12 @@ func newModule(comp *wizard.CompiledIOP, input Input) *Module { mod.csIsSmallAndLarge(comp) mod.csToCirc(comp) - projection.InsertProjection( - comp, + comp.InsertProjection( "MODEXP_BLKMDXP_PROJECTION", - []ifaces.Column{mod.Input.Limbs}, - []ifaces.Column{mod.Limbs}, - mod.Input.isModExp, - mod.IsActive, - ) - + query.ProjectionInput{ColumnA: []ifaces.Column{mod.Input.Limbs}, + ColumnB: []ifaces.Column{mod.Limbs}, + FilterA: mod.Input.isModExp, + FilterB: mod.IsActive}) return mod } diff --git a/prover/zkevm/prover/publicInput/execution_data_collector/execution_data_collector.go b/prover/zkevm/prover/publicInput/execution_data_collector/execution_data_collector.go index 06f3b905919..6f6848a7359 100644 --- a/prover/zkevm/prover/publicInput/execution_data_collector/execution_data_collector.go +++ b/prover/zkevm/prover/publicInput/execution_data_collector/execution_data_collector.go @@ -6,8 +6,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/accessors" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" arith "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/arith_struct" @@ -808,14 +808,12 @@ func ProjectionQueries(comp *wizard.CompiledIOP, edc.LastAbsTxIDBlock, } - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_BLOCK_METADATA_PROJECTION", name), - edcMetadataTable, - metadataTable, - edc.IsNoTx, // We filter on rows where the blockdata is loaded. - metadata.FilterFetched, - ) - + query.ProjectionInput{ColumnA: edcMetadataTable, + ColumnB: metadataTable, + FilterA: edc.IsNoTx, // We filter on rows where the blockdata is loaded. + FilterB: metadata.FilterFetched}) // Because we filtered on edc.IsNoTx=1, we also ensure that FirstAbsTxIDBlock and LastAbsTxIDBlock // remain constant in the DefineConstantConstraints function. // we do not need to also check the constancy of TotalNoTxBlock, as it is only used when IsNoTx=1 @@ -833,13 +831,12 @@ func ProjectionQueries(comp *wizard.CompiledIOP, edc.UnalignedLimb, } - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_TIMESTAMP_PROJECTION", name), - edcTimestamps, - timestampTable, - edc.IsTimestamp, // filter on IsTimestamp=1 - timestamps.FilterFetched, - ) + query.ProjectionInput{ColumnA: edcTimestamps, + ColumnB: timestampTable, + FilterA: edc.IsTimestamp, // filter on IsTimestamp=1 + FilterB: timestamps.FilterFetched}) // Prepare a projection query to the TxnData fetcher, to check the Hi part of the sender address. // compute the fetcher table, directly tied to the arithmetization. @@ -855,13 +852,12 @@ func ProjectionQueries(comp *wizard.CompiledIOP, edc.UnalignedLimb, } - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_SENDER_ADDRESS_HI_PROJECTION", name), - edcTxnSenderAddressTableHi, - txnDataTableHi, - edc.IsAddrHi, // filter on IsAddrHi=1 - txnData.FilterFetched, - ) + query.ProjectionInput{ColumnA: edcTxnSenderAddressTableHi, + ColumnB: txnDataTableHi, + FilterA: edc.IsAddrHi, // filter on IsAddrHi=1 + FilterB: txnData.FilterFetched}) // Prepare the projection query to the TxnData fetcher, to check the Lo part of the sender address. // compute the fetcher table, directly tied to the arithmetization. @@ -877,13 +873,12 @@ func ProjectionQueries(comp *wizard.CompiledIOP, edc.UnalignedLimb, } - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_SENDER_ADDRESS_LO_PROJECTION", name), - edcTxnSenderAddressTableLo, - txnDataTableLo, - edc.IsAddrLo, // filter on IsAddrLo=1 - txnData.FilterFetched, - ) + query.ProjectionInput{ColumnA: edcTxnSenderAddressTableLo, + ColumnB: txnDataTableLo, + FilterA: edc.IsAddrLo, // filter on IsAddrLo=1 + FilterB: txnData.FilterFetched}) // Prepare the projection query to the RlpTxn fetcher, to check: // AbsTxNum, AbsTxNumMax, Limb, NBytes and EndOfRlpSegment. @@ -906,13 +901,12 @@ func ProjectionQueries(comp *wizard.CompiledIOP, // EndOfRlpSegment is also constrained in DefineZeroizationConstraints, with respect to IsActive. } - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_RLP_LIMB_DATA_PROJECTION", name), - edcRlpDataTable, - rlpDataTable, - edc.IsTxRLP, // filter on IsTxRLP=1 - rlp.FilterFetched, - ) + query.ProjectionInput{ColumnA: edcRlpDataTable, + ColumnB: rlpDataTable, + FilterA: edc.IsTxRLP, // filter on IsTxRLP=1 + FilterB: rlp.FilterFetched}) } // LookupQueries computes lookup queries to the BlockTxnMetadata arithmetization fetcher: @@ -937,7 +931,7 @@ func LookupQueries(comp *wizard.CompiledIOP, } comp.InsertInclusionDoubleConditional(0, - ifaces.QueryIDf("%s_BLOCK_METADATA_PROJECTION", name), + ifaces.QueryIDf("%s_BLOCK_METADATA_DOUBLE_CONDITIONAL_LOOKUP", name), metadataTable, // including table edcMetadataTable, // included table metadata.FilterFetched, diff --git a/prover/zkevm/prover/publicInput/fetchers_arithmetization/block_txn_metadata_fetcher.go b/prover/zkevm/prover/publicInput/fetchers_arithmetization/block_txn_metadata_fetcher.go index 3784b5ac968..1db5a8d103d 100644 --- a/prover/zkevm/prover/publicInput/fetchers_arithmetization/block_txn_metadata_fetcher.go +++ b/prover/zkevm/prover/publicInput/fetchers_arithmetization/block_txn_metadata_fetcher.go @@ -5,8 +5,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" arith "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/arith_struct" @@ -130,13 +130,12 @@ func DefineBlockTxnMetaData(comp *wizard.CompiledIOP, btm *BlockTxnMetadata, nam } // a projection query to check that the sender addresses are fetched correctly - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_PROJECTION", name), - fetcherTable, - arithTable, - btm.FilterFetched, - btm.FilterArith, - ) + query.ProjectionInput{ColumnA: fetcherTable, + ColumnB: arithTable, + FilterA: btm.FilterFetched, + FilterB: btm.FilterArith}) } func AssignBlockTxnMetadata(run *wizard.ProverRuntime, btm BlockTxnMetadata, td *arith.TxnData) { diff --git a/prover/zkevm/prover/publicInput/fetchers_arithmetization/rlp_txn_fetcher.go b/prover/zkevm/prover/publicInput/fetchers_arithmetization/rlp_txn_fetcher.go index 57b9e135d32..7dfa1460981 100644 --- a/prover/zkevm/prover/publicInput/fetchers_arithmetization/rlp_txn_fetcher.go +++ b/prover/zkevm/prover/publicInput/fetchers_arithmetization/rlp_txn_fetcher.go @@ -6,8 +6,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/accessors" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" arith "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/arith_struct" @@ -148,13 +148,13 @@ func DefineRlpTxnFetcher(comp *wizard.CompiledIOP, fetcher *RlpTxnFetcher, name } // a projection query to check that the timestamp data is fetched correctly - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_RLP_TXN_PROJECTION", name), - fetcherTable, - arithTable, - fetcher.FilterFetched, - rlpTxnArith.ToHashByProver, // filter lights up on the arithmetization's RlpTxn rows that contain rlp transaction data - ) + query.ProjectionInput{ColumnA: fetcherTable, + ColumnB: arithTable, + FilterA: fetcher.FilterFetched, + // filter lights up on the arithmetization's RlpTxn rows that contain rlp transaction data + FilterB: rlpTxnArith.ToHashByProver}) } func AssignRlpTxnFetcher(run *wizard.ProverRuntime, fetcher *RlpTxnFetcher, rlpTxnArith *arith.RlpTxn) { diff --git a/prover/zkevm/prover/publicInput/fetchers_arithmetization/timestamp_fetcher.go b/prover/zkevm/prover/publicInput/fetchers_arithmetization/timestamp_fetcher.go index dde7d303ba8..195fd3546f6 100644 --- a/prover/zkevm/prover/publicInput/fetchers_arithmetization/timestamp_fetcher.go +++ b/prover/zkevm/prover/publicInput/fetchers_arithmetization/timestamp_fetcher.go @@ -6,8 +6,8 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/accessors" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" arith "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/arith_struct" @@ -182,13 +182,13 @@ func DefineTimestampFetcher(comp *wizard.CompiledIOP, fetcher *TimestampFetcher, } // a projection query to check that the timestamp data is fetched correctly - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_TIMESTAMP_PROJECTION", name), - fetcherTable, - arithTable, - fetcher.FilterFetched, - fetcher.SelectorTimestamp, // filter lights up on the arithmetization's BlockDataCols rows that contain timestamp data - ) + query.ProjectionInput{ColumnA: fetcherTable, + ColumnB: arithTable, + FilterA: fetcher.FilterFetched, + // filter lights up on the arithmetization's BlockDataCols rows that contain timestamp data + FilterB: fetcher.SelectorTimestamp}) // constrain the First/Last Block ID counters ConstrainFirstAndLastBlockID(comp, fetcher, name, bdc) diff --git a/prover/zkevm/prover/publicInput/fetchers_arithmetization/txn_data_fetcher.go b/prover/zkevm/prover/publicInput/fetchers_arithmetization/txn_data_fetcher.go index 531058fb3be..825a43ac693 100644 --- a/prover/zkevm/prover/publicInput/fetchers_arithmetization/txn_data_fetcher.go +++ b/prover/zkevm/prover/publicInput/fetchers_arithmetization/txn_data_fetcher.go @@ -5,8 +5,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/dedicated" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" arith "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/arith_struct" @@ -81,13 +81,13 @@ func DefineTxnDataFetcher(comp *wizard.CompiledIOP, fetcher *TxnDataFetcher, nam } // a projection query to check that the sender addresses are fetched correctly - projection.InsertProjection(comp, + comp.InsertProjection( ifaces.QueryIDf("%s_TXN_DATA_FETCHER_PROJECTION", name), - fetcherTable, - arithTable, - fetcher.FilterFetched, - fetcher.SelectorFromAddress, // filter lights up on the arithmetization's TxnData rows that contain sender address data - ) + query.ProjectionInput{ColumnA: fetcherTable, + ColumnB: arithTable, + FilterA: fetcher.FilterFetched, + // filter lights up on the arithmetization's TxnData rows that contain sender address data + FilterB: fetcher.SelectorFromAddress}) } // AssignTxnDataFetcher assigns the data in the TxnDataFetcher using data fetched from the TxnData diff --git a/prover/zkevm/prover/publicInput/logs/extracted_data.go b/prover/zkevm/prover/publicInput/logs/extracted_data.go index d8ce2673165..1e86056a0e0 100644 --- a/prover/zkevm/prover/publicInput/logs/extracted_data.go +++ b/prover/zkevm/prover/publicInput/logs/extracted_data.go @@ -4,8 +4,8 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/column" - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" sym "github.com/consensys/linea-monorepo/prover/symbolic" util "github.com/consensys/linea-monorepo/prover/zkevm/prover/publicInput/utilities" @@ -92,7 +92,12 @@ func DefineExtractedData(comp *wizard.CompiledIOP, logCols LogColumns, sel Selec ), ) // a projection query to check that the messages are fetched correctly - projection.InsertProjection(comp, ifaces.QueryIDf("%s_LOGS_PROJECTION", GetName(logType)), fetchedTable, logsTable, fetched.filterFetched, fetched.filterArith) + comp.InsertProjection( + ifaces.QueryIDf("%s_LOGS_PROJECTION", GetName(logType)), + query.ProjectionInput{ColumnA: fetchedTable, + ColumnB: logsTable, + FilterA: fetched.filterFetched, + FilterB: fetched.filterArith}) } // CheckBridgeAddress checks if a row does indeed contain the data corresponding to a the bridge address diff --git a/prover/zkevm/prover/statemanager/mimccodehash/input_consistency.go b/prover/zkevm/prover/statemanager/mimccodehash/input_consistency.go index 24c36bd7658..b42153b87c9 100644 --- a/prover/zkevm/prover/statemanager/mimccodehash/input_consistency.go +++ b/prover/zkevm/prover/statemanager/mimccodehash/input_consistency.go @@ -1,8 +1,8 @@ package mimccodehash import ( - "github.com/consensys/linea-monorepo/prover/protocol/dedicated/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/query" "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) @@ -27,12 +27,12 @@ func (mch *Module) ConnectToRom(comp *wizard.CompiledIOP, romInput.complete(comp) // Projection query between romInput and MiMCCodeHash module - projection.InsertProjection(comp, ifaces.QueryIDf("PROJECTION_ROM_MIMC_CODE_HASH_%v", mch.inputs.Name), - []ifaces.Column{romInput.CFI, romInput.Acc, romInput.CodeSize}, - []ifaces.Column{mch.CFI, mch.Limb, mch.CodeSize}, - romInput.CounterIsEqualToNBytesMinusOne, - mch.IsActive, - ) + comp.InsertProjection( + ifaces.QueryIDf("PROJECTION_ROM_MIMC_CODE_HASH_%v", mch.inputs.Name), + query.ProjectionInput{ColumnA: []ifaces.Column{romInput.CFI, romInput.Acc, romInput.CodeSize}, + ColumnB: []ifaces.Column{mch.CFI, mch.Limb, mch.CodeSize}, + FilterA: romInput.CounterIsEqualToNBytesMinusOne, + FilterB: mch.IsActive}) // Lookup between romLexInput and mch for // {CFI, codeHashHi, codeHashLo}