@@ -184,25 +184,63 @@ func (p *ipaProver) Prove() (*IPA, error) {
184184// of the left vector and right is a function of right vector.
185185// Both vectors are committed in com which is passed as a parameter to reduce
186186func (p * ipaProver ) reduce (X , com * mathlib.G1 ) (* mathlib.Zr , * mathlib.Zr , []* mathlib.G1 , []* mathlib.G1 , error ) {
187- leftGen , rightGen := CloneGenerators (p .LeftGenerators , p .RightGenerators )
188-
189187 left := p .leftVector
190188 right := p .rightVector
191189
192190 LArray := make ([]* mathlib.G1 , p .NumberOfRounds )
193191 RArray := make ([]* mathlib.G1 , p .NumberOfRounds )
192+ xList := make ([]* mathlib.Zr , 0 , p .NumberOfRounds )
193+
194194 for i := range p .NumberOfRounds {
195195 // in each round the size of the vector is reduced by 2
196- n := len (leftGen ) / 2
197- leftIP := math .InnerProduct (left [:n ], right [n :], p .Curve )
198- rightIP := math .InnerProduct (left [n :], right [:n ], p .Curve )
199- // LArray[i] is a commitment to left[:n], right[n:] and their inner product
200- LArray [i ] = CommitVectorPlusOne (left [:n ], right [n :], leftGen [n :], rightGen [:n ], leftIP , X , p .Curve )
201- // LArray[i].Add(X.Mul(leftIP))
196+ n_current := len (left ) / 2
197+ leftIP := math .InnerProduct (left [:n_current ], right [n_current :], p .Curve )
198+ rightIP := math .InnerProduct (left [n_current :], right [:n_current ], p .Curve )
199+
200+ var s , sInv []* mathlib.Zr
201+ if i == 0 {
202+ s = []* mathlib.Zr {math .One (p .Curve )}
203+ sInv = []* mathlib.Zr {math .One (p .Curve )}
204+ } else {
205+ s , sInv = ComputeSVector (1 << i , xList , p .Curve )
206+ }
207+
208+ pointsL := make ([]* mathlib.G1 , 0 , len (p .LeftGenerators )+ 1 )
209+ scalarsL := make ([]* mathlib.Zr , 0 , len (p .LeftGenerators )+ 1 )
210+
211+ pointsR := make ([]* mathlib.G1 , 0 , len (p .LeftGenerators )+ 1 )
212+ scalarsR := make ([]* mathlib.Zr , 0 , len (p .LeftGenerators )+ 1 )
213+
214+ for m := range 1 << i {
215+ for j := range n_current {
216+ idxG_R := j + (2 * m + 1 )* n_current
217+ idxH_L := j + 2 * m * n_current
218+
219+ pointsL = append (pointsL , p .LeftGenerators [idxG_R ], p .RightGenerators [idxH_L ])
220+ scalarsL = append (scalarsL ,
221+ p .Curve .ModMul (left [j ], s [m ], p .Curve .GroupOrder ),
222+ p .Curve .ModMul (right [n_current + j ], sInv [m ], p .Curve .GroupOrder ),
223+ )
224+
225+ idxG_L := j + 2 * m * n_current
226+ idxH_R := j + (2 * m + 1 )* n_current
227+
228+ pointsR = append (pointsR , p .LeftGenerators [idxG_L ], p .RightGenerators [idxH_R ])
229+ scalarsR = append (scalarsR ,
230+ p .Curve .ModMul (left [n_current + j ], s [m ], p .Curve .GroupOrder ),
231+ p .Curve .ModMul (right [j ], sInv [m ], p .Curve .GroupOrder ),
232+ )
233+ }
234+ }
235+
236+ pointsL = append (pointsL , X )
237+ scalarsL = append (scalarsL , leftIP )
238+
239+ pointsR = append (pointsR , X )
240+ scalarsR = append (scalarsR , rightIP )
202241
203- // RArray[i] is a commitment to left[n:], right[:n] and their inner product
204- RArray [i ] = CommitVectorPlusOne (left [n :], right [:n ], leftGen [:n ], rightGen [n :], rightIP , X , p .Curve )
205- // RArray[i].Add(X.Mul(rightIP))
242+ LArray [i ] = p .Curve .MultiScalarMul (pointsL , scalarsL )
243+ RArray [i ] = p .Curve .MultiScalarMul (pointsR , scalarsR )
206244
207245 // compute this round's challenge x
208246 array := common .GetG1Array ([]* mathlib.G1 {LArray [i ], RArray [i ]})
@@ -211,14 +249,12 @@ func (p *ipaProver) reduce(X, com *mathlib.G1) (*mathlib.Zr, *mathlib.Zr, []*mat
211249 return nil , nil , nil , nil , err
212250 }
213251 x := p .Curve .HashToZr (bytesToHash )
252+ xList = append (xList , x )
214253
215254 // compute 1/x
216255 xInv := x .Copy ()
217256 xInv .InvModOrder ()
218257
219- // reduce the generators by 1/2, as a function of the old generators and x and 1/x
220- leftGen , rightGen = reduceGenerators (leftGen , rightGen , x , xInv , p .Provider )
221-
222258 // reduce the vectors by 1/2, a function of the old vectors and x and 1/x
223259 left , right = reduceVectors (left , right , x , xInv , p .Curve )
224260
@@ -404,27 +440,6 @@ func reduceVectors(left, right []*mathlib.Zr, x, xInv *mathlib.Zr, c *mathlib.Cu
404440 return leftPrime , rightPrime
405441}
406442
407- // reduceGenerators reduces the number of generators passed in the parameters by 1/2,
408- // as a function of the old generators, x and 1/x
409- func reduceGenerators (leftGen , rightGen []* mathlib.G1 , x , xInv * mathlib.Zr , provider executor.ExecutorProvider ) ([]* mathlib.G1 , []* mathlib.G1 ) {
410- l := len (leftGen ) / 2
411- // Use the Executor abstraction so that the execution strategy can be
412- // swapped without changing this function. SerialExecutor runs each task
413- // immediately with no locks or goroutine overhead.
414- exec := provider .New ()
415- for i := range l {
416- exec .Submit (func () {
417- // G_i = G_i^{x_inv} * G_{i+l}^x
418- leftGen [i ].Mul2InPlace (xInv , leftGen [i + l ], x )
419- // H_i = H_i^x * H_{i+l}^{x_inv}
420- rightGen [i ].Mul2InPlace (x , rightGen [i + l ], xInv )
421- })
422- }
423- exec .Wait ()
424-
425- return leftGen [:l ], rightGen [:l ]
426- }
427-
428443func CommitVector (
429444 left []* mathlib.Zr ,
430445 right []* mathlib.Zr ,
0 commit comments