Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: fast path for SIS with logTwoBound: 8, logTwoDegree: 6 #416

Merged
merged 11 commits into from
Jun 30, 2023
3 changes: 1 addition & 2 deletions ecc/bls12-377/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions ecc/bls12-378/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions ecc/bls12-381/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions ecc/bls24-315/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions ecc/bls24-317/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions ecc/bn254/fr/fft/fft.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 41 additions & 6 deletions ecc/bn254/fr/sis/sis.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ type RSis struct {
LogTwoBound int

// domain for the polynomial multiplication
Domain *fft.Domain
Domain *fft.Domain
twiddleCosets []fr.Element // see fft64 and precomputeTwiddlesCoset

// d, the degree of X^{d}+1
Degree int
Expand Down Expand Up @@ -126,6 +127,10 @@ func NewRSis(seed int64, logTwoDegree, logTwoBound, maxNbElementsToHash int) (*R
bufMValues: bitset.New(uint(n)),
maxNbElementsToHash: maxNbElementsToHash,
}
if r.LogTwoBound == 8 && r.Degree == 64 {
// TODO @gbotrel fixme, that's dirty.
r.twiddleCosets = precomputeTwiddlesCoset(r.Domain.Twiddles, r.Domain.FrMultiplicativeGen)
}

// filling A
a := make([]fr.Element, n*r.Degree)
Expand All @@ -146,8 +151,6 @@ func NewRSis(seed int64, logTwoDegree, logTwoBound, maxNbElementsToHash int) (*R
r.Domain.FFT(r.Ag[i], fft.DIF, fft.OnCoset())
}
})
// TODO @gbotrel add nbtasks here; while in tests it's more convenient to parallelize
// in tensor-commitment we may not want to do that.

return r, nil
}
Expand All @@ -168,12 +171,20 @@ func (r *RSis) Sum(b []byte) []byte {
panic("buffer too large")
}

fastPath := r.LogTwoBound == 8 && r.Degree == 64

// clear the buffers of the instance.
defer r.cleanupBuffers()

m := r.bufM
mValues := r.bufMValues
limbDecomposeBytes(buf, m, r.LogTwoBound, r.Degree, mValues)

if fastPath {
// fast path.
limbDecomposeBytes8_64(buf, m, mValues)
} else {
limbDecomposeBytes(buf, m, r.LogTwoBound, r.Degree, mValues)
}

// we can hash now.
res := r.bufRes
Expand All @@ -186,7 +197,12 @@ func (r *RSis) Sum(b []byte) []byte {
continue
}
k := m[i*r.Degree : (i+1)*r.Degree]
r.Domain.FFT(k, fft.DIF, fft.OnCoset(), fft.WithNbTasks(1))
if fastPath {
// fast path.
fft64(k, r.twiddleCosets)
} else {
r.Domain.FFT(k, fft.DIF, fft.OnCoset(), fft.WithNbTasks(1))
}
mulModAcc(res, r.Ag[i], k)
}
r.Domain.FFTInverse(res, fft.DIT, fft.OnCoset(), fft.WithNbTasks(1)) // -> reduces mod Xᵈ+1
Expand Down Expand Up @@ -357,11 +373,12 @@ func limbDecomposeBytes(buf []byte, m fr.Vector, logTwoBound, degree int, mValue
// r.LogTwoBound < 64; we just use the first word of our element here,
// and set the bits from LSB to MSB.
at := fieldStart + fr.Bytes*8 - bitInField - 1

m[mPos][0] |= uint64(bitAt(at) << j)
bitInField++

// Check if mPos is zero and mark as non-zero in the bitset if not
if m[mPos][0] > 0 && mValues != nil {
if m[mPos][0] != 0 && mValues != nil {
mValues.Set(uint(mPos / degree))
}

Expand All @@ -372,3 +389,21 @@ func limbDecomposeBytes(buf []byte, m fr.Vector, logTwoBound, degree int, mValue
fieldStart += fr.Bytes * 8
}
}

// see limbDecomposeBytes; this function is optimized for the case where
// logTwoBound == 8 and degree == 64
func limbDecomposeBytes8_64(buf []byte, m fr.Vector, mValues *bitset.BitSet) {
// with logTwoBound == 8, we can actually advance byte per byte.
const degree = 64
j := 0

for startPos := fr.Bytes - 1; startPos < len(buf); startPos += fr.Bytes {
for i := startPos; i >= startPos-fr.Bytes+1; i-- {
m[j][0] = uint64(buf[i])
if m[j][0] != 0 {
mValues.Set(uint(j / degree))
}
j++
}
}
}
1 change: 1 addition & 0 deletions ecc/bn254/fr/sis/sis.sage
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ params = [
SISParams(5, 4, 4, 10),
SISParams(5, 5, 4, 10),
SISParams(5, 6, 5, 10),
# SISParams(5, 8, 6, 10),
SISParams(5, 10, 6, 10),
SISParams(5, 11, 7, 10),
SISParams(5, 12, 7, 10),
Expand Down
Loading
Loading