fix the failing projection term test (it was a single sign mistake...)

This commit is contained in:
Balazs Komuves 2026-06-15 02:02:34 +02:00
parent c189df8a15
commit 7b01f27529
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
4 changed files with 82 additions and 57 deletions

View File

@ -47,17 +47,9 @@ func crossTermCoeffs*(D: Domain, As: seq[F], Bs: seq[F]) : seq[F] =
let ABs = pointwiseProdFr( As, Bs )
var Ahat = forwardNTT( As , D )
var Bhat = forwardNTT( Bs , D )
var ABhat = forwardNTT( ABs , D )
inplaceMulByFFTofWVecBar( Ahat )
inplaceMulByFFTofWVecBar( Bhat )
inplaceMulByFFTofWVecBar( ABhat )
let Aconv = inverseNTT( Ahat , D)
let Bconv = inverseNTT( Bhat , D)
let ABconv = inverseNTT( ABhat , D)
let Aconv = fieldConvolveWithWVecBar( D , As )
let Bconv = fieldConvolveWithWVecBar( D , Bs )
let ABconv = fieldConvolveWithWVecBar( D , ABs )
let sumW = sumOfWVec( N )

View File

@ -30,64 +30,25 @@ import groth16/dynamic/shared
#-------------------------------------------------------------------------------
# computes the vectors A*z, B*z (but skips C*z)
func buildPartialAB*( zkey: ZKey, pwitness: seq[Option[Fr[BN254_Snarks]]] ): PartialAB =
let hdr: GrothHeader = zkey.header
let domSize = hdr.domainSize
var valuesAz = newSeq[Fr[BN254_Snarks]](domSize)
var valuesBz = newSeq[Fr[BN254_Snarks]](domSize)
# we also compute the image of the complement of the partial witness under A and B
var complImageA = newSeq[bool](domSize)
var complImageB = newSeq[bool](domSize)
for i in 0..<domSize:
complImageA[i] = false
complImageB[i] = false
for entry in zkey.coeffs:
case entry.matrix
of MatrixA:
if isSome(pwitness[entry.col]):
valuesAz[entry.row] += entry.coeff * pwitness[entry.col].unsafeGet()
else:
complImageA[entry.row] = true
of MatrixB:
if isSome(pwitness[entry.col]):
valuesBz[entry.row] += entry.coeff * pwitness[entry.col].unsafeGet()
else:
complImageB[entry.row] = true
else: raise newException(AssertionDefect, "fatal error")
return PartialAB( valuesAz:valuesAz,
valuesBz:valuesBz,
complImageA:complImageA,
complImageB:complImageB )
#-------------------------------------------------------------------------------
func projectionElementsV1*(setup: DynaSetupV1, D: Domain, As: seq[F], complImage: seq[bool]): seq[G1] =
let N = D.domainSize
var Us: seq[G1] = newSeq[G1]( N )
# reverse indexed wvec: wvecBar[i] = wvec[-i]
let wvecBar: seq[F] = fftReverseVec( setup.weightVec )
# # reverse indexed wvec: wvecBar[i] = wvec[-i]
# let wvecBar: seq[F] = fftReverseVec( setup.weightVec )
let fldN : F = intToFr( N )
let negSumW : F = (fldN - oneFr) / (fldN + fldN)
let fldN : F = intToFr( N )
let sumW : F = sumOfWVec( N )
let WBarStarA : seq[F] = fieldConvolution( As , wvecBar )
let ALstarW : seq[G1] = groupConvolution( setup.weightVec , pointwiseScaleG1( As , setup.pointsDeltaLZ ) )
let WBarStarA : seq[F] = fieldConvolveWithWVecBar( D , As )
let ALstarW : seq[G1] = groupConvolveWithWVec( D , pointwiseScaleG1( As , setup.pointsDeltaLZ ) )
# 2*d scalar multiplications + the group convolution above
for k in 0..<N:
# we only compute for the _image of_ the complementer of the partial witness
if complImage[k]:
let cf : F = WBarStarA[k] - As[k] * negSumW
let cf : F = WBarStarA[k] - As[k] * sumW
Us[k] = ALstarW[k] - (As[k] ** setup.wConvDeltaLZ[k]) + (cf ** setup.pointsDeltaLZ[k])
return Us

