diff --git a/groth16/dynamic/finish.nim b/groth16/dynamic/finish.nim index 8247581..eb72eb8 100644 --- a/groth16/dynamic/finish.nim +++ b/groth16/dynamic/finish.nim @@ -28,6 +28,7 @@ import groth16/files/witness import groth16/math/domain import groth16/math/ntt import groth16/math/poly +import groth16/math/convolution import groth16/prover/types import groth16/prover/shared @@ -111,6 +112,9 @@ proc finishDynaProofWithMaskV1*( zkey: ZKey, wtns: Witness, dynaPreProof: DynaPr let partialMask = dynaPreProof.partialProof.partial_mask + let wvec = dynaPreProof.dynaSetup.weightVec + let wvecRev = fftReverseVec( wvec ) + var deltaAB: OnlyAB var witnessDelta: seq[Option[F]] = newSeq[Option[F]]( M ) withMeasureTime(printTimings,"building deltaAz, deltaBz"): @@ -125,18 +129,67 @@ proc finishDynaProofWithMaskV1*( zkey: ZKey, wtns: Witness, dynaPreProof: DynaPr withMeasureTime(printTimings,"finishing the linear terms"): proof = finishPartialProofWithMaskGeneric( false, zkey, wtns, dynaPreProof.partialProof, mask, pool, false ) - var nonlin: G1 + var nonlin: G1 = infG1 + +#[ + + --- this only makes sense if we can restrict to a subgroup --- + var cs: seq[F] withMeasureTime(printTimings,"computing the nonlinear \"cross\" term"): withMeasureTime(printTimings," - computing the cross coeffs took"): cs = crossTermCoeffs(D , deltaAB.valuesAz , deltaAB.valuesBz ) withMeasureTime(printTimings," - computing the cross MSM took"): nonlin = msmMultiThreadedG1( cs , dynaPreProof.dynaSetup.pointsDeltaLZ , pool ) - + echo " - nonzero coefficients in deltaA = " & $countNonZerosFr(deltaAB.valuesAz) echo " - nonzero coefficients in deltaB = " & $countNonZerosFr(deltaAB.valuesBz) echo " - nonzero coefficients in the cross-term = " & $countNonZerosFr(cs) +]# + + # following the Dynark paper + withMeasureTime(printTimings,"computing the nonlinear \"cross\" term (Dynark-style)"): + + let idxs = trueIndices( dynaPreProof.deltaImages.imageAB ) + let K = idxs.len + + withMeasureTime(printTimings," - computing the diagonal part of the cross-term"): + var cs: seq[F] = newSeq[F ]( K ) + var ps: seq[G1] = newSeq[G1]( K ) + for (k,i) in idxs.pairs: + cs[k] = deltaAB.valuesAz[i] * deltaAB.valuesBz[i] + ps[k] = dynaPreProof.dynaSetup.diagPhiPoints[i] + nonlin += msmMultiThreadedG1( cs , ps , pool ) + + withMeasureTime(printTimings," - computing the off-diagonal part of the cross-term"): + let As = deltaAB.valuesAz + let Bs = deltaAB.valuesBz + let AstarW = fieldConvolution( As , wvecRev ) + let BstarW = fieldConvolution( Bs , wvecRev ) # TODO: make this sparse somehow??! + + var ds: seq[F] = newSeq[F]( K ) + for (k,i) in idxs.pairs: + ds[k] = As[i] * BstarW[i] + Bs[i] * AstarW[i] + + let ls = selectTrues( dynaPreProof.deltaImages.imageAB , dynaPreProof.dynaSetup.pointsDeltaLZ ) + nonlin += msmMultiThreadedG1( ds , ls , pool ) + +#[ + var ds: seq[F] = newSeq[F ]( K ) + var qs: seq[G1] = newSeq[G1]( K ) + for (k,i) in idxs.pairs: + var x: F = zeroFr + for j in idxs: + if (i != j): + let ab = deltaAB.valuesAz[i] * deltaAB.valuesBz[j] + + deltaAB.valuesAz[j] * deltaAB.valuesBz[i] + x += ab * wvec[ safeMod( j - i , N ) ] + ds[k] = x + qs[k] = dynaPreProof.dynaSetup.pointsDeltaLZ[i] + nonlin += msmMultiThreadedG1( ds , qs , pool ) + ]# + withMeasureTime(printTimings,"computing the nonlinear \"projection\" terms"): let comprAz = selectTrues( dynaPreProof.deltaImages.imageA , deltaAB.valuesAz ) let comprBz = selectTrues( dynaPreProof.deltaImages.imageB , deltaAB.valuesBz ) diff --git a/groth16/dynamic/setup.nim b/groth16/dynamic/setup.nim index f0b2739..1f3aa6f 100644 --- a/groth16/dynamic/setup.nim +++ b/groth16/dynamic/setup.nim @@ -3,7 +3,10 @@ # import constantine/named/properties_fields +import taskpools + import groth16/bn128 +import groth16/bn128/arrays import groth16/misc import groth16/math/domain @@ -26,15 +29,54 @@ import groth16/dynamic/shared #------------------------------------------------------------------------------- +# the points `delta^{-1} * phi_ii(tau) * (tau^N - 1) * g1` as in the Dynark paper +# +# where +# +# > phi_ii = - sum_j phi_ij = - sum_j ( W[j-i]*L[i] + W[i-j]*L[j] ) +# > phi_ij = W[j-i]*L[i] + W[i-j]*L[j] +# +func calculateDiagPhiFFT*( wvec: seq[F], deltaLZ: seq[G1] ): seq[G1] = + let N = wvec.len + assert( N == deltaLZ.len ) + + let sumW = sumSeqFr( wvec ) + + var hs: seq[G1] = groupConvolution( wvec , deltaLZ ) + for i in 0..