From 20df8d456f06bec8eb17a0170e2534e4bacebbdf Mon Sep 17 00:00:00 2001 From: AlexandreBelling Date: Thu, 28 Nov 2024 15:01:35 +0100 Subject: [PATCH 01/21] commit all ideas --- .../compiler/inclusion/inclusion.go | 7 ++ .../compiler/permutation/permutation.go | 7 ++ .../compiler/projection/projection.go | 7 ++ prover/protocol/distributed/distributed.go | 80 +++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 prover/protocol/distributed/compiler/inclusion/inclusion.go create mode 100644 prover/protocol/distributed/compiler/permutation/permutation.go create mode 100644 prover/protocol/distributed/compiler/projection/projection.go create mode 100644 prover/protocol/distributed/distributed.go diff --git a/prover/protocol/distributed/compiler/inclusion/inclusion.go b/prover/protocol/distributed/compiler/inclusion/inclusion.go new file mode 100644 index 000000000..74f8e5083 --- /dev/null +++ b/prover/protocol/distributed/compiler/inclusion/inclusion.go @@ -0,0 +1,7 @@ +package inclusion + +import "github.com/consensys/linea-monorepo/prover/protocol/wizard" + +func IntoLogDerivativeSum(comp *wizard.CompiledIOP) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go new file mode 100644 index 000000000..0e3827905 --- /dev/null +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -0,0 +1,7 @@ +package permutation + +import "github.com/consensys/linea-monorepo/prover/protocol/wizard" + +func IntoGrandProduct(comp *wizard.CompiledIOP) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/compiler/projection/projection.go b/prover/protocol/distributed/compiler/projection/projection.go new file mode 100644 index 000000000..1085ca6f4 --- /dev/null +++ b/prover/protocol/distributed/compiler/projection/projection.go @@ -0,0 +1,7 @@ +package projection + +import "github.com/consensys/linea-monorepo/prover/protocol/wizard" + +func IntoGrandSum(comp *wizard.CompiledIOP) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/distributed.go b/prover/protocol/distributed/distributed.go new file mode 100644 index 000000000..3484bafaa --- /dev/null +++ b/prover/protocol/distributed/distributed.go @@ -0,0 +1,80 @@ +package distributed + +import ( + "github.com/consensys/linea-monorepo/prover/maths/field" + "github.com/consensys/linea-monorepo/prover/protocol/compiler/mimc" + "github.com/consensys/linea-monorepo/prover/protocol/compiler/specialqueries" + "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/inclusion" + "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/permutation" + "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/projection" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" +) + +type moduleName = string + +type DistributedWizard struct { + Bootstrapper *wizard.CompiledIOP + DistributedModules []DistributedModule + Aggregator *wizard.CompiledIOP +} + +type DistributedModule struct { + LookupPermProj *wizard.CompiledIOP + GlobalLocal *wizard.CompiledIOP + VK [2]field.Element +} + +type ModuleDiscoverer interface { + // Analyze is responsible for letting the module discoverer compute how to + // group best the columns into modules. + Analyze(comp *wizard.CompiledIOP) + NbModules() moduleName + ModuleList() []string + FindModule(col ifaces.Column) moduleName +} + +// This transforms the initial wizard. So it is not really the initial +// wizard anymore. That means the caller can forget about "initialWizard" +// after calling the function. +func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer) DistributedWizard { + + prepare(initialWizard) + disc.Analyze(initialWizard) + + addSplittingStep(disc, initialWizard) // adds a prover step to "push" all the sub-witness assignment + + moduleLs := disc.ModuleList() + distModules := []DistributedModule{} + + for _, modName := range moduleLs { + distMod := extractDistModule(initialWizard, disc, modName) + distModules = append(distModules, distMod) + } + + // Compile every dist module with the same sequence of compilation steps for uniformity + + return DistributedWizard{ + Bootstrapper: initialWizard, + } +} + +// It adds the compilation steps +func prepare(comp *wizard.CompiledIOP) { + + mimc.CompileMiMC(comp) + specialqueries.RangeProof(comp) + specialqueries.CompileFixedPermutations(comp) + + inclusion.IntoLogDerivativeSum(comp) + permutation.IntoGrandProduct(comp) + projection.IntoGrandSum(comp) +} + +func addSplittingStep(comp *wizard.CompiledIOP) { + panic("unimplemented") +} + +func extractDistModule(comp *wizard.CompiledIOP, disc ModuleDiscoverer, moduleName moduleName) DistributedModule { + panic("unimplemented") +} From 16fbcd9547eb0b4add7d9d86c217f89d0da9b239 Mon Sep 17 00:00:00 2001 From: Soleimani193 Date: Mon, 2 Dec 2024 09:48:18 +0100 Subject: [PATCH 02/21] added aggregator --- .../distributed/compiler/global/global.go | 7 ++++ .../distributed/compiler/local/local.go | 7 ++++ prover/protocol/distributed/distributed.go | 33 ++++++++++++++----- 3 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 prover/protocol/distributed/compiler/global/global.go create mode 100644 prover/protocol/distributed/compiler/local/local.go diff --git a/prover/protocol/distributed/compiler/global/global.go b/prover/protocol/distributed/compiler/global/global.go new file mode 100644 index 000000000..28a5777b9 --- /dev/null +++ b/prover/protocol/distributed/compiler/global/global.go @@ -0,0 +1,7 @@ +package global + +import "github.com/consensys/linea-monorepo/prover/protocol/wizard" + +func IntoDistributedGlobal(comp *wizard.CompiledIOP) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/compiler/local/local.go b/prover/protocol/distributed/compiler/local/local.go new file mode 100644 index 000000000..a8d0dbfbc --- /dev/null +++ b/prover/protocol/distributed/compiler/local/local.go @@ -0,0 +1,7 @@ +package local + +import "github.com/consensys/linea-monorepo/prover/protocol/wizard" + +func IntoDistributedLocal(comp *wizard.CompiledIOP) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/distributed.go b/prover/protocol/distributed/distributed.go index 3484bafaa..b4ee11823 100644 --- a/prover/protocol/distributed/distributed.go +++ b/prover/protocol/distributed/distributed.go @@ -4,7 +4,9 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/compiler/mimc" "github.com/consensys/linea-monorepo/prover/protocol/compiler/specialqueries" + "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/global" "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/inclusion" + "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/local" "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/permutation" "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" @@ -19,6 +21,7 @@ type DistributedWizard struct { Aggregator *wizard.CompiledIOP } +// DistributedModule implements the utilities relevant to a single segment. type DistributedModule struct { LookupPermProj *wizard.CompiledIOP GlobalLocal *wizard.CompiledIOP @@ -30,32 +33,40 @@ type ModuleDiscoverer interface { // group best the columns into modules. Analyze(comp *wizard.CompiledIOP) NbModules() moduleName - ModuleList() []string + ModuleList(comp *wizard.CompiledIOP) []string FindModule(col ifaces.Column) moduleName } // This transforms the initial wizard. So it is not really the initial // wizard anymore. That means the caller can forget about "initialWizard" // after calling the function. -func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer) DistributedWizard { +// maxNbSegment is a large max for the number of segments in a module. +func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer, maxNbSegments int) DistributedWizard { + // prepare the initialWizard for the distribution. e.g., + // adding auxiliary columns or dividing a lookup query to two queries one over T and the other over S. prepare(initialWizard) + // it updates the map of Modules-Columns (that is a field of initialWizard). disc.Analyze(initialWizard) - addSplittingStep(disc, initialWizard) // adds a prover step to "push" all the sub-witness assignment - - moduleLs := disc.ModuleList() + moduleLs := disc.ModuleList(initialWizard) distModules := []DistributedModule{} for _, modName := range moduleLs { + // Segment Compilation; + // Compile every dist module with the same sequence of compilation steps for uniformity distMod := extractDistModule(initialWizard, disc, modName) distModules = append(distModules, distMod) } - // Compile every dist module with the same sequence of compilation steps for uniformity + // for each [DistributedModule] it checks the consistency among + // its replications where the number of replications is maxNbSegments. + aggr := aggregator(maxNbSegments, distModules, moduleLs) return DistributedWizard{ - Bootstrapper: initialWizard, + Bootstrapper: initialWizard, + DistributedModules: distModules, + Aggregator: aggr, } } @@ -69,12 +80,18 @@ func prepare(comp *wizard.CompiledIOP) { inclusion.IntoLogDerivativeSum(comp) permutation.IntoGrandProduct(comp) projection.IntoGrandSum(comp) + local.IntoDistributedLocal(comp) + global.IntoDistributedGlobal(comp) } -func addSplittingStep(comp *wizard.CompiledIOP) { +func addSplittingStep(comp *wizard.CompiledIOP, disc ModuleDiscoverer) { panic("unimplemented") } func extractDistModule(comp *wizard.CompiledIOP, disc ModuleDiscoverer, moduleName moduleName) DistributedModule { panic("unimplemented") } + +func aggregator(n int, idsModules []DistributedModule, moduleNames []string) *wizard.CompiledIOP { + panic("unimplemented") +} From a199f4d2d1e6c1049bb29ae1aacfb6e920965dde Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Tue, 3 Dec 2024 18:50:57 +0530 Subject: [PATCH 03/21] initial framework added --- .../protocol/compiler/permutation/compiler.go | 4 +- prover/protocol/compiler/permutation/utils.go | 4 +- .../compiler/permutation/permutation.go | 47 ++++++++++++++++++- prover/protocol/distributed/distributed.go | 3 +- prover/protocol/wizard/compiled.go | 5 ++ 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/prover/protocol/compiler/permutation/compiler.go b/prover/protocol/compiler/permutation/compiler.go index 1c8320dba..46526ce55 100644 --- a/prover/protocol/compiler/permutation/compiler.go +++ b/prover/protocol/compiler/permutation/compiler.go @@ -67,11 +67,11 @@ func dispatchPermutation( var ( isMultiColumn = len(q.A[0]) > 1 alpha coin.Info - beta = comp.InsertCoin(round+1, deriveName[coin.Name](q, "BETA"), coin.Field) + beta = comp.InsertCoin(round+1, DeriveName[coin.Name](q, "BETA"), coin.Field) ) if isMultiColumn { - alpha = comp.InsertCoin(round+1, deriveName[coin.Name](q, "ALPHA"), coin.Field) + alpha = comp.InsertCoin(round+1, DeriveName[coin.Name](q, "ALPHA"), coin.Field) } for k, aOrB := range [2][][]ifaces.Column{q.A, q.B} { diff --git a/prover/protocol/compiler/permutation/utils.go b/prover/protocol/compiler/permutation/utils.go index ffa652e98..d3777cee1 100644 --- a/prover/protocol/compiler/permutation/utils.go +++ b/prover/protocol/compiler/permutation/utils.go @@ -7,8 +7,8 @@ import ( const permutationStr = "PERMUTATION" -// deriveName constructs a name for the permutation context -func deriveName[R ~string](q query.Permutation, ss ...any) R { +// DeriveName constructs a name for the permutation context +func DeriveName[R ~string](q query.Permutation, ss ...any) R { ss = append([]any{permutationStr, q}, ss...) return wizardutils.DeriveName[R](ss...) } diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 0e3827905..f11ca8469 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -1,7 +1,50 @@ package permutation -import "github.com/consensys/linea-monorepo/prover/protocol/wizard" +import ( + "github.com/consensys/linea-monorepo/prover/protocol/coin" + "github.com/consensys/linea-monorepo/prover/protocol/compiler/permutation" + "github.com/consensys/linea-monorepo/prover/protocol/query" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" +) func IntoGrandProduct(comp *wizard.CompiledIOP) { - panic("unimplemented") + numRounds := comp.NumRounds() + + /* + Handles the lookups and permutations checks + */ + for i := 0; i < numRounds; i++ { + queries := comp.QueriesNoParams.AllKeysAt(i) + for _, qName := range queries { + // Skip if it was already compiled + if comp.QueriesNoParams.IsIgnored(qName) { + continue + } + + switch q_ := comp.QueriesNoParams.Data(qName).(type) { + case query.Permutation: + reducePermutationIntoGrandProduct(comp, q_, i) + } + } + } +} +// The below function does the following: +// 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) +// 2. Tell the prover that they are not needed to be sampled as they are to be fetched from the randomness beacon +func reducePermutationIntoGrandProduct(comp *wizard.CompiledIOP, q query.Permutation, round int) { + var ( + isMultiColumn = len(q.A[0]) > 1 + alpha coin.Info + // beta has to be different for different for different queries for the soundness of z-packing + beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](q, "BETA"), coin.Field) + ) + + if isMultiColumn { + alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](q, "ALPHA"), coin.Field) + } + + // Reduce a permutation query into a GrandProduct query + comp.InsertGrandProduct(round, q.Name(), alpha, beta) + + } diff --git a/prover/protocol/distributed/distributed.go b/prover/protocol/distributed/distributed.go index b4ee11823..8ffec811d 100644 --- a/prover/protocol/distributed/distributed.go +++ b/prover/protocol/distributed/distributed.go @@ -32,7 +32,7 @@ type ModuleDiscoverer interface { // Analyze is responsible for letting the module discoverer compute how to // group best the columns into modules. Analyze(comp *wizard.CompiledIOP) - NbModules() moduleName + NbModules() int ModuleList(comp *wizard.CompiledIOP) []string FindModule(col ifaces.Column) moduleName } @@ -92,6 +92,7 @@ func extractDistModule(comp *wizard.CompiledIOP, disc ModuleDiscoverer, moduleNa panic("unimplemented") } + func aggregator(n int, idsModules []DistributedModule, moduleNames []string) *wizard.CompiledIOP { panic("unimplemented") } diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index 6cf5c37a3..10cd2bcd4 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -629,3 +629,8 @@ func (c *CompiledIOP) RegisterVerifierAction(round int, action VerifierAction) { // switch. c.InsertVerifier(round, action.Run, action.RunGnark) } + +// Register a GrandProduct query for the sub-provers +func (c *CompiledIOP) InsertGrandProduct(round int, name ifaces.QueryID, alpha, beta coin.Info) { + panic("Unimplemented") +} From 3afad761fc7b23c6cf0b75888b8ac90e40c2f96d Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 4 Dec 2024 19:21:55 +0530 Subject: [PATCH 04/21] added grand product query --- .../compiler/permutation/permutation.go | 3 +- prover/protocol/query/grand_product.go | 45 +++++++++++++++++++ prover/protocol/wizard/compiled.go | 10 +++-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 prover/protocol/query/grand_product.go diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index f11ca8469..a18c26d65 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -44,7 +44,8 @@ func reducePermutationIntoGrandProduct(comp *wizard.CompiledIOP, q query.Permuta } // Reduce a permutation query into a GrandProduct query - comp.InsertGrandProduct(round, q.Name(), alpha, beta) + comp.InsertGrandProduct(round, q.Name(), q.A, q.B, alpha, beta) + // Mark the query as ignored } diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go new file mode 100644 index 000000000..f52bac710 --- /dev/null +++ b/prover/protocol/query/grand_product.go @@ -0,0 +1,45 @@ +package query + +import ( + "github.com/consensys/gnark/frontend" + "github.com/consensys/linea-monorepo/prover/protocol/coin" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/symbolic" + "github.com/consensys/linea-monorepo/prover/utils" +) + +type GrandProduct struct { + ID ifaces.QueryID + Numerator [][]ifaces.Column // stores A as multi-column + Denominator [][]ifaces.Column // stores B as multi-column + Alpha coin.Info // randomness for random linear combination in case of multi-column, to be provided by the + // randomness beacon + Beta coin.Info // randomness for the grand product accumulation, to be provided by the + // randomness beacon + Z symbolic.Expression // aimed at storing the expressions (Ai + \beta_i)/(Bi + \beta_i) + Round int +} + +func NewGrandProduct(id ifaces.QueryID, numerator, denominator [][]ifaces.Column, alpha, beta coin.Info, round int) GrandProduct { + return GrandProduct{ + ID: id, + Numerator: numerator, + Denominator: denominator, + Alpha: alpha, + Beta: beta, + Round: round} + +} + +func (g GrandProduct) Name() ifaces.QueryID { + return g.ID +} + +func (g GrandProduct) Check(run ifaces.Runtime) error { + utils.Panic("Unimplemented") + return nil +} + +func (g GrandProduct) CheckGnark(api frontend.API, run ifaces.GnarkRuntime) { + utils.Panic("Unimplemented") +} diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index 10cd2bcd4..3d715771d 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -630,7 +630,11 @@ func (c *CompiledIOP) RegisterVerifierAction(round int, action VerifierAction) { c.InsertVerifier(round, action.Run, action.RunGnark) } -// Register a GrandProduct query for the sub-provers -func (c *CompiledIOP) InsertGrandProduct(round int, name ifaces.QueryID, alpha, beta coin.Info) { - panic("Unimplemented") +// Register a GrandProduct query +func (c *CompiledIOP) InsertGrandProduct(round int, name ifaces.QueryID, numerator, denominator [][]ifaces.Column, alpha, beta coin.Info) query.GrandProduct { + c.assertConsistentRound(round) + q := query.NewGrandProduct(name, numerator, denominator, alpha, beta, round) + // Finally registers the query + c.QueriesParams.AddToRound(round, name, q) + return q } From 9211a6a3208c4574ac9e230aad4e603971f6050c Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 11 Dec 2024 13:29:46 +0530 Subject: [PATCH 05/21] Added initial framework of the grand prod query --- .../compiler/permutation/permutation.go | 107 +++++++++++++++--- prover/protocol/distributed/distributed.go | 34 +----- .../module_discoverer/module_discoverer.go | 12 ++ prover/protocol/query/grand_product.go | 22 ++-- prover/protocol/wizard/compiled.go | 6 +- 5 files changed, 120 insertions(+), 61 deletions(-) create mode 100644 prover/protocol/distributed/module_discoverer/module_discoverer.go diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index a18c26d65..42ca30b7a 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -3,49 +3,128 @@ package permutation import ( "github.com/consensys/linea-monorepo/prover/protocol/coin" "github.com/consensys/linea-monorepo/prover/protocol/compiler/permutation" + "github.com/consensys/linea-monorepo/prover/protocol/distributed" + modulediscoverer "github.com/consensys/linea-monorepo/prover/protocol/distributed/module_discoverer" + "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" + "github.com/consensys/linea-monorepo/prover/symbolic" ) -func IntoGrandProduct(comp *wizard.CompiledIOP) { - numRounds := comp.NumRounds() +/* +The below function does the following: +1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query +2. (ToDo) It adds relevant constraints +*/ +type PermutationIntoGrandProductCtx struct { + numerator *symbolic.Expression // aimed at storing the expressions Ai + \beta_i + denominator *symbolic.Expression // aimed at storing the expressions Bi + \beta_i +} + +// Return a new PermutationIntoGrandProductCtx with numerator and denominator set as symobilc constant 1 +func newPermutationIntoGrandProductCtx() *PermutationIntoGrandProductCtx { + permCtx := PermutationIntoGrandProductCtx{} + permCtx.numerator = symbolic.NewConstant(1) + permCtx.denominator = symbolic.NewConstant(1) + return &permCtx +} +func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, + targetModuleName distributed.ModuleName) { + numRounds := initialComp.NumRounds() + permCtx := newPermutationIntoGrandProductCtx() /* Handles the lookups and permutations checks */ for i := 0; i < numRounds; i++ { - queries := comp.QueriesNoParams.AllKeysAt(i) - for _, qName := range queries { + queries := initialComp.QueriesNoParams.AllKeysAt(i) + for j, qName := range queries { // Skip if it was already compiled - if comp.QueriesNoParams.IsIgnored(qName) { + if initialComp.QueriesNoParams.IsIgnored(qName) { continue } - switch q_ := comp.QueriesNoParams.Data(qName).(type) { + switch q_ := initialComp.QueriesNoParams.Data(qName).(type) { case query.Permutation: - reducePermutationIntoGrandProduct(comp, q_, i) + { + colNameA := modulediscoverer.ModuleDiscoverer(q_.A[0][0]) + colNameB := modulediscoverer.ModuleDiscoverer(q_.B[0][0]) + if colNameA == targetModuleName && colNameB != targetModuleName { + permCtx.push(moduleComp, &q_, i, j, true, false) + } else if colNameA != targetModuleName && colNameB == targetModuleName { + permCtx.push(moduleComp, &q_, i, j, false, false) + } else if colNameA == targetModuleName && colNameB == targetModuleName { + permCtx.push(moduleComp, &q_, i, j, true, true) + } else { + continue + } + } + default: + continue } } } + // Reduce a permutation query into a GrandProduct query + moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(targetModuleName), permCtx.numerator, permCtx.denominator) } + // The below function does the following: // 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) // 2. Tell the prover that they are not needed to be sampled as they are to be fetched from the randomness beacon -func reducePermutationIntoGrandProduct(comp *wizard.CompiledIOP, q query.Permutation, round int) { +func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query.Permutation, round, queryInRound int, isNumerator, isBoth bool) { + /* + Sanity checks : Mark the query as compiled and make sure that + it was not previously compiled. + */ + if comp.QueriesNoParams.MarkAsIgnored(q.ID) { + panic("did not expect that a query no param could be ignored at this stage") + } var ( isMultiColumn = len(q.A[0]) > 1 alpha coin.Info - // beta has to be different for different for different queries for the soundness of z-packing - beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](q, "BETA"), coin.Field) + // beta has to be different for different queries for a perticular round for the soundness of z-packing + beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) ) if isMultiColumn { - alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](q, "ALPHA"), coin.Field) + // alpha has to be different for different queries for a perticular round for the soundness of z-packing + alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) + + } + if isNumerator && !isBoth { + // Take only the numerator + factor := computeFactor(q.A, isMultiColumn, alpha, beta) + p.numerator = symbolic.Mul(p.numerator, factor) + } else if !isNumerator && !isBoth { + // Take only the denominator + factor := computeFactor(q.B, isMultiColumn, alpha, beta) + p.denominator = symbolic.Mul(p.denominator, factor) + } else if isNumerator && isBoth { + // Take both the numerator and the denominator + numFactor := computeFactor(q.A, isMultiColumn, alpha, beta) + denFactor := computeFactor(q.B, isMultiColumn, alpha, beta) + p.numerator = symbolic.Mul(p.numerator, numFactor) + p.denominator = symbolic.Mul(p.denominator, denFactor) + } else if !isNumerator && isBoth { + panic("Invalid case") } - // Reduce a permutation query into a GrandProduct query - comp.InsertGrandProduct(round, q.Name(), q.A, q.B, alpha, beta) - // Mark the query as ignored +} +func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta coin.Info) *symbolic.Expression { + var ( + numFrag = len(aOrB) + factor = symbolic.NewConstant(1) + ) + for frag := range numFrag { + fragFactor := symbolic.NewVariable(aOrB[frag][0]) + if isMultiColumn { + fragFactor = wizardutils.RandLinCombColSymbolic(alpha, aOrB[frag]) + } + fragFactor = symbolic.Add(fragFactor, beta) + factor = symbolic.Mul(factor, fragFactor) + } + return factor } diff --git a/prover/protocol/distributed/distributed.go b/prover/protocol/distributed/distributed.go index 8ffec811d..92db832a5 100644 --- a/prover/protocol/distributed/distributed.go +++ b/prover/protocol/distributed/distributed.go @@ -2,18 +2,11 @@ package distributed import ( "github.com/consensys/linea-monorepo/prover/maths/field" - "github.com/consensys/linea-monorepo/prover/protocol/compiler/mimc" - "github.com/consensys/linea-monorepo/prover/protocol/compiler/specialqueries" - "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/global" - "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/inclusion" - "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/local" - "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/permutation" - "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/projection" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) -type moduleName = string +type ModuleName = string type DistributedWizard struct { Bootstrapper *wizard.CompiledIOP @@ -33,8 +26,8 @@ type ModuleDiscoverer interface { // group best the columns into modules. Analyze(comp *wizard.CompiledIOP) NbModules() int - ModuleList(comp *wizard.CompiledIOP) []string - FindModule(col ifaces.Column) moduleName + ModuleList(comp *wizard.CompiledIOP) []ModuleName + FindModule(col ifaces.Column) ModuleName } // This transforms the initial wizard. So it is not really the initial @@ -42,10 +35,6 @@ type ModuleDiscoverer interface { // after calling the function. // maxNbSegment is a large max for the number of segments in a module. func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer, maxNbSegments int) DistributedWizard { - - // prepare the initialWizard for the distribution. e.g., - // adding auxiliary columns or dividing a lookup query to two queries one over T and the other over S. - prepare(initialWizard) // it updates the map of Modules-Columns (that is a field of initialWizard). disc.Analyze(initialWizard) @@ -70,29 +59,14 @@ func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer, maxNbS } } -// It adds the compilation steps -func prepare(comp *wizard.CompiledIOP) { - - mimc.CompileMiMC(comp) - specialqueries.RangeProof(comp) - specialqueries.CompileFixedPermutations(comp) - - inclusion.IntoLogDerivativeSum(comp) - permutation.IntoGrandProduct(comp) - projection.IntoGrandSum(comp) - local.IntoDistributedLocal(comp) - global.IntoDistributedGlobal(comp) -} - func addSplittingStep(comp *wizard.CompiledIOP, disc ModuleDiscoverer) { panic("unimplemented") } -func extractDistModule(comp *wizard.CompiledIOP, disc ModuleDiscoverer, moduleName moduleName) DistributedModule { +func extractDistModule(comp *wizard.CompiledIOP, disc ModuleDiscoverer, moduleName ModuleName) DistributedModule { panic("unimplemented") } - func aggregator(n int, idsModules []DistributedModule, moduleNames []string) *wizard.CompiledIOP { panic("unimplemented") } diff --git a/prover/protocol/distributed/module_discoverer/module_discoverer.go b/prover/protocol/distributed/module_discoverer/module_discoverer.go new file mode 100644 index 000000000..1a79bd470 --- /dev/null +++ b/prover/protocol/distributed/module_discoverer/module_discoverer.go @@ -0,0 +1,12 @@ +package modulediscoverer + +import ( + "github.com/consensys/linea-monorepo/prover/protocol/distributed" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" +) + +// This function extract the module name of a given column by +// seperating the string that appear before the first period +func ModuleDiscoverer(col ifaces.Column) distributed.ModuleName { + panic("unimplemented") +} diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index f52bac710..e3c0c471f 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -2,33 +2,27 @@ package query import ( "github.com/consensys/gnark/frontend" - "github.com/consensys/linea-monorepo/prover/protocol/coin" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" ) +// The GrandProduct query enables splitting of the Permutation query between sub-provers +// by splitting the grand product Z = \prod(A_i+\beta)/(B_i+\beta) itself. type GrandProduct struct { ID ifaces.QueryID - Numerator [][]ifaces.Column // stores A as multi-column - Denominator [][]ifaces.Column // stores B as multi-column - Alpha coin.Info // randomness for random linear combination in case of multi-column, to be provided by the - // randomness beacon - Beta coin.Info // randomness for the grand product accumulation, to be provided by the - // randomness beacon - Z symbolic.Expression // aimed at storing the expressions (Ai + \beta_i)/(Bi + \beta_i) - Round int + Numerator *symbolic.Expression // stores A as multi-column + Denominator *symbolic.Expression // stores B as multi-column + Round int } -func NewGrandProduct(id ifaces.QueryID, numerator, denominator [][]ifaces.Column, alpha, beta coin.Info, round int) GrandProduct { +func NewGrandProduct(round int, id ifaces.QueryID, numerator, denominator *symbolic.Expression) GrandProduct { return GrandProduct{ ID: id, Numerator: numerator, Denominator: denominator, - Alpha: alpha, - Beta: beta, - Round: round} - + Round: round, + } } func (g GrandProduct) Name() ifaces.QueryID { diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index 3d715771d..9c9c8bd17 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -631,10 +631,10 @@ func (c *CompiledIOP) RegisterVerifierAction(round int, action VerifierAction) { } // Register a GrandProduct query -func (c *CompiledIOP) InsertGrandProduct(round int, name ifaces.QueryID, numerator, denominator [][]ifaces.Column, alpha, beta coin.Info) query.GrandProduct { +func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, numerator, denominator *symbolic.Expression) query.GrandProduct { c.assertConsistentRound(round) - q := query.NewGrandProduct(name, numerator, denominator, alpha, beta, round) + q := query.NewGrandProduct(round, id, numerator, denominator) // Finally registers the query - c.QueriesParams.AddToRound(round, name, q) + c.QueriesParams.AddToRound(round, q.Name(), q) return q } From a782abd5aff60131e183dbc4e4dad54668087b2a Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 11 Dec 2024 19:21:39 +0530 Subject: [PATCH 06/21] added list format for num and den --- .../compiler/permutation/permutation.go | 29 ++++++++++--------- .../compiler/permutation/settings.go | 5 ++++ prover/protocol/query/grand_product.go | 10 +++---- prover/protocol/wizard/compiled.go | 4 +-- 4 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 prover/protocol/distributed/compiler/permutation/settings.go diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 42ca30b7a..78f69cc9d 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -18,22 +18,23 @@ The below function does the following: 2. (ToDo) It adds relevant constraints */ type PermutationIntoGrandProductCtx struct { - numerator *symbolic.Expression // aimed at storing the expressions Ai + \beta_i - denominator *symbolic.Expression // aimed at storing the expressions Bi + \beta_i + numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query + denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query } // Return a new PermutationIntoGrandProductCtx with numerator and denominator set as symobilc constant 1 -func newPermutationIntoGrandProductCtx() *PermutationIntoGrandProductCtx { +func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductCtx { permCtx := PermutationIntoGrandProductCtx{} - permCtx.numerator = symbolic.NewConstant(1) - permCtx.denominator = symbolic.NewConstant(1) + permCtx.numerators = make([]*symbolic.Expression, s.maxNumofQueryPerModule) + permCtx.denominators = make([]*symbolic.Expression, s.maxNumofQueryPerModule) return &permCtx } func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, - targetModuleName distributed.ModuleName) { + targetModuleName distributed.ModuleName, + s Settings) { numRounds := initialComp.NumRounds() - permCtx := newPermutationIntoGrandProductCtx() + permCtx := newPermutationIntoGrandProductCtx(s) /* Handles the lookups and permutations checks */ @@ -66,12 +67,12 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } } // Reduce a permutation query into a GrandProduct query - moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(targetModuleName), permCtx.numerator, permCtx.denominator) + moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(targetModuleName), permCtx.numerators, permCtx.denominators) } // The below function does the following: -// 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) -// 2. Tell the prover that they are not needed to be sampled as they are to be fetched from the randomness beacon +// 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) in the compiledIop +// 2. Populates the nemerators and the denominators of the grand product query func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query.Permutation, round, queryInRound int, isNumerator, isBoth bool) { /* Sanity checks : Mark the query as compiled and make sure that @@ -95,17 +96,17 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query if isNumerator && !isBoth { // Take only the numerator factor := computeFactor(q.A, isMultiColumn, alpha, beta) - p.numerator = symbolic.Mul(p.numerator, factor) + p.numerators = append(p.numerators, factor) } else if !isNumerator && !isBoth { // Take only the denominator factor := computeFactor(q.B, isMultiColumn, alpha, beta) - p.denominator = symbolic.Mul(p.denominator, factor) + p.denominators = append(p.denominators, factor) } else if isNumerator && isBoth { // Take both the numerator and the denominator numFactor := computeFactor(q.A, isMultiColumn, alpha, beta) denFactor := computeFactor(q.B, isMultiColumn, alpha, beta) - p.numerator = symbolic.Mul(p.numerator, numFactor) - p.denominator = symbolic.Mul(p.denominator, denFactor) + p.numerators = append(p.numerators, numFactor) + p.denominators = append(p.denominators, denFactor) } else if !isNumerator && isBoth { panic("Invalid case") } diff --git a/prover/protocol/distributed/compiler/permutation/settings.go b/prover/protocol/distributed/compiler/permutation/settings.go new file mode 100644 index 000000000..826d9dafc --- /dev/null +++ b/prover/protocol/distributed/compiler/permutation/settings.go @@ -0,0 +1,5 @@ +package permutation + +type Settings struct { + maxNumofQueryPerModule int +} \ No newline at end of file diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index e3c0c471f..524cac1a7 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -11,16 +11,16 @@ import ( // by splitting the grand product Z = \prod(A_i+\beta)/(B_i+\beta) itself. type GrandProduct struct { ID ifaces.QueryID - Numerator *symbolic.Expression // stores A as multi-column - Denominator *symbolic.Expression // stores B as multi-column + Numerators []*symbolic.Expression // stores A as multi-column + Denominators []*symbolic.Expression // stores B as multi-column Round int } -func NewGrandProduct(round int, id ifaces.QueryID, numerator, denominator *symbolic.Expression) GrandProduct { +func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) GrandProduct { return GrandProduct{ ID: id, - Numerator: numerator, - Denominator: denominator, + Numerators: numerators, + Denominators: denominators, Round: round, } } diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index 9c9c8bd17..b646c6725 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -631,9 +631,9 @@ func (c *CompiledIOP) RegisterVerifierAction(round int, action VerifierAction) { } // Register a GrandProduct query -func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, numerator, denominator *symbolic.Expression) query.GrandProduct { +func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) query.GrandProduct { c.assertConsistentRound(round) - q := query.NewGrandProduct(round, id, numerator, denominator) + q := query.NewGrandProduct(round, id, numerators, denominators) // Finally registers the query c.QueriesParams.AddToRound(round, q.Name(), q) return q From 6e9ac0bc300399c59b04284103b4b30784c7e25a Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Thu, 12 Dec 2024 17:08:13 +0530 Subject: [PATCH 07/21] module discoverer is added --- .../compiler/permutation/permutation.go | 19 ++--- .../module_discoverer/module_discoverer.go | 69 +++++++++++++++++-- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 78f69cc9d..6520dd8ff 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -3,7 +3,6 @@ package permutation import ( "github.com/consensys/linea-monorepo/prover/protocol/coin" "github.com/consensys/linea-monorepo/prover/protocol/compiler/permutation" - "github.com/consensys/linea-monorepo/prover/protocol/distributed" modulediscoverer "github.com/consensys/linea-monorepo/prover/protocol/distributed/module_discoverer" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/query" @@ -15,7 +14,6 @@ import ( /* The below function does the following: 1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query -2. (ToDo) It adds relevant constraints */ type PermutationIntoGrandProductCtx struct { numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query @@ -31,10 +29,13 @@ func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductC } func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, - targetModuleName distributed.ModuleName, + targetModuleName modulediscoverer.ModuleName, s Settings) { numRounds := initialComp.NumRounds() permCtx := newPermutationIntoGrandProductCtx(s) + // Initialise the period separating module discoverer + disc := modulediscoverer.PeriodSeperatingModuleDiscoverer{} + disc.Analyze(initialComp) /* Handles the lookups and permutations checks */ @@ -49,13 +50,13 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, switch q_ := initialComp.QueriesNoParams.Data(qName).(type) { case query.Permutation: { - colNameA := modulediscoverer.ModuleDiscoverer(q_.A[0][0]) - colNameB := modulediscoverer.ModuleDiscoverer(q_.B[0][0]) - if colNameA == targetModuleName && colNameB != targetModuleName { + moduleNameA := disc.FindModule(q_.A[0][0]) + moduleNameB := disc.FindModule(q_.B[0][0]) + if moduleNameA == targetModuleName && moduleNameB != targetModuleName { permCtx.push(moduleComp, &q_, i, j, true, false) - } else if colNameA != targetModuleName && colNameB == targetModuleName { + } else if moduleNameA != targetModuleName && moduleNameB == targetModuleName { permCtx.push(moduleComp, &q_, i, j, false, false) - } else if colNameA == targetModuleName && colNameB == targetModuleName { + } else if moduleNameA == targetModuleName && moduleNameB == targetModuleName { permCtx.push(moduleComp, &q_, i, j, true, true) } else { continue @@ -67,7 +68,7 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } } // Reduce a permutation query into a GrandProduct query - moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(targetModuleName), permCtx.numerators, permCtx.denominators) + moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(string(targetModuleName)), permCtx.numerators, permCtx.denominators) } // The below function does the following: diff --git a/prover/protocol/distributed/module_discoverer/module_discoverer.go b/prover/protocol/distributed/module_discoverer/module_discoverer.go index 1a79bd470..88f343107 100644 --- a/prover/protocol/distributed/module_discoverer/module_discoverer.go +++ b/prover/protocol/distributed/module_discoverer/module_discoverer.go @@ -1,12 +1,69 @@ -package modulediscoverer +package distributed import ( - "github.com/consensys/linea-monorepo/prover/protocol/distributed" + "strings" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) -// This function extract the module name of a given column by -// seperating the string that appear before the first period -func ModuleDiscoverer(col ifaces.Column) distributed.ModuleName { - panic("unimplemented") +type ModuleName string + +// Example struct implementing ModuleDiscoverer +type PeriodSeperatingModuleDiscoverer struct { + modules map[ModuleName][]ifaces.Column +} + +// Analyze groups columns into modules +func (p *PeriodSeperatingModuleDiscoverer) Analyze(comp *wizard.CompiledIOP) { + p.modules = make(map[ModuleName][]ifaces.Column) + numRounds := comp.NumRounds() + for i := range numRounds { + for _, col := range comp.Columns.AllHandlesAtRound(i) { // Assume comp.Columns exists + module := periodLogicToDetermineModule(col) + p.modules[module] = append(p.modules[module], col) + } + } +} + +func periodLogicToDetermineModule(col ifaces.Column) ModuleName { + colName := col.GetColID() + return ModuleName(periodSeparator(string(colName))) +} + +func periodSeparator(name string) string { + // Find the index of the first occurrence of a period + index := strings.Index(name, ".") + if index == -1 { + // If no period is found, return the original string + return name + } + // Return the substring before the first period + return name[:index] +} + +// NbModules returns the number of modules +func (p *PeriodSeperatingModuleDiscoverer) NbModules() int { + return len(p.modules) +} + +// ModuleList returns the list of module names +func (p *PeriodSeperatingModuleDiscoverer) ModuleList(comp *wizard.CompiledIOP) []ModuleName { + moduleNames := make([]ModuleName, 0, len(p.modules)) + for moduleName := range p.modules { + moduleNames = append(moduleNames, moduleName) + } + return moduleNames +} + +// FindModule finds the module name for a given column +func (p *PeriodSeperatingModuleDiscoverer) FindModule(col ifaces.Column) ModuleName { + for moduleName, columns := range p.modules { + for _, c := range columns { + if c == col { + return moduleName + } + } + } + return "no column found" // Return a default or error value } From 4f3fe256e58b1f2e740b76de5de88cfd8ca25cda Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Fri, 13 Dec 2024 15:52:12 +0530 Subject: [PATCH 08/21] added a test, not working yet --- prover/protocol/query/grand_product.go | 28 +++++++++--- prover/protocol/query/grand_product_test.go | 47 +++++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 prover/protocol/query/grand_product_test.go diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index 524cac1a7..c3fa7f1dc 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -1,6 +1,8 @@ package query import ( + "fmt" + "github.com/consensys/gnark/frontend" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/symbolic" @@ -10,18 +12,18 @@ import ( // The GrandProduct query enables splitting of the Permutation query between sub-provers // by splitting the grand product Z = \prod(A_i+\beta)/(B_i+\beta) itself. type GrandProduct struct { - ID ifaces.QueryID + ID ifaces.QueryID Numerators []*symbolic.Expression // stores A as multi-column Denominators []*symbolic.Expression // stores B as multi-column - Round int + Round int } func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) GrandProduct { return GrandProduct{ - ID: id, + ID: id, Numerators: numerators, Denominators: denominators, - Round: round, + Round: round, } } @@ -30,7 +32,23 @@ func (g GrandProduct) Name() ifaces.QueryID { } func (g GrandProduct) Check(run ifaces.Runtime) error { - utils.Panic("Unimplemented") + var ( + numNumerators = len(g.Numerators) + numDenominators = len(g.Denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) + + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, g.Numerators[i]) + } + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, g.Denominators[j]) + } + if numProd != denProd { + return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v", g.ID, numProd, denProd) + } + return nil } diff --git a/prover/protocol/query/grand_product_test.go b/prover/protocol/query/grand_product_test.go new file mode 100644 index 000000000..64402f33e --- /dev/null +++ b/prover/protocol/query/grand_product_test.go @@ -0,0 +1,47 @@ +package query_test + +import ( + "testing" + + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" + "github.com/consensys/linea-monorepo/prover/symbolic" +) + +func TestGrandProduct(t *testing.T) { + + var ( + runS *wizard.ProverRuntime + G ifaces.Query + ) + + define := func(builder *wizard.Builder) { + A := []*symbolic.Expression{ + symbolic.NewConstant(1), + symbolic.NewConstant(2), + symbolic.NewConstant(3), + symbolic.NewConstant(4), + } + B := []*symbolic.Expression{ + symbolic.NewConstant(4), + symbolic.NewConstant(3), + symbolic.NewConstant(2), + symbolic.NewConstant(1), + } + G = builder.CompiledIOP.InsertGrandProduct(0, "G", A, B) + } + + prove := func(run *wizard.ProverRuntime) { + runS = run + } + + var ( + comp = wizard.Compile(define) + _ = wizard.Prove(comp, prove) + errG = G.Check(runS) + ) + + if errG != nil { + t.Fatalf("error verifying the grand product: %v", errG.Error()) + } +} From 8d80e1f18e5783c0f170a064c76f9181755d4c55 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Mon, 16 Dec 2024 12:23:28 +0530 Subject: [PATCH 09/21] pushing a wip change on Check() --- prover/protocol/query/grand_product.go | 27 +++++++++++++++++---- prover/protocol/query/grand_product_test.go | 2 ++ prover/protocol/wizard/prover.go | 18 ++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index c3fa7f1dc..1c49c937a 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -1,9 +1,9 @@ package query import ( - "fmt" - "github.com/consensys/gnark/frontend" + "github.com/consensys/linea-monorepo/prover/crypto/fiatshamir" + "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -18,6 +18,10 @@ type GrandProduct struct { Round int } +type GrandProductParams struct { + Y field.Element +} + func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) GrandProduct { return GrandProduct{ ID: id, @@ -27,10 +31,20 @@ func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*s } } +// Constructor for grand product query parameters +func NewGrandProductParams(y field.Element) GrandProductParams { + return GrandProductParams{Y: y} +} + func (g GrandProduct) Name() ifaces.QueryID { return g.ID } +// Updates a Fiat-Shamir state +func (gp GrandProductParams) UpdateFS(fs *fiatshamir.State) { + fs.Update(gp.Y) +} + func (g GrandProduct) Check(run ifaces.Runtime) error { var ( numNumerators = len(g.Numerators) @@ -45,9 +59,12 @@ func (g GrandProduct) Check(run ifaces.Runtime) error { for j := 0; j < numDenominators; j++ { denProd = symbolic.Mul(denProd, g.Denominators[j]) } - if numProd != denProd { - return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v", g.ID, numProd, denProd) - } + // params := run.GetParams(g.ID).(GrandProductParams) + // numProdWit := wizardutils.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + // denProdWit := wizardutils.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + // if numProdWit != denProdWit*params.Y { + // return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, witness = %v", g.ID, numProdWit, denProdWit, params.Y) + // } return nil } diff --git a/prover/protocol/query/grand_product_test.go b/prover/protocol/query/grand_product_test.go index 64402f33e..20ecb270c 100644 --- a/prover/protocol/query/grand_product_test.go +++ b/prover/protocol/query/grand_product_test.go @@ -3,6 +3,7 @@ package query_test import ( "testing" + "github.com/consensys/linea-monorepo/prover/maths/field" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/symbolic" @@ -33,6 +34,7 @@ func TestGrandProduct(t *testing.T) { prove := func(run *wizard.ProverRuntime) { runS = run + runS.AssignGrandProduct("G", field.One()) } var ( diff --git a/prover/protocol/wizard/prover.go b/prover/protocol/wizard/prover.go index caa4df4aa..643f97269 100644 --- a/prover/protocol/wizard/prover.go +++ b/prover/protocol/wizard/prover.go @@ -696,3 +696,21 @@ func (run *ProverRuntime) GetLocalPointEvalParams(name ifaces.QueryID) query.Loc func (run *ProverRuntime) GetParams(name ifaces.QueryID) ifaces.QueryParams { return run.QueriesParams.MustGet(name) } + +// AssignGrandProduct assigns the value \prod(num)/\prod(den) +// - the parameters were already assigned +// - the specified query is not registered +// - the assignment round is incorrect +func (run *ProverRuntime) AssignGrandProduct(name ifaces.QueryID, y field.Element) { + + // Global prover locks for accessing the maps + run.lock.Lock() + defer run.lock.Unlock() + + // Make sure, it is done at the right round + run.Spec.QueriesParams.MustBeInRound(run.currRound, name) + + // Adds it to the assignments + params := query.NewGrandProductParams(y) + run.QueriesParams.InsertNew(name, params) +} From 898aef61a7e97209d0afa988fc399f038ab12b84 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Mon, 16 Dec 2024 18:29:22 +0530 Subject: [PATCH 10/21] Check test works --- prover/protocol/column/column.go | 81 +++++++++++++++++++ prover/protocol/compiler/globalcs/merging.go | 4 +- .../protocol/compiler/innerproduct/prover.go | 4 +- prover/protocol/compiler/lookup/prover.go | 5 +- prover/protocol/compiler/mimc/manual.go | 3 +- .../protocol/compiler/permutation/prover.go | 6 +- .../protocol/dedicated/bigrange/bigrange.go | 3 +- .../protocol/dedicated/byte32cmp/decompose.go | 2 +- .../dedicated/byte32cmp/multi_limb_cmp.go | 3 +- .../dedicated/expr_handle/expr_handle.go | 3 +- prover/protocol/dedicated/is_zero.go | 7 +- .../dedicated/projection/projection.go | 4 +- .../compiler/permutation/permutation.go | 2 +- .../compiler/permutation/permutation_test.go | 34 ++++++++ .../compiler/permutation/settings.go | 2 +- prover/protocol/query/grand_product.go | 33 +++++--- prover/protocol/query/grand_product_test.go | 21 +++-- prover/protocol/wizard/compiled.go | 2 +- prover/protocol/wizard/prover.go | 1 + prover/protocol/wizardutils/evaluation.go | 40 --------- prover/protocol/wizardutils/utils.go | 41 +--------- .../protocol/wizardutils/wizardutils_test.go | 9 ++- 22 files changed, 188 insertions(+), 122 deletions(-) create mode 100644 prover/protocol/distributed/compiler/permutation/permutation_test.go diff --git a/prover/protocol/column/column.go b/prover/protocol/column/column.go index 3df39cfee..906bf9102 100644 --- a/prover/protocol/column/column.go +++ b/prover/protocol/column/column.go @@ -3,7 +3,11 @@ package column import ( "reflect" + "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" + "github.com/consensys/linea-monorepo/prover/protocol/coin" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/variables" + "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" ) @@ -91,3 +95,80 @@ func NbLeaves(h ifaces.Column) int { } panic("unreachable") } + +// EvalExprColumn resolves an expression to a column assignment. The expression +// must be converted to a board prior to evaluating the expression. +// +// - If the expression does not uses ifaces.Column as metadata, the function +// will panic. +// +// - If the expression contains several columns and they don't contain all +// have the same size. +func EvalExprColumn(run ifaces.Runtime, board symbolic.ExpressionBoard) smartvectors.SmartVector { + + var ( + metadata = board.ListVariableMetadata() + inputs = make([]smartvectors.SmartVector, len(metadata)) + length = ExprIsOnSameLengthHandles(&board) + ) + + // Attempt to recover the size of the + for i := range inputs { + switch m := metadata[i].(type) { + case ifaces.Column: + inputs[i] = m.GetColAssignment(run) + case coin.Info: + v := run.GetRandomCoinField(m.Name) + inputs[i] = smartvectors.NewConstant(v, length) + case ifaces.Accessor: + v := m.GetVal(run) + inputs[i] = smartvectors.NewConstant(v, length) + case variables.PeriodicSample: + v := m.EvalCoset(length, 0, 1, false) + inputs[i] = v + case variables.X: + v := m.EvalCoset(length, 0, 1, false) + inputs[i] = v + } + } + + return board.Evaluate(inputs) +} + +// ExprIsOnSameLengthHandles checks that all the variables of the expression +// that are [ifaces.Column] have the same size (and panics if it does not), then +// returns the match. +func ExprIsOnSameLengthHandles(board *symbolic.ExpressionBoard) int { + + var ( + metadatas = board.ListVariableMetadata() + length = 0 + ) + + for _, m := range metadatas { + switch metadata := m.(type) { + case ifaces.Column: + // Initialize the length with the first commitment + if length == 0 { + length = metadata.Size() + } + + // Sanity-check the vector should all have the same length + if length != metadata.Size() { + utils.Panic("Inconsistent length for %v (has size %v, but expected %v)", metadata.GetColID(), metadata.Size(), length) + } + // The expression can involve random coins + case coin.Info, variables.X, variables.PeriodicSample, ifaces.Accessor: + // Do nothing + default: + utils.Panic("unknown type %T", metadata) + } + } + + // No commitment were found in the metadata, thus this call is broken + if length == 0 { + utils.Panic("declared a handle from an expression which does not contains any handle") + } + + return length +} diff --git a/prover/protocol/compiler/globalcs/merging.go b/prover/protocol/compiler/globalcs/merging.go index f7b04c453..8d6e22b0b 100644 --- a/prover/protocol/compiler/globalcs/merging.go +++ b/prover/protocol/compiler/globalcs/merging.go @@ -7,11 +7,11 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/fft" "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/variables" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/symbolic" "github.com/consensys/linea-monorepo/prover/utils" ) @@ -178,7 +178,7 @@ func getBoundCancelledExpression(cs query.GlobalConstraint) *symbolic.Expression func getExprRatio(expr *symbolic.Expression) int { var ( board = expr.Board() - domainSize = wizardutils.ExprIsOnSameLengthHandles(&board) + domainSize = column.ExprIsOnSameLengthHandles(&board) exprDegree = board.Degree(GetDegree(domainSize)) quotientSize = exprDegree - domainSize + 1 ratio = utils.DivCeil(quotientSize, domainSize) diff --git a/prover/protocol/compiler/innerproduct/prover.go b/prover/protocol/compiler/innerproduct/prover.go index 6cc508b23..41ed30887 100644 --- a/prover/protocol/compiler/innerproduct/prover.go +++ b/prover/protocol/compiler/innerproduct/prover.go @@ -5,8 +5,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/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" ) // proverTask implements the [wizard.ProverAction] interface and as such @@ -39,7 +39,7 @@ func (ctx *contextForSize) run(run *wizard.ProverRuntime) { var ( size = ctx.Summation.Size() - collapsed = wizardutils.EvalExprColumn(run, ctx.CollapsedBoard).IntoRegVecSaveAlloc() + collapsed = column.EvalExprColumn(run, ctx.CollapsedBoard).IntoRegVecSaveAlloc() summation = make([]field.Element, size) ) diff --git a/prover/protocol/compiler/lookup/prover.go b/prover/protocol/compiler/lookup/prover.go index 063fa5a6b..72d5b6474 100644 --- a/prover/protocol/compiler/lookup/prover.go +++ b/prover/protocol/compiler/lookup/prover.go @@ -7,6 +7,7 @@ import ( sv "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" + "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" @@ -308,7 +309,7 @@ func (z zAssignmentTask) run(run *wizard.ProverRuntime) { var ( numeratorMetadata = z.ZNumeratorBoarded[frag].ListVariableMetadata() - denominator = wizardutils.EvalExprColumn(run, z.ZDenominatorBoarded[frag]).IntoRegVecSaveAlloc() + denominator = column.EvalExprColumn(run, z.ZDenominatorBoarded[frag]).IntoRegVecSaveAlloc() numerator []field.Element packedZ = field.BatchInvert(denominator) ) @@ -318,7 +319,7 @@ func (z zAssignmentTask) run(run *wizard.ProverRuntime) { } if len(numeratorMetadata) > 0 { - numerator = wizardutils.EvalExprColumn(run, z.ZNumeratorBoarded[frag]).IntoRegVecSaveAlloc() + numerator = column.EvalExprColumn(run, z.ZNumeratorBoarded[frag]).IntoRegVecSaveAlloc() } for k := range packedZ { diff --git a/prover/protocol/compiler/mimc/manual.go b/prover/protocol/compiler/mimc/manual.go index a204392ab..50885feb6 100644 --- a/prover/protocol/compiler/mimc/manual.go +++ b/prover/protocol/compiler/mimc/manual.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/consensys/linea-monorepo/prover/crypto/mimc" + "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" @@ -155,7 +156,7 @@ func mimcExprHandle(comp *wizard.CompiledIOP, expr *symbolic.Expression, name .. maxRound := wizardutils.LastRoundToEval(expr) board := expr.Board() - length := wizardutils.ExprIsOnSameLengthHandles(&board) + length := column.ExprIsOnSameLengthHandles(&board) handleName := fmt.Sprintf("SYMBOLIC_%v", expr.ESHash.String()) if len(name) > 0 { diff --git a/prover/protocol/compiler/permutation/prover.go b/prover/protocol/compiler/permutation/prover.go index ab5d0e79a..190da0ce2 100644 --- a/prover/protocol/compiler/permutation/prover.go +++ b/prover/protocol/compiler/permutation/prover.go @@ -6,8 +6,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" + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/wizard" - "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" ) // proverTaskAtRound implements the [wizard.ProverAction] interface and is @@ -48,13 +48,13 @@ func (z *ZCtx) run(run *wizard.ProverRuntime) { ) if packingArity*i < len(z.NumeratorFactors) { - numerator = wizardutils.EvalExprColumn(run, z.NumeratorFactorsBoarded[i]).IntoRegVecSaveAlloc() + numerator = column.EvalExprColumn(run, z.NumeratorFactorsBoarded[i]).IntoRegVecSaveAlloc() } else { numerator = vector.Repeat(field.One(), z.Size) } if packingArity*i < len(z.DenominatorFactors) { - denominator = wizardutils.EvalExprColumn(run, z.DenominatorFactorsBoarded[i]).IntoRegVecSaveAlloc() + denominator = column.EvalExprColumn(run, z.DenominatorFactorsBoarded[i]).IntoRegVecSaveAlloc() } else { denominator = vector.Repeat(field.One(), z.Size) } diff --git a/prover/protocol/dedicated/bigrange/bigrange.go b/prover/protocol/dedicated/bigrange/bigrange.go index 60244ca90..c5192a819 100644 --- a/prover/protocol/dedicated/bigrange/bigrange.go +++ b/prover/protocol/dedicated/bigrange/bigrange.go @@ -11,6 +11,7 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/fft" "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/variables" "github.com/consensys/linea-monorepo/prover/protocol/wizard" @@ -41,7 +42,7 @@ func BigRange(comp *wizard.CompiledIOP, expr *symbolic.Expression, numLimbs, bit limbs = make([]ifaces.Column, numLimbs) round = wizardutils.LastRoundToEval(expr) boarded = expr.Board() - size = wizardutils.ExprIsOnSameLengthHandles(&boarded) + size = column.ExprIsOnSameLengthHandles(&boarded) totalNumBits = numLimbs * bitPerLimbs ) diff --git a/prover/protocol/dedicated/byte32cmp/decompose.go b/prover/protocol/dedicated/byte32cmp/decompose.go index 6058cca73..538412887 100644 --- a/prover/protocol/dedicated/byte32cmp/decompose.go +++ b/prover/protocol/dedicated/byte32cmp/decompose.go @@ -170,7 +170,7 @@ func (d *decompositionCtx) Run(run *wizard.ProverRuntime) { numLimbs = len(d.decomposed.Limbs) bitPerLimbs = d.decomposed.LimbBitSize totalNumBits = numLimbs * bitPerLimbs - original = wizardutils.EvalExprColumn(run, d.original) + original = column.EvalExprColumn(run, d.original) limbsWitness = make([][]field.Element, numLimbs) size = original.Len() ) diff --git a/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go b/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go index 8ff17c5a6..35d96e11d 100644 --- a/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go +++ b/prover/protocol/dedicated/byte32cmp/multi_limb_cmp.go @@ -6,6 +6,7 @@ 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" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" @@ -192,7 +193,7 @@ func (mCmp *multiLimbCmp) Run(run *wizard.ProverRuntime) { }() var ( - syndrom = wizardutils.EvalExprColumn(run, mCmp.syndromBoard) + syndrom = column.EvalExprColumn(run, mCmp.syndromBoard) isGreater = make([]field.Element, mCmp.isGreater.Size()) isLower = make([]field.Element, mCmp.isLower.Size()) nnSyndrom = make([]field.Element, mCmp.isLower.Size()) diff --git a/prover/protocol/dedicated/expr_handle/expr_handle.go b/prover/protocol/dedicated/expr_handle/expr_handle.go index 4e72c2259..7e72eae06 100644 --- a/prover/protocol/dedicated/expr_handle/expr_handle.go +++ b/prover/protocol/dedicated/expr_handle/expr_handle.go @@ -8,6 +8,7 @@ import ( "github.com/consensys/linea-monorepo/prover/maths/fft" "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/variables" "github.com/consensys/linea-monorepo/prover/protocol/wizard" @@ -25,7 +26,7 @@ func ExprHandle(comp *wizard.CompiledIOP, expr *symbolic.Expression, name ...str var ( boarded = expr.Board() maxRound = wizardutils.LastRoundToEval(expr) - length = wizardutils.ExprIsOnSameLengthHandles(&boarded) + length = column.ExprIsOnSameLengthHandles(&boarded) handleName = fmt.Sprintf("SYMBOLIC_%v", expr.ESHash.String()) ) diff --git a/prover/protocol/dedicated/is_zero.go b/prover/protocol/dedicated/is_zero.go index 208886c7f..68df50089 100644 --- a/prover/protocol/dedicated/is_zero.go +++ b/prover/protocol/dedicated/is_zero.go @@ -2,6 +2,7 @@ package dedicated import ( "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" + "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" @@ -44,7 +45,7 @@ func IsZero(comp *wizard.CompiledIOP, c any) (ifaces.Column, wizard.ProverAction case *sym.Expression: board := c1.Board() ctx.c = c1 - ctx.size = wizardutils.ExprIsOnSameLengthHandles(&board) + ctx.size = column.ExprIsOnSameLengthHandles(&board) ctx.round = wizardutils.LastRoundToEval(c1) } @@ -123,13 +124,13 @@ func compileIsZeroWithSize(comp *wizard.CompiledIOP, ctx *isZeroCtx) { // Run implements the [wizard.ProverAction] interface func (ctx *isZeroCtx) Run(run *wizard.ProverRuntime) { var ( - c = wizardutils.EvalExprColumn(run, ctx.c.Board()) + c = column.EvalExprColumn(run, ctx.c.Board()) invOrZero = smartvectors.BatchInvert(c) isZero = smartvectors.IsZero(c) ) if ctx.mask != nil { - mask := wizardutils.EvalExprColumn(run, ctx.mask.Board()) + mask := column.EvalExprColumn(run, ctx.mask.Board()) invOrZero = smartvectors.Mul(invOrZero, mask) isZero = smartvectors.Mul(isZero, mask) } diff --git a/prover/protocol/dedicated/projection/projection.go b/prover/protocol/dedicated/projection/projection.go index efa137fb4..8141e01da 100644 --- a/prover/protocol/dedicated/projection/projection.go +++ b/prover/protocol/dedicated/projection/projection.go @@ -219,8 +219,8 @@ func InsertProjection( func (pa projectionProverAction) Run(run *wizard.ProverRuntime) { var ( - a = wizardutils.EvalExprColumn(run, pa.ABoard).IntoRegVecSaveAlloc() - b = wizardutils.EvalExprColumn(run, pa.BBoard).IntoRegVecSaveAlloc() + 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) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 6520dd8ff..844f5d599 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -1,4 +1,4 @@ -package permutation +package dist_permutation import ( "github.com/consensys/linea-monorepo/prover/protocol/coin" diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go new file mode 100644 index 000000000..5b5bdf047 --- /dev/null +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -0,0 +1,34 @@ +package dist_permutation_test + +import ( + "testing" +) + +func TestDistPermutation(t *testing.T) { + + // define := func(builder *wizard.Builder) { + // A := []ifaces.Column{ + // builder.RegisterCommit("modExp.A0", 4), + // builder.RegisterCommit("modExp.A1", 4), + // builder.RegisterCommit("modExp.A2", 4), + // } + // B := []ifaces.Column{ + // builder.RegisterCommit("rom.B0", 4), + // builder.RegisterCommit("rom.B1", 4), + // builder.RegisterCommit("rom.B2", 4), + // } + // C := []ifaces.Column{ + // builder.RegisterCommit("romLex.C0", 4), + // builder.RegisterCommit("romLex.C1", 4), + // builder.RegisterCommit("romLex.C2", 4), + // } + // _ = builder.CompiledIOP.InsertPermutation(0, "P_MODEXP_ROM", A, B) + // _ = builder.CompiledIOP.InsertPermutation(0, "P_ROMLEX_MODEXP", C, A) + // _ = builder.CompiledIOP.InsertPermutation(0, "P_ROM_ROMLEX", B, C) + // } + + // initialComp := wizard.Compile(define) + // moduleCompModExp := wizard.CompiledIOP{} + // dist_permutation.AddGdProductQuery() + +} diff --git a/prover/protocol/distributed/compiler/permutation/settings.go b/prover/protocol/distributed/compiler/permutation/settings.go index 826d9dafc..79309cfe7 100644 --- a/prover/protocol/distributed/compiler/permutation/settings.go +++ b/prover/protocol/distributed/compiler/permutation/settings.go @@ -1,4 +1,4 @@ -package permutation +package dist_permutation type Settings struct { maxNumofQueryPerModule int diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index 1c49c937a..48c8be993 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -1,9 +1,12 @@ package query import ( + "fmt" + "github.com/consensys/gnark/frontend" "github.com/consensys/linea-monorepo/prover/crypto/fiatshamir" "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/symbolic" "github.com/consensys/linea-monorepo/prover/utils" @@ -22,8 +25,8 @@ type GrandProductParams struct { Y field.Element } -func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) GrandProduct { - return GrandProduct{ +func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) *GrandProduct { + return &GrandProduct{ ID: id, Numerators: numerators, Denominators: denominators, @@ -45,7 +48,7 @@ func (gp GrandProductParams) UpdateFS(fs *fiatshamir.State) { fs.Update(gp.Y) } -func (g GrandProduct) Check(run ifaces.Runtime) error { +func (g *GrandProduct) Check(run ifaces.Runtime) error { var ( numNumerators = len(g.Numerators) numDenominators = len(g.Denominators) @@ -59,12 +62,24 @@ func (g GrandProduct) Check(run ifaces.Runtime) error { for j := 0; j < numDenominators; j++ { denProd = symbolic.Mul(denProd, g.Denominators[j]) } - // params := run.GetParams(g.ID).(GrandProductParams) - // numProdWit := wizardutils.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() - // denProdWit := wizardutils.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() - // if numProdWit != denProdWit*params.Y { - // return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, witness = %v", g.ID, numProdWit, denProdWit, params.Y) - // } + params := run.GetParams(g.ID).(GrandProductParams) + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + if len(numProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { + return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, witness = %v", g.ID, numProdFr, denProdFr, params.Y) + } return nil } diff --git a/prover/protocol/query/grand_product_test.go b/prover/protocol/query/grand_product_test.go index 20ecb270c..4501c2e62 100644 --- a/prover/protocol/query/grand_product_test.go +++ b/prover/protocol/query/grand_product_test.go @@ -3,6 +3,7 @@ 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/wizard" @@ -17,23 +18,27 @@ func TestGrandProduct(t *testing.T) { ) define := func(builder *wizard.Builder) { + A0 := builder.RegisterCommit("A0", 4) + B0 := builder.RegisterCommit("B0", 4) + C0 := builder.RegisterCommit("C0", 4) A := []*symbolic.Expression{ - symbolic.NewConstant(1), - symbolic.NewConstant(2), - symbolic.NewConstant(3), - symbolic.NewConstant(4), + symbolic.Add(A0, B0), + symbolic.Add(B0, C0), + symbolic.Add(C0, A0), } B := []*symbolic.Expression{ - symbolic.NewConstant(4), - symbolic.NewConstant(3), - symbolic.NewConstant(2), - symbolic.NewConstant(1), + symbolic.Add(C0, A0), + symbolic.Add(B0, C0), + symbolic.Add(A0, B0), } G = builder.CompiledIOP.InsertGrandProduct(0, "G", A, B) } prove := func(run *wizard.ProverRuntime) { runS = run + run.AssignColumn("A0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("B0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("C0", smartvectors.ForTest(1, 2, 3, 4)) runS.AssignGrandProduct("G", field.One()) } diff --git a/prover/protocol/wizard/compiled.go b/prover/protocol/wizard/compiled.go index b646c6725..ff65bd675 100644 --- a/prover/protocol/wizard/compiled.go +++ b/prover/protocol/wizard/compiled.go @@ -631,7 +631,7 @@ func (c *CompiledIOP) RegisterVerifierAction(round int, action VerifierAction) { } // Register a GrandProduct query -func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) query.GrandProduct { +func (c *CompiledIOP) InsertGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) *query.GrandProduct { c.assertConsistentRound(round) q := query.NewGrandProduct(round, id, numerators, denominators) // Finally registers the query diff --git a/prover/protocol/wizard/prover.go b/prover/protocol/wizard/prover.go index 643f97269..dbbbeddc3 100644 --- a/prover/protocol/wizard/prover.go +++ b/prover/protocol/wizard/prover.go @@ -698,6 +698,7 @@ func (run *ProverRuntime) GetParams(name ifaces.QueryID) ifaces.QueryParams { } // AssignGrandProduct assigns the value \prod(num)/\prod(den) +// The function will panic if: // - the parameters were already assigned // - the specified query is not registered // - the assignment round is incorrect diff --git a/prover/protocol/wizardutils/evaluation.go b/prover/protocol/wizardutils/evaluation.go index 7381060ac..a3b93acc8 100644 --- a/prover/protocol/wizardutils/evaluation.go +++ b/prover/protocol/wizardutils/evaluation.go @@ -5,50 +5,10 @@ import ( "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/variables" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/symbolic" ) -// EvalExprColumn resolves an expression to a column assignment. The expression -// must be converted to a board prior to evaluating the expression. -// -// - If the expression does not uses ifaces.Column as metadata, the function -// will panic. -// -// - If the expression contains several columns and they don't contain all -// have the same size. -func EvalExprColumn(run *wizard.ProverRuntime, board symbolic.ExpressionBoard) smartvectors.SmartVector { - - var ( - metadata = board.ListVariableMetadata() - inputs = make([]smartvectors.SmartVector, len(metadata)) - length = ExprIsOnSameLengthHandles(&board) - ) - - // Attempt to recover the size of the - for i := range inputs { - switch m := metadata[i].(type) { - case ifaces.Column: - inputs[i] = m.GetColAssignment(run) - case coin.Info: - v := run.GetRandomCoinField(m.Name) - inputs[i] = smartvectors.NewConstant(v, length) - case ifaces.Accessor: - v := m.GetVal(run) - inputs[i] = smartvectors.NewConstant(v, length) - case variables.PeriodicSample: - v := m.EvalCoset(length, 0, 1, false) - inputs[i] = v - case variables.X: - v := m.EvalCoset(length, 0, 1, false) - inputs[i] = v - } - } - - return board.Evaluate(inputs) -} - // returns the symbolic expression of a column obtained as a random linear combinations of differents handles // without committing to the column itself func RandLinCombColSymbolic(x coin.Info, hs []ifaces.Column) *symbolic.Expression { diff --git a/prover/protocol/wizardutils/utils.go b/prover/protocol/wizardutils/utils.go index ba58ac339..764092a1f 100644 --- a/prover/protocol/wizardutils/utils.go +++ b/prover/protocol/wizardutils/utils.go @@ -5,6 +5,7 @@ import ( "strings" "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/variables" "github.com/consensys/linea-monorepo/prover/symbolic" @@ -41,44 +42,6 @@ func LastRoundToEval(expr *symbolic.Expression) int { return maxRound } -// ExprIsOnSameLengthHandles checks that all the variables of the expression -// that are [ifaces.Column] have the same size (and panics if it does not), then -// returns the match. -func ExprIsOnSameLengthHandles(board *symbolic.ExpressionBoard) int { - - var ( - metadatas = board.ListVariableMetadata() - length = 0 - ) - - for _, m := range metadatas { - switch metadata := m.(type) { - case ifaces.Column: - // Initialize the length with the first commitment - if length == 0 { - length = metadata.Size() - } - - // Sanity-check the vector should all have the same length - if length != metadata.Size() { - utils.Panic("Inconsistent length for %v (has size %v, but expected %v)", metadata.GetColID(), metadata.Size(), length) - } - // The expression can involve random coins - case coin.Info, variables.X, variables.PeriodicSample, ifaces.Accessor: - // Do nothing - default: - utils.Panic("unknown type %T", metadata) - } - } - - // No commitment were found in the metadata, thus this call is broken - if length == 0 { - utils.Panic("declared a handle from an expression which does not contains any handle") - } - - return length -} - // maximal round of declaration for a list of commitment func MaxRound(handles ...ifaces.Column) int { res := 0 @@ -128,7 +91,7 @@ func AsExpr(x any) (e *symbolic.Expression, round, size int) { case *symbolic.Expression: board := c1.Board() e = c1 - size = ExprIsOnSameLengthHandles(&board) + size = column.ExprIsOnSameLengthHandles(&board) round = LastRoundToEval(c1) return e, round, size } diff --git a/prover/protocol/wizardutils/wizardutils_test.go b/prover/protocol/wizardutils/wizardutils_test.go index 417a0a85a..fd2ac86bc 100644 --- a/prover/protocol/wizardutils/wizardutils_test.go +++ b/prover/protocol/wizardutils/wizardutils_test.go @@ -6,6 +6,7 @@ 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/coin" + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/column/verifiercol" "github.com/consensys/linea-monorepo/prover/protocol/compiler/dummy" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" @@ -48,16 +49,16 @@ func TestWizarldutils(t *testing.T) { run.GetRandomCoinField(coin.Namef("Coin")) - res1Wit := EvalExprColumn(run, res1.Board()).IntoRegVecSaveAlloc() - res11Wit := EvalExprColumn(run, res11.Board()).IntoRegVecSaveAlloc() + res1Wit := column.EvalExprColumn(run, res1.Board()).IntoRegVecSaveAlloc() + res11Wit := column.EvalExprColumn(run, res11.Board()).IntoRegVecSaveAlloc() for i := range res11Wit { if res1Wit[i].Cmp(&res11Wit[i]) != 0 { panic("err") } } - res2Wit := EvalExprColumn(run, res2.Board()).IntoRegVecSaveAlloc() - res22Wit := EvalExprColumn(run, res22.Board()).IntoRegVecSaveAlloc() + res2Wit := column.EvalExprColumn(run, res2.Board()).IntoRegVecSaveAlloc() + res22Wit := column.EvalExprColumn(run, res22.Board()).IntoRegVecSaveAlloc() for i := range res11Wit { if res2Wit[i].Cmp(&res22Wit[i]) != 0 { panic("err") From 28d79e9dc0d8d2a12c3ea554d77c16042703c67b Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Mon, 16 Dec 2024 20:36:13 +0530 Subject: [PATCH 11/21] added test for AddGdProduct --- .../compiler/permutation/permutation.go | 19 ++--- .../compiler/permutation/permutation_test.go | 76 +++++++++++++------ .../compiler/permutation/settings.go | 4 +- 3 files changed, 63 insertions(+), 36 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 844f5d599..0fe838144 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -9,6 +9,7 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/symbolic" + "github.com/sirupsen/logrus" ) /* @@ -23,14 +24,14 @@ type PermutationIntoGrandProductCtx struct { // Return a new PermutationIntoGrandProductCtx with numerator and denominator set as symobilc constant 1 func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductCtx { permCtx := PermutationIntoGrandProductCtx{} - permCtx.numerators = make([]*symbolic.Expression, s.maxNumofQueryPerModule) - permCtx.denominators = make([]*symbolic.Expression, s.maxNumofQueryPerModule) + permCtx.numerators = make([]*symbolic.Expression, s.MaxNumOfQueryPerModule) + permCtx.denominators = make([]*symbolic.Expression, s.MaxNumOfQueryPerModule) return &permCtx } func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, targetModuleName modulediscoverer.ModuleName, - s Settings) { + s Settings) *query.GrandProduct { numRounds := initialComp.NumRounds() permCtx := newPermutationIntoGrandProductCtx(s) // Initialise the period separating module discoverer @@ -52,6 +53,7 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, { moduleNameA := disc.FindModule(q_.A[0][0]) moduleNameB := disc.FindModule(q_.B[0][0]) + logrus.Printf("moduleNameA = %v, moduleNameB = %v", moduleNameA, moduleNameB) if moduleNameA == targetModuleName && moduleNameB != targetModuleName { permCtx.push(moduleComp, &q_, i, j, true, false) } else if moduleNameA != targetModuleName && moduleNameB == targetModuleName { @@ -68,20 +70,15 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } } // Reduce a permutation query into a GrandProduct query - moduleComp.InsertGrandProduct(0, ifaces.QueryIDf(string(targetModuleName)), permCtx.numerators, permCtx.denominators) + qId := ifaces.QueryIDf(string(targetModuleName)+"GRAND_PRODUCT") + return moduleComp.InsertGrandProduct(0, qId, permCtx.numerators, permCtx.denominators) } // The below function does the following: // 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) in the compiledIop // 2. Populates the nemerators and the denominators of the grand product query func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query.Permutation, round, queryInRound int, isNumerator, isBoth bool) { - /* - Sanity checks : Mark the query as compiled and make sure that - it was not previously compiled. - */ - if comp.QueriesNoParams.MarkAsIgnored(q.ID) { - panic("did not expect that a query no param could be ignored at this stage") - } + logrus.Printf("queryInRound %d", queryInRound) var ( isMultiColumn = len(q.A[0]) > 1 alpha coin.Info diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index 5b5bdf047..112dbfa65 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -2,33 +2,63 @@ package dist_permutation_test import ( "testing" + + "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" + "github.com/consensys/linea-monorepo/prover/maths/field" + dist_permutation "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/permutation" + "github.com/consensys/linea-monorepo/prover/protocol/ifaces" + "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) func TestDistPermutation(t *testing.T) { + var ( + runS *wizard.ProverRuntime + G ifaces.Query + ) + + define := func(builder *wizard.Builder) { + A := []ifaces.Column{ + builder.RegisterCommit("modExp.A0", 4), + builder.RegisterCommit("modExp.A1", 4), + builder.RegisterCommit("modExp.A2", 4), + } + B := []ifaces.Column{ + builder.RegisterCommit("rom.B0", 4), + builder.RegisterCommit("rom.B1", 4), + builder.RegisterCommit("rom.B2", 4), + } + C := []ifaces.Column{ + builder.RegisterCommit("romLex.C0", 4), + builder.RegisterCommit("romLex.C1", 4), + builder.RegisterCommit("romLex.C2", 4), + } + _ = builder.CompiledIOP.InsertPermutation(0, "P_MODEXP_ROM", A, B) + _ = builder.CompiledIOP.InsertPermutation(0, "P_ROMLEX_MODEXP", C, A) + _ = builder.CompiledIOP.InsertPermutation(0, "P_ROM_ROMLEX", B, C) + } - // define := func(builder *wizard.Builder) { - // A := []ifaces.Column{ - // builder.RegisterCommit("modExp.A0", 4), - // builder.RegisterCommit("modExp.A1", 4), - // builder.RegisterCommit("modExp.A2", 4), - // } - // B := []ifaces.Column{ - // builder.RegisterCommit("rom.B0", 4), - // builder.RegisterCommit("rom.B1", 4), - // builder.RegisterCommit("rom.B2", 4), - // } - // C := []ifaces.Column{ - // builder.RegisterCommit("romLex.C0", 4), - // builder.RegisterCommit("romLex.C1", 4), - // builder.RegisterCommit("romLex.C2", 4), - // } - // _ = builder.CompiledIOP.InsertPermutation(0, "P_MODEXP_ROM", A, B) - // _ = builder.CompiledIOP.InsertPermutation(0, "P_ROMLEX_MODEXP", C, A) - // _ = builder.CompiledIOP.InsertPermutation(0, "P_ROM_ROMLEX", B, C) - // } + initialComp := wizard.Compile(define) + moduleCompModExp := wizard.Compile(define) + G = dist_permutation.AddGdProductQuery(initialComp, moduleCompModExp, "modExp", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) + prove := func(run *wizard.ProverRuntime) { + runS = run + run.AssignColumn("modExp.A0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("modExp.A1", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("modExp.A2", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("rom.B0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("rom.B1", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("rom.B2", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("romLex.C0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("romLex.C1", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("romLex.C2", smartvectors.ForTest(1, 2, 3, 4)) + runS.AssignGrandProduct("modExp_GRAND_PRODUCT", field.One()) + } + _ = wizard.Prove(initialComp, prove) + _ = wizard.Prove(moduleCompModExp, prove) + errG := G.Check(runS) - // initialComp := wizard.Compile(define) - // moduleCompModExp := wizard.CompiledIOP{} - // dist_permutation.AddGdProductQuery() + if errG != nil { + t.Fatalf("error verifying the grand product: %v", errG.Error()) + } } diff --git a/prover/protocol/distributed/compiler/permutation/settings.go b/prover/protocol/distributed/compiler/permutation/settings.go index 79309cfe7..73e3bf5f2 100644 --- a/prover/protocol/distributed/compiler/permutation/settings.go +++ b/prover/protocol/distributed/compiler/permutation/settings.go @@ -1,5 +1,5 @@ package dist_permutation type Settings struct { - maxNumofQueryPerModule int -} \ No newline at end of file + MaxNumOfQueryPerModule int +} From 26b011421920dba98d5143675af771a1f6fa948a Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Tue, 17 Dec 2024 19:08:06 +0530 Subject: [PATCH 12/21] bug fix added --- .../compiler/permutation/permutation.go | 8 +-- .../compiler/permutation/permutation_test.go | 66 ++++++++----------- .../compiler/permutation/settings.go | 1 + .../module_discoverer/module_discoverer.go | 2 +- prover/protocol/query/grand_product.go | 2 +- 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 0fe838144..9e57f4a54 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -21,7 +21,7 @@ type PermutationIntoGrandProductCtx struct { denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query } -// Return a new PermutationIntoGrandProductCtx with numerator and denominator set as symobilc constant 1 +// Returns a new PermutationIntoGrandProductCtx func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductCtx { permCtx := PermutationIntoGrandProductCtx{} permCtx.numerators = make([]*symbolic.Expression, s.MaxNumOfQueryPerModule) @@ -70,7 +70,7 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } } // Reduce a permutation query into a GrandProduct query - qId := ifaces.QueryIDf(string(targetModuleName)+"GRAND_PRODUCT") + qId := ifaces.QueryIDf(string(targetModuleName) + "_GRAND_PRODUCT") return moduleComp.InsertGrandProduct(0, qId, permCtx.numerators, permCtx.denominators) } @@ -83,12 +83,12 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query isMultiColumn = len(q.A[0]) > 1 alpha coin.Info // beta has to be different for different queries for a perticular round for the soundness of z-packing - beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) + beta = comp.InsertCoin(round, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) ) if isMultiColumn { // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) + alpha = comp.InsertCoin(round, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) } if isNumerator && !isBoth { diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index 112dbfa65..e52d160a4 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -11,54 +11,42 @@ import ( ) func TestDistPermutation(t *testing.T) { - var ( - runS *wizard.ProverRuntime - G ifaces.Query - ) - - define := func(builder *wizard.Builder) { + initialDefine := func(builder *wizard.Builder) { A := []ifaces.Column{ - builder.RegisterCommit("modExp.A0", 4), - builder.RegisterCommit("modExp.A1", 4), - builder.RegisterCommit("modExp.A2", 4), + builder.RegisterCommit("MODULE_A.A0", 4), + builder.RegisterCommit("MODULE_A.A1", 4), + builder.RegisterCommit("MODULE_A.A2", 4), } B := []ifaces.Column{ - builder.RegisterCommit("rom.B0", 4), - builder.RegisterCommit("rom.B1", 4), - builder.RegisterCommit("rom.B2", 4), + builder.RegisterCommit("MODULE_B.B0", 4), + builder.RegisterCommit("MODULE_B.B1", 4), + builder.RegisterCommit("MODULE_B.B2", 4), } C := []ifaces.Column{ - builder.RegisterCommit("romLex.C0", 4), - builder.RegisterCommit("romLex.C1", 4), - builder.RegisterCommit("romLex.C2", 4), + builder.RegisterCommit("MODULE_C.C0", 4), + builder.RegisterCommit("MODULE_C.C1", 4), + builder.RegisterCommit("MODULE_C.C2", 4), } - _ = builder.CompiledIOP.InsertPermutation(0, "P_MODEXP_ROM", A, B) - _ = builder.CompiledIOP.InsertPermutation(0, "P_ROMLEX_MODEXP", C, A) - _ = builder.CompiledIOP.InsertPermutation(0, "P_ROM_ROMLEX", B, C) + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_A_MOD_B", A, B) + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_C_MOD_A", C, A) + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_B_MOD_C", B, C) } - initialComp := wizard.Compile(define) - moduleCompModExp := wizard.Compile(define) - G = dist_permutation.AddGdProductQuery(initialComp, moduleCompModExp, "modExp", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) - prove := func(run *wizard.ProverRuntime) { - runS = run - run.AssignColumn("modExp.A0", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("modExp.A1", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("modExp.A2", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("rom.B0", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("rom.B1", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("rom.B2", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("romLex.C0", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("romLex.C1", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignColumn("romLex.C2", smartvectors.ForTest(1, 2, 3, 4)) - runS.AssignGrandProduct("modExp_GRAND_PRODUCT", field.One()) + moduleADefine := func(builder *wizard.Builder) { + builder.RegisterCommit("MODULE_A.A0", 4) + builder.RegisterCommit("MODULE_A.A1", 4) + builder.RegisterCommit("MODULE_A.A2", 4) } - _ = wizard.Prove(initialComp, prove) - _ = wizard.Prove(moduleCompModExp, prove) - errG := G.Check(runS) - if errG != nil { - t.Fatalf("error verifying the grand product: %v", errG.Error()) - } + initialComp := wizard.Compile(initialDefine) + moduleAComp := wizard.Compile(moduleADefine) + _ = dist_permutation.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) + moduleAProve := func(run *wizard.ProverRuntime) { + run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A1", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A2", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignGrandProduct("MODULE_A_GRAND_PRODUCT", field.One()) + } + _ = wizard.Prove(moduleAComp, moduleAProve) } diff --git a/prover/protocol/distributed/compiler/permutation/settings.go b/prover/protocol/distributed/compiler/permutation/settings.go index 73e3bf5f2..6f2c6ab00 100644 --- a/prover/protocol/distributed/compiler/permutation/settings.go +++ b/prover/protocol/distributed/compiler/permutation/settings.go @@ -1,5 +1,6 @@ package dist_permutation type Settings struct { +// Maximum number of permutation queries per module MaxNumOfQueryPerModule int } diff --git a/prover/protocol/distributed/module_discoverer/module_discoverer.go b/prover/protocol/distributed/module_discoverer/module_discoverer.go index 88f343107..9eb386522 100644 --- a/prover/protocol/distributed/module_discoverer/module_discoverer.go +++ b/prover/protocol/distributed/module_discoverer/module_discoverer.go @@ -19,7 +19,7 @@ func (p *PeriodSeperatingModuleDiscoverer) Analyze(comp *wizard.CompiledIOP) { p.modules = make(map[ModuleName][]ifaces.Column) numRounds := comp.NumRounds() for i := range numRounds { - for _, col := range comp.Columns.AllHandlesAtRound(i) { // Assume comp.Columns exists + for _, col := range comp.Columns.AllHandlesAtRound(i) { module := periodLogicToDetermineModule(col) p.modules[module] = append(p.modules[module], col) } diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index 48c8be993..4800e89b4 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -78,7 +78,7 @@ func (g *GrandProduct) Check(run ifaces.Runtime) error { } } if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { - return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, witness = %v", g.ID, numProdFr, denProdFr, params.Y) + return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, param.Y = %v", g.ID, numProdFr, denProdFr, params.Y) } return nil From 0704e8a2cfd788a43123e20940efeed45168686a Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 18 Dec 2024 13:36:07 +0530 Subject: [PATCH 13/21] Prover action added --- .../compiler/permutation/permutation.go | 57 ++++++++++++++++--- .../compiler/permutation/permutation_test.go | 16 ++++-- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 9e57f4a54..15662d4ef 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -2,6 +2,7 @@ package dist_permutation import ( "github.com/consensys/linea-monorepo/prover/protocol/coin" + "github.com/consensys/linea-monorepo/prover/protocol/column" "github.com/consensys/linea-monorepo/prover/protocol/compiler/permutation" modulediscoverer "github.com/consensys/linea-monorepo/prover/protocol/distributed/module_discoverer" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" @@ -31,7 +32,7 @@ func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductC func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, targetModuleName modulediscoverer.ModuleName, - s Settings) *query.GrandProduct { + s Settings, run *wizard.ProverRuntime) ifaces.Query { numRounds := initialComp.NumRounds() permCtx := newPermutationIntoGrandProductCtx(s) // Initialise the period separating module discoverer @@ -71,7 +72,9 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } // Reduce a permutation query into a GrandProduct query qId := ifaces.QueryIDf(string(targetModuleName) + "_GRAND_PRODUCT") - return moduleComp.InsertGrandProduct(0, qId, permCtx.numerators, permCtx.denominators) + G := moduleComp.InsertGrandProduct(0, qId, permCtx.numerators, permCtx.denominators) + moduleComp.RegisterProverAction(1, permCtx.AssignParam(run, qId)) + return G } // The below function does the following: @@ -83,12 +86,12 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query isMultiColumn = len(q.A[0]) > 1 alpha coin.Info // beta has to be different for different queries for a perticular round for the soundness of z-packing - beta = comp.InsertCoin(round, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) + beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) ) if isMultiColumn { // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(round, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) + alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) } if isNumerator && !isBoth { @@ -113,17 +116,57 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta coin.Info) *symbolic.Expression { var ( - numFrag = len(aOrB) - factor = symbolic.NewConstant(1) + numFrag = len(aOrB) + factor = symbolic.NewConstant(1) + fragFactor = symbolic.NewConstant(1) ) for frag := range numFrag { - fragFactor := symbolic.NewVariable(aOrB[frag][0]) if isMultiColumn { fragFactor = wizardutils.RandLinCombColSymbolic(alpha, aOrB[frag]) + } else { + fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) } fragFactor = symbolic.Add(fragFactor, beta) factor = symbolic.Mul(factor, fragFactor) } return factor } + +func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, name ifaces.QueryID) *PermutationIntoGrandProductCtx { + var ( + numNumerators = len(p.numerators) + numDenominators = len(p.denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) + + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, p.numerators[i]) + } + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, p.denominators[j]) + } + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + if len(numProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + denProdFr.Inverse(&denProdFr) + Y := numProdFr.Mul(&numProdFr, &denProdFr) + run.AssignGrandProduct(name, *Y) + return p +} + +func (p *PermutationIntoGrandProductCtx) Run(run *wizard.ProverRuntime) { + panic("unimplemented") +} diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index e52d160a4..afe9e1fcc 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -4,13 +4,16 @@ import ( "testing" "github.com/consensys/linea-monorepo/prover/maths/common/smartvectors" - "github.com/consensys/linea-monorepo/prover/maths/field" dist_permutation "github.com/consensys/linea-monorepo/prover/protocol/distributed/compiler/permutation" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) func TestDistPermutation(t *testing.T) { + var ( + runS *wizard.ProverRuntime + G ifaces.Query + ) initialDefine := func(builder *wizard.Builder) { A := []ifaces.Column{ builder.RegisterCommit("MODULE_A.A0", 4), @@ -40,13 +43,18 @@ func TestDistPermutation(t *testing.T) { initialComp := wizard.Compile(initialDefine) moduleAComp := wizard.Compile(moduleADefine) - _ = dist_permutation.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) - + moduleAProve := func(run *wizard.ProverRuntime) { + runS = run run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) run.AssignColumn("MODULE_A.A1", smartvectors.ForTest(1, 2, 3, 4)) run.AssignColumn("MODULE_A.A2", smartvectors.ForTest(1, 2, 3, 4)) - run.AssignGrandProduct("MODULE_A_GRAND_PRODUCT", field.One()) + G = dist_permutation.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}, run) } _ = wizard.Prove(moduleAComp, moduleAProve) + errG := G.Check(runS) + + if errG != nil { + t.Fatalf("error verifying the grand product: %v", errG.Error()) + } } From 390bbe41a76e0d7e325ff5eda872311a91913ce0 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 18 Dec 2024 17:44:45 +0530 Subject: [PATCH 14/21] added some refactoring, debug wip --- .../compiler/permutation/permutation.go | 78 +++++++++---------- .../compiler/permutation/permutation_test.go | 4 +- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 15662d4ef..3a3d693a1 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -1,6 +1,7 @@ package dist_permutation import ( + "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/compiler/permutation" @@ -18,23 +19,23 @@ The below function does the following: 1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query */ type PermutationIntoGrandProductCtx struct { - numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query - denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query + Numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query + Denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query + ParamY field.Element + QId ifaces.QueryID } // Returns a new PermutationIntoGrandProductCtx -func newPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductCtx { +func NewPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductCtx { permCtx := PermutationIntoGrandProductCtx{} - permCtx.numerators = make([]*symbolic.Expression, s.MaxNumOfQueryPerModule) - permCtx.denominators = make([]*symbolic.Expression, s.MaxNumOfQueryPerModule) + permCtx.Numerators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) + permCtx.Denominators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) return &permCtx } -func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, - targetModuleName modulediscoverer.ModuleName, - s Settings, run *wizard.ProverRuntime) ifaces.Query { +func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, + targetModuleName modulediscoverer.ModuleName, run *wizard.ProverRuntime) ifaces.Query { numRounds := initialComp.NumRounds() - permCtx := newPermutationIntoGrandProductCtx(s) // Initialise the period separating module discoverer disc := modulediscoverer.PeriodSeperatingModuleDiscoverer{} disc.Analyze(initialComp) @@ -56,11 +57,11 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, moduleNameB := disc.FindModule(q_.B[0][0]) logrus.Printf("moduleNameA = %v, moduleNameB = %v", moduleNameA, moduleNameB) if moduleNameA == targetModuleName && moduleNameB != targetModuleName { - permCtx.push(moduleComp, &q_, i, j, true, false) + p.push(moduleComp, &q_, i, j, true, false) } else if moduleNameA != targetModuleName && moduleNameB == targetModuleName { - permCtx.push(moduleComp, &q_, i, j, false, false) + p.push(moduleComp, &q_, i, j, false, false) } else if moduleNameA == targetModuleName && moduleNameB == targetModuleName { - permCtx.push(moduleComp, &q_, i, j, true, true) + p.push(moduleComp, &q_, i, j, true, true) } else { continue } @@ -72,8 +73,9 @@ func AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, } // Reduce a permutation query into a GrandProduct query qId := ifaces.QueryIDf(string(targetModuleName) + "_GRAND_PRODUCT") - G := moduleComp.InsertGrandProduct(0, qId, permCtx.numerators, permCtx.denominators) - moduleComp.RegisterProverAction(1, permCtx.AssignParam(run, qId)) + p.QId = qId + G := moduleComp.InsertGrandProduct(0, qId, p.Numerators, p.Denominators) + moduleComp.RegisterProverAction(1, p.AssignParam(run, qId)) return G } @@ -84,37 +86,36 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query logrus.Printf("queryInRound %d", queryInRound) var ( isMultiColumn = len(q.A[0]) > 1 - alpha coin.Info + // isFragmented = len(q.A) > 1 + alpha coin.Info // beta has to be different for different queries for a perticular round for the soundness of z-packing - beta = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "BETA_%v", queryInRound), coin.Field) + beta coin.Info ) - if isMultiColumn { - // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(round+1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v", queryInRound), coin.Field) - - } + // alpha has to be different for different queries for a perticular round for the soundness of z-packing + alpha = comp.InsertCoin(1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v_%v", round, queryInRound), coin.Field) + beta = comp.InsertCoin(1, permutation.DeriveName[coin.Name](*q, "BETA_%v_%v", round, queryInRound), coin.Field) if isNumerator && !isBoth { // Take only the numerator - factor := computeFactor(q.A, isMultiColumn, alpha, beta) - p.numerators = append(p.numerators, factor) + factor := computeFactor(q.A, isMultiColumn, &alpha, &beta) + p.Numerators = append(p.Numerators, factor) } else if !isNumerator && !isBoth { // Take only the denominator - factor := computeFactor(q.B, isMultiColumn, alpha, beta) - p.denominators = append(p.denominators, factor) + factor := computeFactor(q.B, isMultiColumn, &alpha, &beta) + p.Denominators = append(p.Denominators, factor) } else if isNumerator && isBoth { // Take both the numerator and the denominator - numFactor := computeFactor(q.A, isMultiColumn, alpha, beta) - denFactor := computeFactor(q.B, isMultiColumn, alpha, beta) - p.numerators = append(p.numerators, numFactor) - p.denominators = append(p.denominators, denFactor) + numFactor := computeFactor(q.A, isMultiColumn, &alpha, &beta) + denFactor := computeFactor(q.B, isMultiColumn, &alpha, &beta) + p.Numerators = append(p.Numerators, numFactor) + p.Denominators = append(p.Denominators, denFactor) } else if !isNumerator && isBoth { panic("Invalid case") } } -func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta coin.Info) *symbolic.Expression { +func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta *coin.Info) *symbolic.Expression { var ( numFrag = len(aOrB) factor = symbolic.NewConstant(1) @@ -123,11 +124,11 @@ func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta coin. for frag := range numFrag { if isMultiColumn { - fragFactor = wizardutils.RandLinCombColSymbolic(alpha, aOrB[frag]) + fragFactor = wizardutils.RandLinCombColSymbolic(*alpha, aOrB[frag]) } else { fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) } - fragFactor = symbolic.Add(fragFactor, beta) + fragFactor = symbolic.Add(fragFactor, *beta) factor = symbolic.Mul(factor, fragFactor) } return factor @@ -135,17 +136,16 @@ func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta coin. func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, name ifaces.QueryID) *PermutationIntoGrandProductCtx { var ( - numNumerators = len(p.numerators) - numDenominators = len(p.denominators) + numNumerators = len(p.Numerators) + numDenominators = len(p.Denominators) numProd = symbolic.NewConstant(1) denProd = symbolic.NewConstant(1) ) - for i := 0; i < numNumerators; i++ { - numProd = symbolic.Mul(numProd, p.numerators[i]) + numProd = symbolic.Mul(numProd, p.Numerators[i]) } for j := 0; j < numDenominators; j++ { - denProd = symbolic.Mul(denProd, p.denominators[j]) + denProd = symbolic.Mul(denProd, p.Denominators[j]) } numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() @@ -163,10 +163,10 @@ func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, } denProdFr.Inverse(&denProdFr) Y := numProdFr.Mul(&numProdFr, &denProdFr) - run.AssignGrandProduct(name, *Y) + p.ParamY = *Y return p } func (p *PermutationIntoGrandProductCtx) Run(run *wizard.ProverRuntime) { - panic("unimplemented") + run.AssignGrandProduct(p.QId, p.ParamY) } diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index afe9e1fcc..42eff0342 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -13,7 +13,9 @@ func TestDistPermutation(t *testing.T) { var ( runS *wizard.ProverRuntime G ifaces.Query + permCtx *dist_permutation.PermutationIntoGrandProductCtx ) + permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) initialDefine := func(builder *wizard.Builder) { A := []ifaces.Column{ builder.RegisterCommit("MODULE_A.A0", 4), @@ -49,7 +51,7 @@ func TestDistPermutation(t *testing.T) { run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) run.AssignColumn("MODULE_A.A1", smartvectors.ForTest(1, 2, 3, 4)) run.AssignColumn("MODULE_A.A2", smartvectors.ForTest(1, 2, 3, 4)) - G = dist_permutation.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", dist_permutation.Settings{MaxNumOfQueryPerModule: 4}, run) + G = permCtx.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", run) } _ = wizard.Prove(moduleAComp, moduleAProve) errG := G.Check(runS) From 12f5281ad236ebf52bd512acb9f0b514f87ba8a6 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 18 Dec 2024 19:28:25 +0530 Subject: [PATCH 15/21] coin in grand product test, deriveName for GP added --- .../protocol/compiler/permutation/compiler.go | 4 +-- prover/protocol/compiler/permutation/utils.go | 4 +-- .../compiler/permutation/permutation.go | 27 +++++++++++++------ prover/protocol/query/grand_product_test.go | 14 +++++----- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/prover/protocol/compiler/permutation/compiler.go b/prover/protocol/compiler/permutation/compiler.go index 46526ce55..1c8320dba 100644 --- a/prover/protocol/compiler/permutation/compiler.go +++ b/prover/protocol/compiler/permutation/compiler.go @@ -67,11 +67,11 @@ func dispatchPermutation( var ( isMultiColumn = len(q.A[0]) > 1 alpha coin.Info - beta = comp.InsertCoin(round+1, DeriveName[coin.Name](q, "BETA"), coin.Field) + beta = comp.InsertCoin(round+1, deriveName[coin.Name](q, "BETA"), coin.Field) ) if isMultiColumn { - alpha = comp.InsertCoin(round+1, DeriveName[coin.Name](q, "ALPHA"), coin.Field) + alpha = comp.InsertCoin(round+1, deriveName[coin.Name](q, "ALPHA"), coin.Field) } for k, aOrB := range [2][][]ifaces.Column{q.A, q.B} { diff --git a/prover/protocol/compiler/permutation/utils.go b/prover/protocol/compiler/permutation/utils.go index d3777cee1..ffa652e98 100644 --- a/prover/protocol/compiler/permutation/utils.go +++ b/prover/protocol/compiler/permutation/utils.go @@ -7,8 +7,8 @@ import ( const permutationStr = "PERMUTATION" -// DeriveName constructs a name for the permutation context -func DeriveName[R ~string](q query.Permutation, ss ...any) R { +// deriveName constructs a name for the permutation context +func deriveName[R ~string](q query.Permutation, ss ...any) R { ss = append([]any{permutationStr, q}, ss...) return wizardutils.DeriveName[R](ss...) } diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 3a3d693a1..383985658 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -4,7 +4,6 @@ import ( "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/compiler/permutation" modulediscoverer "github.com/consensys/linea-monorepo/prover/protocol/distributed/module_discoverer" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/query" @@ -14,6 +13,8 @@ import ( "github.com/sirupsen/logrus" ) +const grandProductStr = "GRAND_PRODUCT" + /* The below function does the following: 1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query @@ -21,8 +22,8 @@ The below function does the following: type PermutationIntoGrandProductCtx struct { Numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query Denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query - ParamY field.Element - QId ifaces.QueryID + ParamY field.Element + QId ifaces.QueryID } // Returns a new PermutationIntoGrandProductCtx @@ -39,6 +40,9 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo // Initialise the period separating module discoverer disc := modulediscoverer.PeriodSeperatingModuleDiscoverer{} disc.Analyze(initialComp) + qId := deriveName[ifaces.QueryID](ifaces.QueryID(targetModuleName)) + logrus.Printf("qId : %s", qId) + p.QId = qId /* Handles the lookups and permutations checks */ @@ -55,7 +59,6 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo { moduleNameA := disc.FindModule(q_.A[0][0]) moduleNameB := disc.FindModule(q_.B[0][0]) - logrus.Printf("moduleNameA = %v, moduleNameB = %v", moduleNameA, moduleNameB) if moduleNameA == targetModuleName && moduleNameB != targetModuleName { p.push(moduleComp, &q_, i, j, true, false) } else if moduleNameA != targetModuleName && moduleNameB == targetModuleName { @@ -72,8 +75,6 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo } } // Reduce a permutation query into a GrandProduct query - qId := ifaces.QueryIDf(string(targetModuleName) + "_GRAND_PRODUCT") - p.QId = qId G := moduleComp.InsertGrandProduct(0, qId, p.Numerators, p.Denominators) moduleComp.RegisterProverAction(1, p.AssignParam(run, qId)) return G @@ -93,8 +94,8 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query ) // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(1, permutation.DeriveName[coin.Name](*q, "ALPHA_%v_%v", round, queryInRound), coin.Field) - beta = comp.InsertCoin(1, permutation.DeriveName[coin.Name](*q, "BETA_%v_%v", round, queryInRound), coin.Field) + alpha = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID("ALPHA"), round, queryInRound), coin.Field) + beta = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID("BETA"), round, queryInRound), coin.Field) if isNumerator && !isBoth { // Take only the numerator factor := computeFactor(q.A, isMultiColumn, &alpha, &beta) @@ -141,6 +142,10 @@ func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, numProd = symbolic.NewConstant(1) denProd = symbolic.NewConstant(1) ) + coins := run.Spec.Coins.AllKeys() + for i := range coins { + logrus.Printf("coin : %v", coins[i]) + } for i := 0; i < numNumerators; i++ { numProd = symbolic.Mul(numProd, p.Numerators[i]) } @@ -170,3 +175,9 @@ func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, func (p *PermutationIntoGrandProductCtx) Run(run *wizard.ProverRuntime) { run.AssignGrandProduct(p.QId, p.ParamY) } + +// DeriveName constructs a name for the permutation context +func deriveName[R ~string](q ifaces.QueryID, ss ...any) R { + ss = append([]any{grandProductStr, q}, ss...) + return wizardutils.DeriveName[R](ss...) +} diff --git a/prover/protocol/query/grand_product_test.go b/prover/protocol/query/grand_product_test.go index 4501c2e62..adbfcb2a0 100644 --- a/prover/protocol/query/grand_product_test.go +++ b/prover/protocol/query/grand_product_test.go @@ -5,6 +5,7 @@ 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/coin" "github.com/consensys/linea-monorepo/prover/protocol/ifaces" "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/symbolic" @@ -21,15 +22,16 @@ func TestGrandProduct(t *testing.T) { A0 := builder.RegisterCommit("A0", 4) B0 := builder.RegisterCommit("B0", 4) C0 := builder.RegisterCommit("C0", 4) + alpha := builder.RegisterRandomCoin("ALPHA", coin.Field) A := []*symbolic.Expression{ - symbolic.Add(A0, B0), - symbolic.Add(B0, C0), - symbolic.Add(C0, A0), + symbolic.Add(A0, symbolic.Mul(B0, alpha)), + symbolic.Add(B0, symbolic.Mul(C0, alpha)), + symbolic.Add(C0, symbolic.Mul(A0, alpha)), } B := []*symbolic.Expression{ - symbolic.Add(C0, A0), - symbolic.Add(B0, C0), - symbolic.Add(A0, B0), + symbolic.Add(C0, symbolic.Mul(A0, alpha)), + symbolic.Add(B0, symbolic.Mul(C0, alpha)), + symbolic.Add(A0, symbolic.Mul(B0, alpha)), } G = builder.CompiledIOP.InsertGrandProduct(0, "G", A, B) } From 970dd8a34acadfd885f489445b943f85313cf81d Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 18 Dec 2024 19:36:22 +0530 Subject: [PATCH 16/21] name fix --- .../compiler/permutation/permutation.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 383985658..c5ab00792 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -20,10 +20,11 @@ The below function does the following: 1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query */ type PermutationIntoGrandProductCtx struct { - Numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query - Denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query - ParamY field.Element - QId ifaces.QueryID + Numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query + Denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query + ParamY field.Element + QId ifaces.QueryID + TargetModuleName string } // Returns a new PermutationIntoGrandProductCtx @@ -43,6 +44,7 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo qId := deriveName[ifaces.QueryID](ifaces.QueryID(targetModuleName)) logrus.Printf("qId : %s", qId) p.QId = qId + p.TargetModuleName = string(targetModuleName) /* Handles the lookups and permutations checks */ @@ -94,8 +96,8 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query ) // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID("ALPHA"), round, queryInRound), coin.Field) - beta = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID("BETA"), round, queryInRound), coin.Field) + alpha = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID(p.TargetModuleName), "ALPHA", round, queryInRound), coin.Field) + beta = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID(p.TargetModuleName), "BETA", round, queryInRound), coin.Field) if isNumerator && !isBoth { // Take only the numerator factor := computeFactor(q.A, isMultiColumn, &alpha, &beta) From 77ed42313ff45c86b7a16b5d48c8e531df591519 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Wed, 18 Dec 2024 21:21:11 +0530 Subject: [PATCH 17/21] bug fix, thanks Alex --- .../protocol/distributed/compiler/permutation/permutation.go | 3 ++- prover/protocol/wizard/prover.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index c5ab00792..587b332a7 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -32,6 +32,7 @@ func NewPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductC permCtx := PermutationIntoGrandProductCtx{} permCtx.Numerators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) permCtx.Denominators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) + permCtx.ParamY = field.One() return &permCtx } @@ -77,7 +78,7 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo } } // Reduce a permutation query into a GrandProduct query - G := moduleComp.InsertGrandProduct(0, qId, p.Numerators, p.Denominators) + G := moduleComp.InsertGrandProduct(1, qId, p.Numerators, p.Denominators) moduleComp.RegisterProverAction(1, p.AssignParam(run, qId)) return G } diff --git a/prover/protocol/wizard/prover.go b/prover/protocol/wizard/prover.go index dbbbeddc3..c13396874 100644 --- a/prover/protocol/wizard/prover.go +++ b/prover/protocol/wizard/prover.go @@ -422,6 +422,7 @@ func (run *ProverRuntime) getRandomCoinGeneric(name coin.Name, requestedType coi params, messages etc.. from the past round have been set. Then, we can generate the coins the user is requesting. */ + logrus.Printf("We get error here") run.goNextRound() case foundAtRound > run.currRound+1: From 7b5fcebd3b261a5bde1d766b7b92f30691f9eda3 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Thu, 19 Dec 2024 12:36:11 +0530 Subject: [PATCH 18/21] Test with fragment added --- .../compiler/permutation/permutation.go | 7 -- .../compiler/permutation/permutation_test.go | 70 ++++++++++++++++++- prover/protocol/wizard/prover.go | 1 - 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 587b332a7..d61fd735a 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -10,7 +10,6 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" "github.com/consensys/linea-monorepo/prover/protocol/wizardutils" "github.com/consensys/linea-monorepo/prover/symbolic" - "github.com/sirupsen/logrus" ) const grandProductStr = "GRAND_PRODUCT" @@ -43,7 +42,6 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo disc := modulediscoverer.PeriodSeperatingModuleDiscoverer{} disc.Analyze(initialComp) qId := deriveName[ifaces.QueryID](ifaces.QueryID(targetModuleName)) - logrus.Printf("qId : %s", qId) p.QId = qId p.TargetModuleName = string(targetModuleName) /* @@ -87,7 +85,6 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo // 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) in the compiledIop // 2. Populates the nemerators and the denominators of the grand product query func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query.Permutation, round, queryInRound int, isNumerator, isBoth bool) { - logrus.Printf("queryInRound %d", queryInRound) var ( isMultiColumn = len(q.A[0]) > 1 // isFragmented = len(q.A) > 1 @@ -145,10 +142,6 @@ func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, numProd = symbolic.NewConstant(1) denProd = symbolic.NewConstant(1) ) - coins := run.Spec.Coins.AllKeys() - for i := range coins { - logrus.Printf("coin : %v", coins[i]) - } for i := 0; i < numNumerators; i++ { numProd = symbolic.Mul(numProd, p.Numerators[i]) } diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index 42eff0342..cf0ffb832 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -9,7 +9,7 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) -func TestDistPermutation(t *testing.T) { +func TestDistPermutationNoFragment(t *testing.T) { var ( runS *wizard.ProverRuntime G ifaces.Query @@ -60,3 +60,71 @@ func TestDistPermutation(t *testing.T) { t.Fatalf("error verifying the grand product: %v", errG.Error()) } } + + +func TestDistPermutationFragment(t *testing.T) { + var ( + runS *wizard.ProverRuntime + G ifaces.Query + permCtx *dist_permutation.PermutationIntoGrandProductCtx + ) + permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) + initialDefine := func(builder *wizard.Builder) { + A := [][]ifaces.Column{ + {builder.RegisterCommit("MODULE_A.A00", 4), + builder.RegisterCommit("MODULE_A.A10", 4), + builder.RegisterCommit("MODULE_A.A20", 4)}, + {builder.RegisterCommit("MODULE_A.A01", 4), + builder.RegisterCommit("MODULE_A.A11", 4), + builder.RegisterCommit("MODULE_A.A21", 4)}, + } + B := [][]ifaces.Column{ + {builder.RegisterCommit("MODULE_B.B00", 4), + builder.RegisterCommit("MODULE_B.B10", 4), + builder.RegisterCommit("MODULE_B.B20", 4),}, + {builder.RegisterCommit("MODULE_B.B01", 4), + builder.RegisterCommit("MODULE_B.B11", 4), + builder.RegisterCommit("MODULE_B.B21", 4),}, + } + C := [][]ifaces.Column{ + {builder.RegisterCommit("MODULE_C.C00", 4), + builder.RegisterCommit("MODULE_C.C10", 4), + builder.RegisterCommit("MODULE_C.C20", 4),}, + {builder.RegisterCommit("MODULE_C.C01", 4), + builder.RegisterCommit("MODULE_C.C11", 4), + builder.RegisterCommit("MODULE_C.C21", 4),}, + } + _ = builder.CompiledIOP.InsertFragmentedPermutation(0, "P_MOD_A_MOD_B", A, B) + _ = builder.CompiledIOP.InsertFragmentedPermutation(0, "P_MOD_C_MOD_A", C, A) + _ = builder.CompiledIOP.InsertFragmentedPermutation(0, "P_MOD_B_MOD_C", B, C) + } + + moduleADefine := func(builder *wizard.Builder) { + builder.RegisterCommit("MODULE_A.A00", 4) + builder.RegisterCommit("MODULE_A.A10", 4) + builder.RegisterCommit("MODULE_A.A20", 4) + builder.RegisterCommit("MODULE_A.A01", 4) + builder.RegisterCommit("MODULE_A.A11", 4) + builder.RegisterCommit("MODULE_A.A21", 4) + } + + initialComp := wizard.Compile(initialDefine) + moduleAComp := wizard.Compile(moduleADefine) + + moduleAProve := func(run *wizard.ProverRuntime) { + runS = run + run.AssignColumn("MODULE_A.A00", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A10", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A20", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A01", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A11", smartvectors.ForTest(1, 2, 3, 4)) + run.AssignColumn("MODULE_A.A21", smartvectors.ForTest(1, 2, 3, 4)) + G = permCtx.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", run) + } + _ = wizard.Prove(moduleAComp, moduleAProve) + errG := G.Check(runS) + + if errG != nil { + t.Fatalf("error verifying the grand product: %v", errG.Error()) + } +} diff --git a/prover/protocol/wizard/prover.go b/prover/protocol/wizard/prover.go index c13396874..dbbbeddc3 100644 --- a/prover/protocol/wizard/prover.go +++ b/prover/protocol/wizard/prover.go @@ -422,7 +422,6 @@ func (run *ProverRuntime) getRandomCoinGeneric(name coin.Name, requestedType coi params, messages etc.. from the past round have been set. Then, we can generate the coins the user is requesting. */ - logrus.Printf("We get error here") run.goNextRound() case foundAtRound > run.currRound+1: From b22a49b715c4bf14724f8f61efe33aad1314434b Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Thu, 19 Dec 2024 13:31:27 +0530 Subject: [PATCH 19/21] added documentation --- .../compiler/permutation/permutation.go | 204 ++++++++++++------ .../compiler/permutation/permutation_test.go | 45 ++++ prover/protocol/query/grand_product.go | 104 +++++---- 3 files changed, 245 insertions(+), 108 deletions(-) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index d61fd735a..b246439e0 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -12,17 +12,27 @@ import ( "github.com/consensys/linea-monorepo/prover/symbolic" ) +// Used for deriving names of queries and coins const grandProductStr = "GRAND_PRODUCT" /* -The below function does the following: -1. For a given target module name, it finds all the relevant permutation query and combine them into a big grand product query +The below function aims to process all the permuation queries specific to a target module +into a grand product query. We store the randomised symbolic products of A and B of permuation +queries combinedly into the Numerators and the Denominators of the GrandProduct query */ type PermutationIntoGrandProductCtx struct { - Numerators []*symbolic.Expression // aimed at storing the expressions Ai + \beta_i for a particular permutation query - Denominators []*symbolic.Expression // aimed at storing the expressions Bi + \beta_i for a particular permutation query - ParamY field.Element - QId ifaces.QueryID + // stores the expressions Ai + \beta_i for the ith permutation query, Ai is a linear combination with alpha_i + // in case of multi-column + Numerators []*symbolic.Expression + // stores the expressions Bi + \beta_i for the ith permutation query, Bi is a linear combination with alpha_i + // in case of multi-column + Denominators []*symbolic.Expression + // stores the field element obtained by collapsing the expression + // \prod(Numerators)/\prod(Denominators) + ParamY field.Element + // The query id specific to the target module + QueryId ifaces.QueryID + // The module name for which we are processing the grand product query TargetModuleName string } @@ -31,10 +41,22 @@ func NewPermutationIntoGrandProductCtx(s Settings) *PermutationIntoGrandProductC permCtx := PermutationIntoGrandProductCtx{} permCtx.Numerators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) permCtx.Denominators = make([]*symbolic.Expression, 0, s.MaxNumOfQueryPerModule) - permCtx.ParamY = field.One() return &permCtx } +// AddGdProductQuery processes all permutation queries specific to a target module +// into a grand product query. It stores the randomised symbolic products of A and B +// of permutation queries combinedly into the Numerators and the Denominators of the +// GrandProduct query. +// +// Parameters: +// - initialComp: The initial compiledIOP +// - moduleComp: The compiledIOP for the target module +// - targetModuleName: The name of the module for which we are processing the grand product query +// - run: The prover runtime +// +// Returns: +// - An instance of the grand product query (ifaces.Query) func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleComp *wizard.CompiledIOP, targetModuleName modulediscoverer.ModuleName, run *wizard.ProverRuntime) ifaces.Query { numRounds := initialComp.NumRounds() @@ -42,10 +64,10 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo disc := modulediscoverer.PeriodSeperatingModuleDiscoverer{} disc.Analyze(initialComp) qId := deriveName[ifaces.QueryID](ifaces.QueryID(targetModuleName)) - p.QId = qId + p.QueryId = qId p.TargetModuleName = string(targetModuleName) /* - Handles the lookups and permutations checks + Handles the lookups and permutations checks */ for i := 0; i < numRounds; i++ { queries := initialComp.QueriesNoParams.AllKeysAt(i) @@ -75,26 +97,36 @@ func (p *PermutationIntoGrandProductCtx) AddGdProductQuery(initialComp, moduleCo } } } - // Reduce a permutation query into a GrandProduct query + // We register the grand product query in round one because + // alphas, betas, and the query param are assigned in round one G := moduleComp.InsertGrandProduct(1, qId, p.Numerators, p.Denominators) + // The below prover action is responsible for computing the query parameter + // and assign it in round one moduleComp.RegisterProverAction(1, p.AssignParam(run, qId)) return G } -// The below function does the following: -// 1. Register beta and alpha (for the random linear combination in case A and B are multi-columns) in the compiledIop -// 2. Populates the nemerators and the denominators of the grand product query +// push processes a permutation query and adds its symbolic factors to the Numerators or Denominators +// based on the provided flags. It also inserts coins for alpha and beta for each permutation query. +// +// Parameters: +// - comp: The compiled IOP for the target module +// - q: The permutation query to be processed +// - round: The round number of the permutation query +// - queryInRound: The index of the permutation query within the round +// - isNumerator: A flag indicating whether to add the symbolic factor to the Numerators +// - isBoth: A flag indicating whether we need to add the symbolic factor to both Numerators and Denominators func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query.Permutation, round, queryInRound int, isNumerator, isBoth bool) { var ( isMultiColumn = len(q.A[0]) > 1 - // isFragmented = len(q.A) > 1 - alpha coin.Info - // beta has to be different for different queries for a perticular round for the soundness of z-packing - beta coin.Info + alpha coin.Info + beta coin.Info ) - - // alpha has to be different for different queries for a perticular round for the soundness of z-packing - alpha = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID(p.TargetModuleName), "ALPHA", round, queryInRound), coin.Field) + if isMultiColumn { + // alpha has to be different for different queries for a particular round for the soundness of z-packing + alpha = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID(p.TargetModuleName), "ALPHA", round, queryInRound), coin.Field) + } + // beta has to be different for different queries for a particular round for the soundness of z-packing beta = comp.InsertCoin(1, deriveName[coin.Name](ifaces.QueryID(p.TargetModuleName), "BETA", round, queryInRound), coin.Field) if isNumerator && !isBoth { // Take only the numerator @@ -113,66 +145,102 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query } else if !isNumerator && isBoth { panic("Invalid case") } - } +// computeFactor computes the symbolic factor for a permutation query based on the given parameters. +// It iterates through the fragments of the query, computes the linear combination of columns with alpha +// (if multi-column) or directly uses the column as a variable, adds the beta value, and multiplies it with +// the current factor. The final computed factor is returned. +// +// Parameters: +// - aOrB: A 2D slice of Column interfaces representing the fragments of the permutation query. +// - isMultiColumn: A boolean indicating whether the permutation query is multi-column. +// - alpha: A pointer to a CoinInfo struct representing the alpha coin for the permutation query. +// - beta: A pointer to a CoinInfo struct representing the beta coin for the permutation query. +// +// Returns: +// - A pointer to a symbolic.Expression representing the computed factor for the permutation query. func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta *coin.Info) *symbolic.Expression { - var ( - numFrag = len(aOrB) - factor = symbolic.NewConstant(1) - fragFactor = symbolic.NewConstant(1) - ) + var ( + numFrag = len(aOrB) + factor = symbolic.NewConstant(1) + fragFactor = symbolic.NewConstant(1) + ) - for frag := range numFrag { - if isMultiColumn { - fragFactor = wizardutils.RandLinCombColSymbolic(*alpha, aOrB[frag]) - } else { - fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) - } - fragFactor = symbolic.Add(fragFactor, *beta) - factor = symbolic.Mul(factor, fragFactor) - } - return factor + for frag := range numFrag { + if isMultiColumn { + fragFactor = wizardutils.RandLinCombColSymbolic(*alpha, aOrB[frag]) + } else { + fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) + } + fragFactor = symbolic.Add(fragFactor, *beta) + factor = symbolic.Mul(factor, fragFactor) + } + return factor } +// AssignParam computes the query parameter for the grand product query and assigns it in round one. +// It multiplies the products of the Numerators and Denominators, evaluates the resulting symbolic expressions, +// and assigns the result to the field element ParamY. +// +// Parameters: +// - run: The prover runtime. +// - name: The query ID specific to the target module. +// +// Returns: +// - A pointer to the PermutationIntoGrandProductCtx instance with the updated ParamY field. func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, name ifaces.QueryID) *PermutationIntoGrandProductCtx { - var ( - numNumerators = len(p.Numerators) - numDenominators = len(p.Denominators) - numProd = symbolic.NewConstant(1) - denProd = symbolic.NewConstant(1) - ) - for i := 0; i < numNumerators; i++ { - numProd = symbolic.Mul(numProd, p.Numerators[i]) - } - for j := 0; j < numDenominators; j++ { - denProd = symbolic.Mul(denProd, p.Denominators[j]) - } - numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() - denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() - numProdFr := numProdFrVec[0] - denProdFr := denProdFrVec[0] - if len(numProdFrVec) > 1 { - for i := 1; i < len(numProdFrVec); i++ { - numProdFr.Mul(&numProdFr, &numProdFrVec[i]) - } - } - if len(numProdFrVec) > 1 { - for j := 1; j < len(denProdFrVec); j++ { - denProdFr.Mul(&denProdFr, &denProdFrVec[j]) - } - } - denProdFr.Inverse(&denProdFr) - Y := numProdFr.Mul(&numProdFr, &denProdFr) - p.ParamY = *Y - return p + var ( + numNumerators = len(p.Numerators) + numDenominators = len(p.Denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) + // Multiply all Numerators + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, p.Numerators[i]) + } + // Multiply all Denominators + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, p.Denominators[j]) + } + // Evaluate the symbolic expressions for Numerator and Denominator products + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + // Multiply all field elements in the Numerator product vector + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + // Multiply all field elements in the Denominator product vector + if len(denProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + // Invert the Denominator product field element + denProdFr.Inverse(&denProdFr) + // Compute the final query parameter Y + Y := numProdFr.Mul(&numProdFr, &denProdFr) + p.ParamY = *Y + return p } +// Run executes the grand product query by assigning the computed parameter Y to the prover runtime. +// +// Parameters: +// - run: The prover runtime where the grand product query will be executed. +// +// The function does not return any value. It directly assigns the computed parameter Y to the prover runtime +// using the AssignGrandProduct method of the runtime. func (p *PermutationIntoGrandProductCtx) Run(run *wizard.ProverRuntime) { - run.AssignGrandProduct(p.QId, p.ParamY) + run.AssignGrandProduct(p.QueryId, p.ParamY) } -// DeriveName constructs a name for the permutation context +// deriveName constructs a name for the PermutationIntoGrandProduct context func deriveName[R ~string](q ifaces.QueryID, ss ...any) R { ss = append([]any{grandProductStr, q}, ss...) return wizardutils.DeriveName[R](ss...) diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index cf0ffb832..a76adfe3b 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -9,6 +9,51 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) + +func TestDistPermutationNoMultiColumnNoFragment(t *testing.T) { + var ( + runS *wizard.ProverRuntime + G ifaces.Query + permCtx *dist_permutation.PermutationIntoGrandProductCtx + ) + permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) + initialDefine := func(builder *wizard.Builder) { + A := []ifaces.Column{ + builder.RegisterCommit("MODULE_A.A0", 4), + } + B := []ifaces.Column{ + builder.RegisterCommit("MODULE_B.B0", 4), + } + C := []ifaces.Column{ + builder.RegisterCommit("MODULE_C.C0", 4), + } + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_A_MOD_B", A, B) + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_C_MOD_A", C, A) + _ = builder.CompiledIOP.InsertPermutation(0, "P_MOD_B_MOD_C", B, C) + } + + moduleADefine := func(builder *wizard.Builder) { + builder.RegisterCommit("MODULE_A.A0", 4) + } + + initialComp := wizard.Compile(initialDefine) + moduleAComp := wizard.Compile(moduleADefine) + + moduleAProve := func(run *wizard.ProverRuntime) { + runS = run + run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) + G = permCtx.AddGdProductQuery(initialComp, moduleAComp, "MODULE_A", run) + } + _ = wizard.Prove(moduleAComp, moduleAProve) + errG := G.Check(runS) + + if errG != nil { + t.Fatalf("error verifying the grand product: %v", errG.Error()) + } +} + + + func TestDistPermutationNoFragment(t *testing.T) { var ( runS *wizard.ProverRuntime diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index 4800e89b4..bb00ce163 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -12,8 +12,9 @@ import ( "github.com/consensys/linea-monorepo/prover/utils" ) -// The GrandProduct query enables splitting of the Permutation query between sub-provers -// by splitting the grand product Z = \prod(A_i+\beta)/(B_i+\beta) itself. +// The GrandProduct query is obtained by process all the permuation queries specific to a target module. +// We store the randomised symbolic products of A and B of permuation queries combinedly +// into the Numerators and the Denominators of the GrandProduct query type GrandProduct struct { ID ifaces.QueryID Numerators []*symbolic.Expression // stores A as multi-column @@ -25,13 +26,26 @@ type GrandProductParams struct { Y field.Element } +// NewGrandProduct creates a new instance of a GrandProduct query. +// The GrandProduct query is obtained by processing all permutation queries specific to a target module. +// We store the randomized symbolic products of A and B of permutation queries combinedly +// into the Numerators and the Denominators of the GrandProduct query. +// +// Parameters: +// - round: The round number of the query. +// - id: The unique identifier for the query. +// - numerators: A slice of symbolic expressions representing the numerators of the permutation queries. +// - denominators: A slice of symbolic expressions representing the denominators of the permutation queries. +// +// Returns: +// - A pointer to a new instance of GrandProduct. func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) *GrandProduct { - return &GrandProduct{ - ID: id, - Numerators: numerators, - Denominators: denominators, - Round: round, - } + return &GrandProduct{ + ID: id, + Numerators: numerators, + Denominators: denominators, + Round: round, + } } // Constructor for grand product query parameters @@ -39,8 +53,9 @@ func NewGrandProductParams(y field.Element) GrandProductParams { return GrandProductParams{Y: y} } +// Name returns the unique identifier of the GrandProduct query. func (g GrandProduct) Name() ifaces.QueryID { - return g.ID + return g.ID } // Updates a Fiat-Shamir state @@ -48,40 +63,49 @@ func (gp GrandProductParams) UpdateFS(fs *fiatshamir.State) { fs.Update(gp.Y) } +// Check verifies the satisfaction of the GrandProduct query using the provided runtime. +// It calculates the product of numerators and denominators, and checks +// if prod(Numerators) == Prod(Denominators)*ParamY, and returns an error if the condition is not satisfied. +// +// Parameters: +// - run: The runtime interface providing access to the query parameter for query verification. +// +// Returns: +// - An error if the grand product query is not satisfied, or nil if it is satisfied. func (g *GrandProduct) Check(run ifaces.Runtime) error { - var ( - numNumerators = len(g.Numerators) - numDenominators = len(g.Denominators) - numProd = symbolic.NewConstant(1) - denProd = symbolic.NewConstant(1) - ) + var ( + numNumerators = len(g.Numerators) + numDenominators = len(g.Denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) - for i := 0; i < numNumerators; i++ { - numProd = symbolic.Mul(numProd, g.Numerators[i]) - } - for j := 0; j < numDenominators; j++ { - denProd = symbolic.Mul(denProd, g.Denominators[j]) - } - params := run.GetParams(g.ID).(GrandProductParams) - numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() - denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() - numProdFr := numProdFrVec[0] - denProdFr := denProdFrVec[0] - if len(numProdFrVec) > 1 { - for i := 1; i < len(numProdFrVec); i++ { - numProdFr.Mul(&numProdFr, &numProdFrVec[i]) - } - } - if len(numProdFrVec) > 1 { - for j := 1; j < len(denProdFrVec); j++ { - denProdFr.Mul(&denProdFr, &denProdFrVec[j]) - } - } - if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { - return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, param.Y = %v", g.ID, numProdFr, denProdFr, params.Y) - } + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, g.Numerators[i]) + } + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, g.Denominators[j]) + } + params := run.GetParams(g.ID).(GrandProductParams) + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + if len(numProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { + return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, param.Y = %v", g.ID, numProdFr, denProdFr, params.Y) + } - return nil + return nil } func (g GrandProduct) CheckGnark(api frontend.API, run ifaces.GnarkRuntime) { From 2bea59348f3b9f15b5c41a4740c58a428187d0f1 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Thu, 19 Dec 2024 16:49:26 +0530 Subject: [PATCH 20/21] fixes after merge --- .../compiler/permutation/permutation.go | 108 +++++++++--------- .../compiler/permutation/permutation_test.go | 46 ++++---- .../compiler/permutation/settings.go | 2 +- .../compiler/projection/projection.go | 1 - prover/protocol/distributed/distributed.go | 8 +- .../protocol/distributed/module_discover.go | 2 +- ...=> period_separating_module_discoverer.go} | 6 + prover/protocol/query/grand_product.go | 78 ++++++------- 8 files changed, 127 insertions(+), 124 deletions(-) rename prover/protocol/distributed/module_discoverer/{module_discoverer.go => period_separating_module_discoverer.go} (90%) diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index b246439e0..78834876e 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -16,7 +16,7 @@ import ( const grandProductStr = "GRAND_PRODUCT" /* -The below function aims to process all the permuation queries specific to a target module +The below function aims to process all the permutation queries specific to a target module into a grand product query. We store the randomised symbolic products of A and B of permuation queries combinedly into the Numerators and the Denominators of the GrandProduct query */ @@ -161,22 +161,22 @@ func (p *PermutationIntoGrandProductCtx) push(comp *wizard.CompiledIOP, q *query // Returns: // - A pointer to a symbolic.Expression representing the computed factor for the permutation query. func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta *coin.Info) *symbolic.Expression { - var ( - numFrag = len(aOrB) - factor = symbolic.NewConstant(1) - fragFactor = symbolic.NewConstant(1) - ) + var ( + numFrag = len(aOrB) + factor = symbolic.NewConstant(1) + fragFactor = symbolic.NewConstant(1) + ) - for frag := range numFrag { - if isMultiColumn { - fragFactor = wizardutils.RandLinCombColSymbolic(*alpha, aOrB[frag]) - } else { - fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) - } - fragFactor = symbolic.Add(fragFactor, *beta) - factor = symbolic.Mul(factor, fragFactor) - } - return factor + for frag := range numFrag { + if isMultiColumn { + fragFactor = wizardutils.RandLinCombColSymbolic(*alpha, aOrB[frag]) + } else { + fragFactor = ifaces.ColumnAsVariable(aOrB[frag][0]) + } + fragFactor = symbolic.Add(fragFactor, *beta) + factor = symbolic.Mul(factor, fragFactor) + } + return factor } // AssignParam computes the query parameter for the grand product query and assigns it in round one. @@ -190,43 +190,43 @@ func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta *coin // Returns: // - A pointer to the PermutationIntoGrandProductCtx instance with the updated ParamY field. func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, name ifaces.QueryID) *PermutationIntoGrandProductCtx { - var ( - numNumerators = len(p.Numerators) - numDenominators = len(p.Denominators) - numProd = symbolic.NewConstant(1) - denProd = symbolic.NewConstant(1) - ) - // Multiply all Numerators - for i := 0; i < numNumerators; i++ { - numProd = symbolic.Mul(numProd, p.Numerators[i]) - } - // Multiply all Denominators - for j := 0; j < numDenominators; j++ { - denProd = symbolic.Mul(denProd, p.Denominators[j]) - } - // Evaluate the symbolic expressions for Numerator and Denominator products - numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() - denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() - numProdFr := numProdFrVec[0] - denProdFr := denProdFrVec[0] - // Multiply all field elements in the Numerator product vector - if len(numProdFrVec) > 1 { - for i := 1; i < len(numProdFrVec); i++ { - numProdFr.Mul(&numProdFr, &numProdFrVec[i]) - } - } - // Multiply all field elements in the Denominator product vector - if len(denProdFrVec) > 1 { - for j := 1; j < len(denProdFrVec); j++ { - denProdFr.Mul(&denProdFr, &denProdFrVec[j]) - } - } - // Invert the Denominator product field element - denProdFr.Inverse(&denProdFr) - // Compute the final query parameter Y - Y := numProdFr.Mul(&numProdFr, &denProdFr) - p.ParamY = *Y - return p + var ( + numNumerators = len(p.Numerators) + numDenominators = len(p.Denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) + // Multiply all Numerators + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, p.Numerators[i]) + } + // Multiply all Denominators + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, p.Denominators[j]) + } + // Evaluate the symbolic expressions for Numerator and Denominator products + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + // Multiply all field elements in the Numerator product vector + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + // Multiply all field elements in the Denominator product vector + if len(denProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + // Invert the Denominator product field element + denProdFr.Inverse(&denProdFr) + // Compute the final query parameter Y + Y := numProdFr.Mul(&numProdFr, &denProdFr) + p.ParamY = *Y + return p } // Run executes the grand product query by assigning the computed parameter Y to the prover runtime. @@ -237,7 +237,7 @@ func (p *PermutationIntoGrandProductCtx) AssignParam(run *wizard.ProverRuntime, // The function does not return any value. It directly assigns the computed parameter Y to the prover runtime // using the AssignGrandProduct method of the runtime. func (p *PermutationIntoGrandProductCtx) Run(run *wizard.ProverRuntime) { - run.AssignGrandProduct(p.QueryId, p.ParamY) + run.AssignGrandProduct(p.QueryId, p.ParamY) } // deriveName constructs a name for the PermutationIntoGrandProduct context diff --git a/prover/protocol/distributed/compiler/permutation/permutation_test.go b/prover/protocol/distributed/compiler/permutation/permutation_test.go index a76adfe3b..74a23932b 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation_test.go +++ b/prover/protocol/distributed/compiler/permutation/permutation_test.go @@ -9,11 +9,10 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) - func TestDistPermutationNoMultiColumnNoFragment(t *testing.T) { var ( - runS *wizard.ProverRuntime - G ifaces.Query + runS *wizard.ProverRuntime + G ifaces.Query permCtx *dist_permutation.PermutationIntoGrandProductCtx ) permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) @@ -38,7 +37,7 @@ func TestDistPermutationNoMultiColumnNoFragment(t *testing.T) { initialComp := wizard.Compile(initialDefine) moduleAComp := wizard.Compile(moduleADefine) - + moduleAProve := func(run *wizard.ProverRuntime) { runS = run run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) @@ -52,12 +51,10 @@ func TestDistPermutationNoMultiColumnNoFragment(t *testing.T) { } } - - func TestDistPermutationNoFragment(t *testing.T) { var ( - runS *wizard.ProverRuntime - G ifaces.Query + runS *wizard.ProverRuntime + G ifaces.Query permCtx *dist_permutation.PermutationIntoGrandProductCtx ) permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) @@ -90,7 +87,7 @@ func TestDistPermutationNoFragment(t *testing.T) { initialComp := wizard.Compile(initialDefine) moduleAComp := wizard.Compile(moduleADefine) - + moduleAProve := func(run *wizard.ProverRuntime) { runS = run run.AssignColumn("MODULE_A.A0", smartvectors.ForTest(1, 2, 3, 4)) @@ -106,38 +103,37 @@ func TestDistPermutationNoFragment(t *testing.T) { } } - func TestDistPermutationFragment(t *testing.T) { var ( - runS *wizard.ProverRuntime - G ifaces.Query + runS *wizard.ProverRuntime + G ifaces.Query permCtx *dist_permutation.PermutationIntoGrandProductCtx ) permCtx = dist_permutation.NewPermutationIntoGrandProductCtx(dist_permutation.Settings{MaxNumOfQueryPerModule: 4}) initialDefine := func(builder *wizard.Builder) { A := [][]ifaces.Column{ {builder.RegisterCommit("MODULE_A.A00", 4), - builder.RegisterCommit("MODULE_A.A10", 4), - builder.RegisterCommit("MODULE_A.A20", 4)}, + builder.RegisterCommit("MODULE_A.A10", 4), + builder.RegisterCommit("MODULE_A.A20", 4)}, {builder.RegisterCommit("MODULE_A.A01", 4), - builder.RegisterCommit("MODULE_A.A11", 4), - builder.RegisterCommit("MODULE_A.A21", 4)}, + builder.RegisterCommit("MODULE_A.A11", 4), + builder.RegisterCommit("MODULE_A.A21", 4)}, } B := [][]ifaces.Column{ {builder.RegisterCommit("MODULE_B.B00", 4), - builder.RegisterCommit("MODULE_B.B10", 4), - builder.RegisterCommit("MODULE_B.B20", 4),}, + builder.RegisterCommit("MODULE_B.B10", 4), + builder.RegisterCommit("MODULE_B.B20", 4)}, {builder.RegisterCommit("MODULE_B.B01", 4), - builder.RegisterCommit("MODULE_B.B11", 4), - builder.RegisterCommit("MODULE_B.B21", 4),}, + builder.RegisterCommit("MODULE_B.B11", 4), + builder.RegisterCommit("MODULE_B.B21", 4)}, } C := [][]ifaces.Column{ {builder.RegisterCommit("MODULE_C.C00", 4), - builder.RegisterCommit("MODULE_C.C10", 4), - builder.RegisterCommit("MODULE_C.C20", 4),}, + builder.RegisterCommit("MODULE_C.C10", 4), + builder.RegisterCommit("MODULE_C.C20", 4)}, {builder.RegisterCommit("MODULE_C.C01", 4), - builder.RegisterCommit("MODULE_C.C11", 4), - builder.RegisterCommit("MODULE_C.C21", 4),}, + builder.RegisterCommit("MODULE_C.C11", 4), + builder.RegisterCommit("MODULE_C.C21", 4)}, } _ = builder.CompiledIOP.InsertFragmentedPermutation(0, "P_MOD_A_MOD_B", A, B) _ = builder.CompiledIOP.InsertFragmentedPermutation(0, "P_MOD_C_MOD_A", C, A) @@ -155,7 +151,7 @@ func TestDistPermutationFragment(t *testing.T) { initialComp := wizard.Compile(initialDefine) moduleAComp := wizard.Compile(moduleADefine) - + moduleAProve := func(run *wizard.ProverRuntime) { runS = run run.AssignColumn("MODULE_A.A00", smartvectors.ForTest(1, 2, 3, 4)) diff --git a/prover/protocol/distributed/compiler/permutation/settings.go b/prover/protocol/distributed/compiler/permutation/settings.go index 6f2c6ab00..a19a6b3af 100644 --- a/prover/protocol/distributed/compiler/permutation/settings.go +++ b/prover/protocol/distributed/compiler/permutation/settings.go @@ -1,6 +1,6 @@ package dist_permutation type Settings struct { -// Maximum number of permutation queries per module + // Maximum number of permutation queries per module MaxNumOfQueryPerModule int } diff --git a/prover/protocol/distributed/compiler/projection/projection.go b/prover/protocol/distributed/compiler/projection/projection.go index b0367c57b..20f705d66 100644 --- a/prover/protocol/distributed/compiler/projection/projection.go +++ b/prover/protocol/distributed/compiler/projection/projection.go @@ -1,6 +1,5 @@ package projection -======= import ( "github.com/consensys/linea-monorepo/prover/protocol/coin" "github.com/consensys/linea-monorepo/prover/protocol/wizard" diff --git a/prover/protocol/distributed/distributed.go b/prover/protocol/distributed/distributed.go index 67e007a8d..daed7e542 100644 --- a/prover/protocol/distributed/distributed.go +++ b/prover/protocol/distributed/distributed.go @@ -9,7 +9,7 @@ import ( "github.com/consensys/linea-monorepo/prover/protocol/wizard" ) -type moduleName = string +type ModuleName = string type DistributedWizard struct { // initializedWizard @@ -35,6 +35,8 @@ type ModuleDiscoverer interface { NbModules() int ModuleList(comp *wizard.CompiledIOP) []ModuleName FindModule(col ifaces.Column) ModuleName + // given a query and a module name it checks if the query is inside the module + QueryIsInModule(ifaces.Query, ModuleName) bool } // This transforms the initial wizard. So it is not really the initial @@ -72,7 +74,7 @@ func Distribute(initialWizard *wizard.CompiledIOP, disc ModuleDiscoverer, maxSeg // it should scan comp and based on module name build compiledIOP for LPP and for GL. func extractDistModule( comp *wizard.CompiledIOP, disc ModuleDiscoverer, - moduleName moduleName, + moduleName ModuleName, maxSegmentSize, maxNumSegment int, ) DistributedModule { // initialize two compiledIOPs, for LPP and GL. @@ -141,4 +143,4 @@ func prepare(comp *wizard.CompiledIOP) { innerproduct.Compile(comp) // prepareLookup(comp) -} \ No newline at end of file +} diff --git a/prover/protocol/distributed/module_discover.go b/prover/protocol/distributed/module_discover.go index 41393e0d2..b2271d6e3 100644 --- a/prover/protocol/distributed/module_discover.go +++ b/prover/protocol/distributed/module_discover.go @@ -19,7 +19,7 @@ func (split HorizontalSplitting) Split(comp *wizard.CompiledIOP) { } // QueryIsInModule checks if the given query is inside the given module -func (split HorizontalSplitting) QueryIsInModule(ifaces.Query, moduleName) bool { +func (split HorizontalSplitting) QueryIsInModule(ifaces.Query, ModuleName) bool { panic("unimplemented") } diff --git a/prover/protocol/distributed/module_discoverer/module_discoverer.go b/prover/protocol/distributed/module_discoverer/period_separating_module_discoverer.go similarity index 90% rename from prover/protocol/distributed/module_discoverer/module_discoverer.go rename to prover/protocol/distributed/module_discoverer/period_separating_module_discoverer.go index 9eb386522..1fce3f679 100644 --- a/prover/protocol/distributed/module_discoverer/module_discoverer.go +++ b/prover/protocol/distributed/module_discoverer/period_separating_module_discoverer.go @@ -67,3 +67,9 @@ func (p *PeriodSeperatingModuleDiscoverer) FindModule(col ifaces.Column) ModuleN } return "no column found" // Return a default or error value } + +// QueryIsInModule checks if the given query is inside the given module +func (p *PeriodSeperatingModuleDiscoverer) QueryIsInModule(ifaces.Query, ModuleName) bool { + panic("unimplemented") + +} diff --git a/prover/protocol/query/grand_product.go b/prover/protocol/query/grand_product.go index bb00ce163..9ad6e885c 100644 --- a/prover/protocol/query/grand_product.go +++ b/prover/protocol/query/grand_product.go @@ -13,7 +13,7 @@ import ( ) // The GrandProduct query is obtained by process all the permuation queries specific to a target module. -// We store the randomised symbolic products of A and B of permuation queries combinedly +// We store the randomised symbolic products of A and B of permuation queries combinedly // into the Numerators and the Denominators of the GrandProduct query type GrandProduct struct { ID ifaces.QueryID @@ -40,12 +40,12 @@ type GrandProductParams struct { // Returns: // - A pointer to a new instance of GrandProduct. func NewGrandProduct(round int, id ifaces.QueryID, numerators, denominators []*symbolic.Expression) *GrandProduct { - return &GrandProduct{ - ID: id, - Numerators: numerators, - Denominators: denominators, - Round: round, - } + return &GrandProduct{ + ID: id, + Numerators: numerators, + Denominators: denominators, + Round: round, + } } // Constructor for grand product query parameters @@ -55,7 +55,7 @@ func NewGrandProductParams(y field.Element) GrandProductParams { // Name returns the unique identifier of the GrandProduct query. func (g GrandProduct) Name() ifaces.QueryID { - return g.ID + return g.ID } // Updates a Fiat-Shamir state @@ -73,39 +73,39 @@ func (gp GrandProductParams) UpdateFS(fs *fiatshamir.State) { // Returns: // - An error if the grand product query is not satisfied, or nil if it is satisfied. func (g *GrandProduct) Check(run ifaces.Runtime) error { - var ( - numNumerators = len(g.Numerators) - numDenominators = len(g.Denominators) - numProd = symbolic.NewConstant(1) - denProd = symbolic.NewConstant(1) - ) + var ( + numNumerators = len(g.Numerators) + numDenominators = len(g.Denominators) + numProd = symbolic.NewConstant(1) + denProd = symbolic.NewConstant(1) + ) - for i := 0; i < numNumerators; i++ { - numProd = symbolic.Mul(numProd, g.Numerators[i]) - } - for j := 0; j < numDenominators; j++ { - denProd = symbolic.Mul(denProd, g.Denominators[j]) - } - params := run.GetParams(g.ID).(GrandProductParams) - numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() - denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() - numProdFr := numProdFrVec[0] - denProdFr := denProdFrVec[0] - if len(numProdFrVec) > 1 { - for i := 1; i < len(numProdFrVec); i++ { - numProdFr.Mul(&numProdFr, &numProdFrVec[i]) - } - } - if len(numProdFrVec) > 1 { - for j := 1; j < len(denProdFrVec); j++ { - denProdFr.Mul(&denProdFr, &denProdFrVec[j]) - } - } - if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { - return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, param.Y = %v", g.ID, numProdFr, denProdFr, params.Y) - } + for i := 0; i < numNumerators; i++ { + numProd = symbolic.Mul(numProd, g.Numerators[i]) + } + for j := 0; j < numDenominators; j++ { + denProd = symbolic.Mul(denProd, g.Denominators[j]) + } + params := run.GetParams(g.ID).(GrandProductParams) + numProdFrVec := column.EvalExprColumn(run, numProd.Board()).IntoRegVecSaveAlloc() + denProdFrVec := column.EvalExprColumn(run, denProd.Board()).IntoRegVecSaveAlloc() + numProdFr := numProdFrVec[0] + denProdFr := denProdFrVec[0] + if len(numProdFrVec) > 1 { + for i := 1; i < len(numProdFrVec); i++ { + numProdFr.Mul(&numProdFr, &numProdFrVec[i]) + } + } + if len(numProdFrVec) > 1 { + for j := 1; j < len(denProdFrVec); j++ { + denProdFr.Mul(&denProdFr, &denProdFrVec[j]) + } + } + if numProdFr != *denProdFr.Mul(&denProdFr, ¶ms.Y) { + return fmt.Errorf("the grand product query %v is not satisfied, numProd = %v, denProd = %v, param.Y = %v", g.ID, numProdFr, denProdFr, params.Y) + } - return nil + return nil } func (g GrandProduct) CheckGnark(api frontend.API, run ifaces.GnarkRuntime) { From 28ac18c62aee6d4ea0993739bde778491a0ab8c1 Mon Sep 17 00:00:00 2001 From: arijitdutta67 Date: Thu, 19 Dec 2024 17:03:57 +0530 Subject: [PATCH 21/21] linter fix --- prover/protocol/distributed/compiler/global/global.go | 1 + prover/protocol/distributed/compiler/permutation/permutation.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/prover/protocol/distributed/compiler/global/global.go b/prover/protocol/distributed/compiler/global/global.go index 505698ab8..37f1d6070 100644 --- a/prover/protocol/distributed/compiler/global/global.go +++ b/prover/protocol/distributed/compiler/global/global.go @@ -2,6 +2,7 @@ package global import "github.com/consensys/linea-monorepo/prover/protocol/wizard" +// CompileDist compiles the global queries distributedly. func CompileDist(comp *wizard.CompiledIOP) { panic("unimplemented") } diff --git a/prover/protocol/distributed/compiler/permutation/permutation.go b/prover/protocol/distributed/compiler/permutation/permutation.go index 78834876e..7e822489d 100644 --- a/prover/protocol/distributed/compiler/permutation/permutation.go +++ b/prover/protocol/distributed/compiler/permutation/permutation.go @@ -164,7 +164,7 @@ func computeFactor(aOrB [][]ifaces.Column, isMultiColumn bool, alpha, beta *coin var ( numFrag = len(aOrB) factor = symbolic.NewConstant(1) - fragFactor = symbolic.NewConstant(1) + fragFactor *symbolic.Expression ) for frag := range numFrag {