View File

@ -8,6 +8,8 @@ import groth16/bn128
import groth16/bn128/arrays
import groth16/math/domain
import groth16/math/ntt
import groth16/math/group_fft
import groth16/math/poly
#import groth16/math/convolution
@ -80,6 +82,51 @@ proc inplaceMulByFFTofWVecBar*( xs: var seq[F] ) =
let u = c + intToFr(i) * invN
xs[k] *= u
#---------------------------------------
# pointwise multiply group elements by `FFT[W]_k = (k + (1-N)/2) / N`
proc inplaceScalarMulByFFTofWVec*( gs: var seq[G1] ) =
let N = gs.len
let fN = intToFr( N )
let invN = invFr( fN )
let c = divBy2Fr(oneFr - fN) * invN
for k in 0..<N:
let u = c + intToFr(k) * invN
gs[k] = u ** gs[k]
# pointwise multiply group elements by `FFT[Wbar]_k = Bar[FFT[W]]_k`
proc inplaceScalarMulByFFTofWVecBar*( gs: var seq[G1] ) =
let N = gs.len
let fN = intToFr( N )
let invN = invFr( fN )
let c = divBy2Fr(oneFr - fN) * invN
for k in 0..<N:
let i = (if k==0: 0 else: N-k)
let u = c + intToFr(i) * invN
gs[k] = u ** gs[k]
#---------------------------------------
proc fieldConvolveWithWVec*( D: Domain, xs: seq[F] ): seq[F] =
var xsHat = forwardNTT( xs , D )
inplaceMulByFFTofWVec( xsHat )
return inverseNTT( xsHat , D)
proc fieldConvolveWithWVecBar*( D: Domain, xs: seq[F] ): seq[F] =
var xsHat = forwardNTT( xs , D )
inplaceMulByFFTofWVecBar( xsHat )
return inverseNTT( xsHat , D)
proc groupConvolveWithWVec*( D: Domain, gs: seq[G1] ): seq[G1] =
var gsHat = forwardGroupFFT( gs , D )
inplaceScalarMulByFFTofWVec( gsHat )
return inverseGroupFFT( gsHat , D)
proc groupConvolveWithWVecBar*( D: Domain, gs: seq[G1] ): seq[G1] =
var gsHat = forwardGroupFFT( gs , D )
inplaceScalarMulByFFTofWVecBar( gsHat )
return inverseGroupFFT( gsHat , D)
#-------------------------------------------------------------------------------
# computes the vectors A*z, B*z (but skips C*z)

View File

@ -13,6 +13,7 @@ import groth16/bn128/arrays
import groth16/math/domain
import groth16/math/ntt
import groth16/math/poly
import groth16/math/convolution
import groth16/dynamic/types
import groth16/dynamic/shared
@ -62,6 +63,30 @@ suite "dynamic proof (Dynark) tests":
let ys = forwardNTT( calculateWVecBar(D) , D )
check isEqualFrSeq( xs , ys)
test "field convolution with Wvec":
let xs = randFrSeq( N )
let lhs = fieldConvolveWithWVec( D , xs )
let rhs = fieldConvolution( xs , calculateWVec(D) )
check isEqualFrSeq( lhs , rhs )
test "field convolution with WvecBar":
let xs = randFrSeq( N )
let lhs = fieldConvolveWithWVecBar( D , xs )
let rhs = fieldConvolution( xs , calculateWVecBar(D) )
check isEqualFrSeq( lhs , rhs )
test "group convolution with Wvec":
let gs = randG1Seq( N )
let lhs = groupConvolveWithWVec( D , gs )
let rhs = groupConvolution( calculateWVec(D) , gs )
check isEqualG1Seq( lhs , rhs )
test "group convolution with WvecBar":
let gs = randG1Seq( N )
let lhs = groupConvolveWithWVecBar( D , gs )
let rhs = groupConvolution( calculateWVecBar(D) , gs )
check isEqualG1Seq( lhs , rhs )
test "expansion of the product of Lagrange polynomials":
var ok = true
for i in 0..<N: