Skip to content

Commit 9d7eb9c

Browse files
committed
smartvector-type for product
1 parent 62438cb commit 9d7eb9c

File tree

9 files changed

+112
-9
lines changed

9 files changed

+112
-9
lines changed

prover/maths/common/smartvectors/arithmetic_gen.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ func processOperator(op operator, coeffs []int, svecs []SmartVector, p ...mempoo
110110

111111
switch {
112112
case matchedRegular == totalToMatch:
113-
return regularRes
113+
return &regularRes.Regular
114114
case matchedRegular+matchedConst == totalToMatch:
115115
// In this case, there are no windowed in the list. This means we only
116116
// need to merge the const one into the regular one before returning
117117
op.constTermIntoVec(regularRes.Regular, &constRes.val)
118-
return regularRes
118+
return &regularRes.Regular
119119
default:
120120

121121
// If windowRes is a regular (can happen if all windows arguments cover the full circle)

prover/protocol/compiler/innerproduct/context.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,8 @@ func compileForSize(
9191
}
9292
}
9393

94-
// @Azam the following function is commented out due to the issue https://github.com/Consensys/linea-monorepo/issues/192
95-
// ctx.Collapsed = symbolic.NewPolyEval(batchingCoin.AsVariable(), pairProduct)
96-
res := symbolic.NewConstant(0)
97-
for i := len(pairProduct) - 1; i >= 0; i-- {
98-
res = symbolic.Mul(res, batchingCoin)
99-
res = symbolic.Add(res, pairProduct[i])
100-
}
94+
// random linear combination over the pairs of inner-product.
95+
res := symbolic.NewPolyEval(batchingCoin.AsVariable(), pairProduct)
10196

10297
ctx.Collapsed = res
10398
ctx.CollapsedBoard = ctx.Collapsed.Board()
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package wizardutils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/consensys/linea-monorepo/prover/maths/common/smartvectors"
7+
"github.com/consensys/linea-monorepo/prover/maths/field"
8+
"github.com/consensys/linea-monorepo/prover/protocol/coin"
9+
"github.com/consensys/linea-monorepo/prover/protocol/column/verifiercol"
10+
"github.com/consensys/linea-monorepo/prover/protocol/compiler/dummy"
11+
"github.com/consensys/linea-monorepo/prover/protocol/ifaces"
12+
"github.com/consensys/linea-monorepo/prover/protocol/wizard"
13+
"github.com/consensys/linea-monorepo/prover/symbolic"
14+
"github.com/stretchr/testify/assert"
15+
)
16+
17+
func TestWizarldutils(t *testing.T) {
18+
var res1, res11, res2, res22 *symbolic.Expression
19+
define := func(b *wizard.Builder) {
20+
var (
21+
size = 4
22+
col1 = b.RegisterCommit("P1", size)
23+
col2 = b.RegisterCommit("P2", size)
24+
25+
col5 = b.RegisterPrecomputed("P3", smartvectors.ForTest(1, 0, 1, 1))
26+
col6 = verifiercol.NewConstantCol(field.NewElement(3), size)
27+
28+
coin = b.RegisterRandomCoin(coin.Namef("Coin"), coin.Field)
29+
)
30+
31+
// PolyEval over columns
32+
res1 = symbolic.NewPolyEval(coin.AsVariable(), []*symbolic.Expression{ifaces.ColumnAsVariable(col1), ifaces.ColumnAsVariable(col2)})
33+
res11 = linCom(coin.AsVariable(), []*symbolic.Expression{ifaces.ColumnAsVariable(col1), ifaces.ColumnAsVariable(col2)})
34+
35+
// PolyEval over PolyEval and Mul.
36+
expr := symbolic.Mul(col6, col5, coin)
37+
res2 = symbolic.NewPolyEval(coin.AsVariable(), []*symbolic.Expression{res1, expr})
38+
res22 = linCom(coin.AsVariable(), []*symbolic.Expression{res1, expr})
39+
40+
}
41+
prover := func(run *wizard.ProverRuntime) {
42+
var (
43+
col1 = smartvectors.ForTest(1, 2, 1, 0)
44+
col2 = smartvectors.ForTest(1, 1, 3, 1)
45+
)
46+
run.AssignColumn("P1", col1)
47+
run.AssignColumn("P2", col2)
48+
49+
run.GetRandomCoinField(coin.Namef("Coin"))
50+
51+
res1Wit := EvalExprColumn(run, res1.Board()).IntoRegVecSaveAlloc()
52+
res11Wit := EvalExprColumn(run, res11.Board()).IntoRegVecSaveAlloc()
53+
for i := range res11Wit {
54+
if res1Wit[i].Cmp(&res11Wit[i]) != 0 {
55+
panic("err")
56+
}
57+
}
58+
59+
res2Wit := EvalExprColumn(run, res2.Board()).IntoRegVecSaveAlloc()
60+
res22Wit := EvalExprColumn(run, res22.Board()).IntoRegVecSaveAlloc()
61+
for i := range res11Wit {
62+
if res2Wit[i].Cmp(&res22Wit[i]) != 0 {
63+
panic("err")
64+
}
65+
}
66+
67+
}
68+
69+
comp := wizard.Compile(define, dummy.Compile)
70+
proof := wizard.Prove(comp, prover)
71+
assert.NoErrorf(t, wizard.Verify(comp, proof), "invalid proof")
72+
}
73+
74+
func linCom(x *symbolic.Expression, coeff []*symbolic.Expression) *symbolic.Expression {
75+
res := symbolic.NewConstant(0)
76+
for i := len(coeff) - 1; i >= 0; i-- {
77+
res = symbolic.Mul(res, x)
78+
res = symbolic.Add(res, coeff[i])
79+
}
80+
return res
81+
}

prover/symbolic/constant.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ type Constant struct {
1616
Val field.Element
1717
}
1818

19+
// Name returns the name for the Constant [Operator].
20+
func (Constant) Name() string {
21+
return "Constant"
22+
}
23+
1924
// Degree implements the [Operator] interface
2025
func (Constant) Degree([]int) int {
2126
panic("we never call it for a constant")

prover/symbolic/expression.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ type Operator interface {
6565
Degree([]int) int
6666
// GnarkEval returns an evaluation of the operator in a gnark circuit.
6767
GnarkEval(frontend.API, []frontend.Variable) frontend.Variable
68+
// Name of the operator, used for debugging.
69+
Name() string
6870
}
6971

7072
// Board pins down the expression into an ExpressionBoard. This converts the

prover/symbolic/lincomb.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ func NewLinComb(items []*Expression, coeffs []int) *Expression {
8989
return e
9090
}
9191

92+
// Name outputs the name for the LinComb [Operator]
93+
func (LinComb) Name() string {
94+
return "LinComb"
95+
}
96+
9297
// Degree implements the [Operator] interface and returns the maximum degree of
9398
// the underlying expression.
9499
func (LinComb) Degree(inputDegrees []int) int {

prover/symbolic/polyeval.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ func NewPolyEval(x *Expression, coeffs []*Expression) *Expression {
5252
}
5353
}
5454

55+
// Name outputs the name for the PolyEval [Operator].
56+
func (PolyEval) Name() string {
57+
return "PolyEval"
58+
}
59+
5560
/*
5661
Returns the degree of the operation given, as input, the degree of the children
5762
*/

prover/symbolic/product.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ func NewProduct(items []*Expression, exponents []int) *Expression {
112112
return e
113113
}
114114

115+
// Name outputs the name for the Product [Operator]
116+
func (Product) Name() string {
117+
return "Product"
118+
}
119+
115120
// Degree implements the [Operator] interface and returns the sum of the degree
116121
// of all the operands weighted by the exponents.
117122
func (prod Product) Degree(inputDegrees []int) int {

prover/symbolic/variable.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ type Variable struct {
2828
Metadata Metadata
2929
}
3030

31+
// Name outputs the name for the Variable [Operator].
32+
func (Variable) Name() string {
33+
return "Variable"
34+
}
35+
3136
// Degree implements the [Operator] interface. Yet, this panics if this is called.
3237
func (Variable) Degree([]int) int {
3338
panic("we never call it for a variable")

0 commit comments

Comments
 (0)