This commit is contained in:
Jean-Philippe Bossuat
2023-03-30 12:33:47 +02:00
parent 3549569ba8
commit e8a2746ac8
14 changed files with 372 additions and 35 deletions

View File

@@ -68,8 +68,12 @@ func (btp *Bootstrapper) Bootstrap(ctIn *rlwe.Ciphertext) (ctOut *rlwe.Ciphertex
// 2^(d-n) * e + 2^(d-2n) * e'
btp.MultByConst(tmp, btp.params.QiFloat64(tmp.Level())/float64(uint64(1<<16)), tmp)
tmp.Scale = tmp.Scale.Mul(rlwe.NewScale(btp.params.Q()[tmp.Level()]))
btp.Rescale(tmp, btp.params.DefaultScale(), tmp)
if err := btp.Rescale(tmp, btp.params.DefaultScale(), tmp); err != nil {
panic(err)
}
// [2^d * M + 2^(d-2n) * e'] <- [2^d * M + 2^(d-n) * e] - [2^(d-n) * e + 2^(d-2n) * e']
btp.Add(ctOut, tmp, ctOut)

View File

@@ -1,12 +1,22 @@
package ckks
import (
"fmt"
"math/bits"
"unsafe"
)
const (
minVecLenForLoopUnrolling = 16
)
// SpecialiFFTVec performs the CKKS special inverse FFT transform in place.
func SpecialiFFTVec(values []complex128, N, M int, rotGroup []int, roots []complex128) {
if len(values) < N || len(rotGroup) < N || len(roots) < M+1 {
panic(fmt.Sprintf("invalid call of SpecialiFFTVec: len(values)=%d or len(rotGroup)=%d < N=%d or len(roots)=%d < M+1=%d", len(values), len(rotGroup), N, len(roots), M))
}
logN := int(bits.Len64(uint64(N))) - 1
logM := int(bits.Len64(uint64(M))) - 1
for loglen := logN; loglen > 0; loglen-- {
@@ -31,6 +41,11 @@ func SpecialiFFTVec(values []complex128, N, M int, rotGroup []int, roots []compl
// SpecialFFTVec performs the CKKS special FFT transform in place.
func SpecialFFTVec(values []complex128, N, M int, rotGroup []int, roots []complex128) {
if len(values) < N || len(rotGroup) < N || len(roots) < M+1 {
panic(fmt.Sprintf("invalid call of SpecialFFTVec: len(values)=%d or len(rotGroup)=%d < N=%d or len(roots)=%d < M+1=%d", len(values), len(rotGroup), N, len(roots), M))
}
SliceBitReverseInPlaceComplex128(values, N)
logN := int(bits.Len64(uint64(N))) - 1
logM := int(bits.Len64(uint64(M))) - 1
@@ -52,6 +67,14 @@ func SpecialFFTVec(values []complex128, N, M int, rotGroup []int, roots []comple
// SpecialFFTUL8Vec performs the CKKS special FFT transform in place with unrolled loops of size 8.
func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []complex128) {
if len(values) < minVecLenForLoopUnrolling {
panic(fmt.Sprintf("unsafe call of SpecialFFTUL8Vec: len(values)=%d < %d", len(values), minVecLenForLoopUnrolling))
}
if len(values) < N || len(rotGroup) < N || len(roots) < M+1 {
panic(fmt.Sprintf("invalid call of SpecialFFTUL8Vec: len(values)=%d or len(rotGroup)=%d < N=%d or len(roots)=%d < M+1=%d", len(values), len(rotGroup), N, len(roots), M))
}
SliceBitReverseInPlaceComplex128(values, N)
logN := int(bits.Len64(uint64(N))) - 1
@@ -70,8 +93,11 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
for j, k := 0, i; j < lenh; j, k = j+8, k+8 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[8]complex128)(unsafe.Pointer(&values[k]))
/* #nosec G103 -- behavior and consequences well understood */
v := (*[8]complex128)(unsafe.Pointer(&values[k+lenh]))
/* #nosec G103 -- behavior and consequences well understood */
w := (*[8]int)(unsafe.Pointer(&rotGroup[j]))
v[0] *= roots[(w[0]&mask)<<logGap]
@@ -106,6 +132,7 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[8] *= psi0
@@ -136,6 +163,7 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[4] *= psi0
@@ -163,6 +191,7 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[2] *= psi0
@@ -189,6 +218,7 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[1] *= psi0
@@ -216,6 +246,14 @@ func SpecialFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []com
// SpecialiFFTUL8Vec performs the CKKS special inverse FFT transform in place with unrolled loops of size 8.
func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []complex128) {
if len(values) < minVecLenForLoopUnrolling {
panic(fmt.Sprintf("unsafe call of SpecialiFFTUL8Vec: len(values)=%d < %d", len(values), minVecLenForLoopUnrolling))
}
if len(values) < N || len(rotGroup) < N || len(roots) < M+1 {
panic(fmt.Sprintf("invalid call of SpecialiFFTUL8Vec: len(values)=%d or len(rotGroup)=%d < N=%d or len(roots)=%d < M+1=%d", len(values), len(rotGroup), N, len(roots), M))
}
logN := int(bits.Len64(uint64(N))) - 1
logM := int(bits.Len64(uint64(M))) - 1
@@ -230,8 +268,11 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
for i := 0; i < N; i += len {
for j, k := 0, i; j < lenh; j, k = j+8, k+8 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[8]complex128)(unsafe.Pointer(&values[k]))
/* #nosec G103 -- behavior and consequences well understood */
v := (*[8]complex128)(unsafe.Pointer(&values[k+lenh]))
/* #nosec G103 -- behavior and consequences well understood */
w := (*[8]int)(unsafe.Pointer(&rotGroup[j]))
u[0], v[0] = u[0]+v[0], (u[0]-v[0])*roots[(lenq-(w[0]&mask))<<logGap]
@@ -257,6 +298,7 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[0], u[8] = u[0]+u[8], (u[0]-u[8])*psi0
@@ -278,6 +320,7 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[0], u[4] = u[0]+u[4], (u[0]-u[4])*psi0
@@ -296,6 +339,7 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[0], u[2] = u[0]+u[2], (u[0]-u[2])*psi0
@@ -313,6 +357,7 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
for i := 0; i < N; i += 16 {
/* #nosec G103 -- behavior and consequences well understood */
u := (*[16]complex128)(unsafe.Pointer(&values[i]))
u[0], u[1] = u[0]+u[1], (u[0]-u[1])*psi0
@@ -327,16 +372,17 @@ func SpecialiFFTUL8Vec(values []complex128, N, M int, rotGroup []int, roots []co
}
}
DivideComplex128SliceVec(values, complex(float64(N), 0))
divideComplex128SliceVec(values, complex(float64(N), 0))
SliceBitReverseInPlaceComplex128(values, N)
}
// DivideComplex128SliceVec divides the entries in values by scaleVal in place.
func DivideComplex128SliceVec(values []complex128, scaleVal complex128) {
// divideComplex128SliceVec divides the entries in values by scaleVal in place.
func divideComplex128SliceVec(values []complex128, scaleVal complex128) {
lenValues := len(values)
for i := 0; i < lenValues; i = i + 8 {
/* #nosec G103 -- behavior and consequences well understood */
v := (*[8]complex128)(unsafe.Pointer(&values[i]))
v[0] /= scaleVal

View File

@@ -117,7 +117,7 @@ func newEncoder(params Parameters) encoder {
m := int(params.RingQ().NthRoot())
rotGroup := make([]int, m>>1)
rotGroup := make([]int, m>>2)
fivePows := 1
for i := 0; i < m>>2; i++ {
rotGroup[i] = fivePows
@@ -430,7 +430,7 @@ func polyToComplexNoCRT(coeffs []uint64, values []complex128, scale rlwe.Scale,
}
}
DivideComplex128SliceVec(values, complex(scale.Float64(), 0))
divideComplex128SliceVec(values, complex(scale.Float64(), 0))
}
func polyToComplexCRT(poly *ring.Poly, bigintCoeffs []*big.Int, values []complex128, scale rlwe.Scale, logSlots int, isreal bool, ringQ *ring.Ring, Q *big.Int) {

View File

@@ -174,7 +174,9 @@ func example() {
start = time.Now()
monomialBasis := ckks.NewPowerBasis(ciphertext, polynomial.Monomial)
monomialBasis.GenPower(int(r), false, params.DefaultScale(), evaluator)
if err = monomialBasis.GenPower(int(r), false, params.DefaultScale(), evaluator); err != nil {
panic(err)
}
ciphertext = monomialBasis.Value[int(r)]
fmt.Printf("Done in %s \n", time.Since(start))

View File

@@ -49,10 +49,12 @@ func (r *Ring) AutomorphismNTTWithIndex(polIn *Poly, index []uint64, polOut *Pol
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&index[j]))
for i := 0; i < level+1; i++ {
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&polOut.Coeffs[i][j]))
y := polIn.Coeffs[i]
@@ -79,10 +81,12 @@ func (r *Ring) AutomorphismNTTWithIndexThenAddLazy(polIn *Poly, index []uint64,
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&index[j]))
for i := 0; i < level+1; i++ {
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&polOut.Coeffs[i][j]))
y := polIn.Coeffs[i]

View File

@@ -299,6 +299,7 @@ func ModUpExact(p1, p2 [][]uint64, ringQ, ringP *Ring, MUC ModUpConstants) {
for x := 0; x < len(p1[0]); x = x + 8 {
reconstructRNS(0, levelQ+1, x, p1, &v, &y0, &y1, &y2, &y3, &y4, &y5, &y6, &y7, Q, mredQ, qoverqiinvqi)
for j := 0; j < levelP+1; j++ {
/* #nosec G103 -- behavior and consequences well understood */
multSum(levelQ, (*[8]uint64)(unsafe.Pointer(&p2[j][x])), &rlo, &rhi, &v, &y0, &y1, &y2, &y3, &y4, &y5, &y6, &y7, P[j], mredP[j], vtimesqmodp[j], qoverqimodp[j])
}
}
@@ -461,16 +462,19 @@ func (decomposer *Decomposer) DecomposeAndSplit(levelQ, levelP, nbPi, decompRNS
// Coefficients of index smaller than the ones to be decomposed
for j := 0; j < p0idxst; j++ {
/* #nosec G103 -- behavior and consequences well understood */
multSum(decompLvl+1, (*[8]uint64)(unsafe.Pointer(&p1Q.Coeffs[j][x])), &rlo, &rhi, &v, &y0, &y1, &y2, &y3, &y4, &y5, &y6, &y7, Q[j], mredQ[j], vtimesqmodp[j], qoverqimodp[j])
}
// Coefficients of index greater than the ones to be decomposed
for j := p0idxed; j < levelQ+1; j++ {
/* #nosec G103 -- behavior and consequences well understood */
multSum(decompLvl+1, (*[8]uint64)(unsafe.Pointer(&p1Q.Coeffs[j][x])), &rlo, &rhi, &v, &y0, &y1, &y2, &y3, &y4, &y5, &y6, &y7, Q[j], mredQ[j], vtimesqmodp[j], qoverqimodp[j])
}
// Coefficients of the special primes Pi
for j, u := 0, len(Q); j < levelP+1; j, u = j+1, u+1 {
/* #nosec G103 -- behavior and consequences well understood */
multSum(decompLvl+1, (*[8]uint64)(unsafe.Pointer(&p1P.Coeffs[j][x])), &rlo, &rhi, &v, &y0, &y1, &y2, &y3, &y4, &y5, &y6, &y7, P[j], mredP[j], vtimesqmodp[u], qoverqimodp[u])
}
}
@@ -492,6 +496,7 @@ func reconstructRNSCentered(start, end, x int, p [][]uint64, v *[8]uint64, vi *[
mredConstant := mredQ[j]
qif := float64(qi)
/* #nosec G103 -- behavior and consequences well understood */
px := (*[8]uint64)(unsafe.Pointer(&p[j][x]))
y0[i] = MRed(px[0]+qHalf, qqiinv, qi, mredConstant)
@@ -537,6 +542,8 @@ func reconstructRNS(start, end, x int, p [][]uint64, v *[8]uint64, y0, y1, y2, y
qi = Q[i]
qiInv = QInv[i]
qif = float64(qi)
/* #nosec G103 -- behavior and consequences well understood */
pTmp := (*[8]uint64)(unsafe.Pointer(&p[i][x]))
y0[j] = MRed(pTmp[0], qoverqiinvqi, qi, qiInv)

View File

@@ -1,6 +1,7 @@
package ring
import (
"fmt"
"math/bits"
"unsafe"
)
@@ -202,6 +203,14 @@ func INTTConjugateInvariantLazy(p1, p2 []uint64, N int, NInv, Q, QInv, MRedConst
// NTTStandardLazy computes the NTT on the input coefficients using the input parameters with output values in the range [0, 2*modulus-1].
func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
if len(p2) < MinimuRingDegree {
panic(fmt.Sprintf("unsafe call of NTTStandardLazy: receiver len(p2)=%d < %d", len(p2), MinimuRingDegree))
}
if len(p1) < N || len(p2) < N || len(nttPsi) < N {
panic(fmt.Sprintf("cannot NTTStandardLazy: ensure that len(p1)=%d, len(p2)=%d and len(nttPsi)=%d >= N=%d", len(p1), len(p2), len(nttPsi), N))
}
var j1, j2, t int
var F, V uint64
@@ -214,10 +223,14 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for jx, jy := 0, t; jx <= t-1; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
xin := (*[8]uint64)(unsafe.Pointer(&p1[jx]))
/* #nosec G103 -- behavior and consequences well understood */
yin := (*[8]uint64)(unsafe.Pointer(&p1[jy]))
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
yout := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
V = MRedLazy(yin[0], F, Q, QInv)
@@ -268,7 +281,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
x[0], y[0] = butterfly(x[0], y[0], F, twoQ, fourQ, Q, QInv)
@@ -285,7 +300,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
V = MRedLazy(y[0], F, Q, QInv)
@@ -321,7 +338,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for i, j1 := m, 0; i < 2*m; i, j1 = i+2, j1+4*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[4] = butterfly(x[0], x[4], psi[0], twoQ, fourQ, Q, QInv)
@@ -338,7 +357,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for i, j1 := m, 0; i < 2*m; i, j1 = i+2, j1+4*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
V = MRedLazy(x[4], psi[0], Q, QInv)
@@ -375,7 +396,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for i, j1 := m, 0; i < 2*m; i, j1 = i+4, j1+8*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[2] = butterfly(x[0], x[2], psi[0], twoQ, fourQ, Q, QInv)
@@ -391,7 +414,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for i, j1 := m, 0; i < 2*m; i, j1 = i+4, j1+8*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
V = MRedLazy(x[2], psi[0], Q, QInv)
@@ -424,7 +449,9 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
for i, j1 := m, 0; i < 2*m; i, j1 = i+8, j1+16 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[8]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[1] = butterfly(x[0], x[1], psi[0], twoQ, fourQ, Q, QInv)
@@ -474,6 +501,14 @@ func NTTStandardLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
if len(p2) < MinimuRingDegree {
panic(fmt.Sprintf("unsafe call of iNTTCore: receiver len(p2)=%d < %d", len(p2), MinimuRingDegree))
}
if len(p1) < N || len(p2) < N || len(nttPsiInv) < N {
panic(fmt.Sprintf("cannot iNTTCore: ensure that len(p1)=%d, len(p2)=%d and len(nttPsiInv)=%d >= N=%d", len(p1), len(p2), len(nttPsiInv), N))
}
var h, t int
var F uint64
@@ -485,8 +520,11 @@ func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
for i, j := h, 0; i < 2*h; i, j = i+8, j+16 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[8]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
xin := (*[16]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[16]uint64)(unsafe.Pointer(&p2[j]))
xout[0], xout[1] = invbutterfly(xin[0], xin[1], psi[0], twoQ, fourQ, Q, QInv)
@@ -513,7 +551,9 @@ func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
x[0], y[0] = invbutterfly(x[0], y[0], F, twoQ, fourQ, Q, QInv)
@@ -531,7 +571,9 @@ func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
for i, j1 := h, 0; i < 2*h; i, j1 = i+2, j1+4*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[4] = invbutterfly(x[0], x[4], psi[0], twoQ, fourQ, Q, QInv)
@@ -548,7 +590,9 @@ func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
for i, j1 := h, 0; i < 2*h; i, j1 = i+4, j1+8*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[2] = invbutterfly(x[0], x[2], psi[0], twoQ, fourQ, Q, QInv)
@@ -569,6 +613,14 @@ func iNTTCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
// nttConjugateInvariantLazy evaluates p2 = NTT(p1) in the sub-ring Z[X + X^-1]/(X^2N +1) of Z[X]/(X^2N+1) with p2 [0, 2*modulus-1].
func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []uint64) {
if len(p2) < MinimuRingDegree {
panic(fmt.Sprintf("unsafe call of nttConjugateInvariantLazy: receiver len(p2)=%d < %d", len(p2), MinimuRingDegree))
}
if len(p1) < N || len(p2) < N || len(nttPsi) < N {
panic(fmt.Sprintf("cannot nttConjugateInvariantLazy: ensure that len(p1)=%d, len(p2)=%d and len(nttPsi)=%d >= N=%d", len(p1), len(p2), len(nttPsi), N))
}
var t, h int
var F, V uint64
var reduce bool
@@ -582,10 +634,14 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for jx, jy := 1, N-8; jx < (N>>1)-7; jx, jy = jx+8, jy-8 {
/* #nosec G103 -- behavior and consequences well understood */
xin := (*[8]uint64)(unsafe.Pointer(&p1[jx]))
/* #nosec G103 -- behavior and consequences well understood */
yin := (*[8]uint64)(unsafe.Pointer(&p1[jy]))
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
yout := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
xout[0], yout[7] = xin[0]+twoQ-MRedLazy(yin[7], F, Q, QInv), yin[7]+twoQ-MRedLazy(xin[0], F, Q, QInv)
@@ -599,9 +655,13 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
}
j := (N >> 1) - 7
/* #nosec G103 -- behavior and consequences well understood */
xin := (*[7]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
yin := (*[7]uint64)(unsafe.Pointer(&p1[N-j-6]))
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[7]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
yout := (*[7]uint64)(unsafe.Pointer(&p2[N-j-6]))
xout[0], yout[6] = xin[0]+twoQ-MRedLazy(yin[6], F, Q, QInv), yin[6]+twoQ-MRedLazy(xin[0], F, Q, QInv)
@@ -633,7 +693,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
x[0], y[0] = butterfly(x[0], y[0], F, twoQ, fourQ, Q, QInv)
@@ -650,7 +712,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
V = MRedLazy(y[0], F, Q, QInv)
@@ -686,7 +750,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+2, j1+4*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[4] = butterfly(x[0], x[4], psi[0], twoQ, fourQ, Q, QInv)
@@ -703,7 +769,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+2, j1+4*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
V = MRedLazy(x[4], psi[0], Q, QInv)
@@ -739,7 +807,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+4, j1+8*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[2] = butterfly(x[0], x[2], psi[0], twoQ, fourQ, Q, QInv)
@@ -755,7 +825,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+4, j1+8*t {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
V = MRedLazy(x[2], psi[0], Q, QInv)
@@ -790,7 +862,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+8, j1+16 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[8]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[1] = butterfly(x[0], x[1], psi[0], twoQ, fourQ, Q, QInv)
@@ -806,7 +880,9 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
for i, j1 := m, 0; i < h+m; i, j1 = i+8, j1+16 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[8]uint64)(unsafe.Pointer(&nttPsi[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
V = MRedLazy(x[1], psi[0], Q, QInv)
@@ -840,6 +916,14 @@ func nttConjugateInvariantLazy(p1, p2 []uint64, N int, Q, QInv uint64, nttPsi []
func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiInv []uint64) {
if len(p2) < MinimuRingDegree {
panic(fmt.Sprintf("unsafe call of iNTTConjugateInvariantCore: receiver len(p2)=%d < %d", len(p2), MinimuRingDegree))
}
if len(p1) < N || len(p2) < N || len(nttPsiInv) < N {
panic(fmt.Sprintf("cannot iNTTConjugateInvariantCore: ensure that len(p1)=%d, len(p2)=%d and len(nttPsiInv)=%d >= N=%d", len(p1), len(p2), len(nttPsiInv), N))
}
var j1, j2, h, t int
var F uint64
@@ -851,8 +935,11 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
for i, j := N, 0; i < h+N; i, j = i+8, j+16 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[8]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
xin := (*[16]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[16]uint64)(unsafe.Pointer(&p2[j]))
xout[0], xout[1] = invbutterfly(xin[0], xin[1], psi[0], twoQ, fourQ, Q, QInv)
@@ -882,7 +969,9 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
for jx, jy := j1, j1+t; jx <= j2; jx, jy = jx+8, jy+8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
x[0], y[0] = invbutterfly(x[0], y[0], F, twoQ, fourQ, Q, QInv)
@@ -902,7 +991,9 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
for i := m; i < h+m; i = i + 2 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[2]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[4] = invbutterfly(x[0], x[4], psi[0], twoQ, fourQ, Q, QInv)
@@ -921,7 +1012,9 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
for i := m; i < h+m; i = i + 4 {
/* #nosec G103 -- behavior and consequences well understood */
psi := (*[4]uint64)(unsafe.Pointer(&nttPsiInv[i]))
/* #nosec G103 -- behavior and consequences well understood */
x := (*[16]uint64)(unsafe.Pointer(&p2[j1]))
x[0], x[2] = invbutterfly(x[0], x[2], psi[0], twoQ, fourQ, Q, QInv)
@@ -944,7 +1037,9 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
for jx, jy := 1, N-8; jx < (N>>1)-7; jx, jy = jx+8, jy-8 {
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[8]uint64)(unsafe.Pointer(&p2[jx]))
/* #nosec G103 -- behavior and consequences well understood */
yout := (*[8]uint64)(unsafe.Pointer(&p2[jy]))
xout[0], yout[7] = xout[0]+twoQ-MRedLazy(yout[7], F, Q, QInv), yout[7]+twoQ-MRedLazy(xout[0], F, Q, QInv)
@@ -958,7 +1053,9 @@ func iNTTConjugateInvariantCore(p1, p2 []uint64, N int, Q, QInv uint64, nttPsiIn
}
j := (N >> 1) - 7
/* #nosec G103 -- behavior and consequences well understood */
xout := (*[7]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
yout := (*[7]uint64)(unsafe.Pointer(&p2[N-j-6]))
xout[0], yout[6] = xout[0]+twoQ-MRedLazy(yout[6], F, Q, QInv), yout[6]+twoQ-MRedLazy(xout[0], F, Q, QInv)

View File

@@ -36,7 +36,9 @@ func (u *UniformSampler) Read(pol *Poly) {
var randomUint, mask, qi uint64
var ptr int
u.prng.Read(u.randomBufferN)
if _, err := u.prng.Read(u.randomBufferN); err != nil {
panic(err)
}
N := u.baseRing.N()
@@ -59,7 +61,9 @@ func (u *UniformSampler) Read(pol *Poly) {
// Refills the buff if it runs empty
if ptr == N {
u.prng.Read(buffer)
if _, err := u.prng.Read(buffer); err != nil {
panic(err)
}
ptr = 0
}
@@ -106,13 +110,12 @@ func randInt32(prng sampling.PRNG, mask uint64) uint64 {
// generate random 4 bytes
randomBytes := make([]byte, 4)
prng.Read(randomBytes)
// convert 4 bytes to a uint32
randomUint32 := uint64(binary.LittleEndian.Uint32(randomBytes))
if _, err := prng.Read(randomBytes); err != nil {
panic(err)
}
// return required bits
return mask & randomUint32
return mask & uint64(binary.LittleEndian.Uint32(randomBytes))
}
// randInt64 samples a uniform variable in the range [0, mask], where mask is of the form 2^n-1, with n in [0, 64].
@@ -120,11 +123,11 @@ func randInt64(prng sampling.PRNG, mask uint64) uint64 {
// generate random 8 bytes
randomBytes := make([]byte, 8)
prng.Read(randomBytes)
// convert 8 bytes to a uint64
randomUint64 := binary.LittleEndian.Uint64(randomBytes)
if _, err := prng.Read(randomBytes); err != nil {
panic(err)
}
// return required bits
return mask & randomUint64
return mask & binary.LittleEndian.Uint64(randomBytes)
}

View File

@@ -69,7 +69,9 @@ func (g *GaussianSampler) ReadAndAddFromDist(pol *Poly, r *Ring, sigma float64,
var coeffFlo float64
var coeffInt, sign uint64
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
modulus := r.ModuliChain()[:r.level+1]
@@ -98,7 +100,9 @@ func (g *GaussianSampler) read(pol *Poly, r *Ring, sigma float64, bound int) {
level := r.level
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
modulus := r.ModuliChain()[:level+1]
@@ -140,7 +144,9 @@ func (g *GaussianSampler) normFloat64() (float64, uint64) {
for {
if g.ptr == uint64(len(g.randomBufferN)) {
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
g.ptr = 0
}
@@ -168,7 +174,9 @@ func (g *GaussianSampler) normFloat64() (float64, uint64) {
for {
if g.ptr == uint64(len(g.randomBufferN)) {
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
g.ptr = 0
}
@@ -176,7 +184,9 @@ func (g *GaussianSampler) normFloat64() (float64, uint64) {
g.ptr += 8
if g.ptr == uint64(len(g.randomBufferN)) {
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
g.ptr = 0
}
@@ -192,7 +202,9 @@ func (g *GaussianSampler) normFloat64() (float64, uint64) {
}
if g.ptr == uint64(len(g.randomBufferN)) {
g.prng.Read(g.randomBufferN)
if _, err := g.prng.Read(g.randomBufferN); err != nil {
panic(err)
}
g.ptr = 0
}

View File

@@ -143,9 +143,13 @@ func (ts *TernarySampler) sampleProba(pol *Poly) {
randomBytesCoeffs := make([]byte, N>>3)
randomBytesSign := make([]byte, N>>3)
ts.prng.Read(randomBytesCoeffs)
if _, err := ts.prng.Read(randomBytesCoeffs); err != nil {
panic(err)
}
ts.prng.Read(randomBytesSign)
if _, err := ts.prng.Read(randomBytesSign); err != nil {
panic(err)
}
for i := 0; i < N; i++ {
coeff = uint64(uint8(randomBytesCoeffs[i>>3])>>(i&7)) & 1
@@ -165,7 +169,9 @@ func (ts *TernarySampler) sampleProba(pol *Poly) {
pointer := uint8(0)
var bytePointer int
ts.prng.Read(randomBytes)
if _, err := ts.prng.Read(randomBytes); err != nil {
panic(err)
}
for i := 0; i < N; i++ {
@@ -200,7 +206,9 @@ func (ts *TernarySampler) sampleSparse(pol *Poly) {
randomBytes := make([]byte, (uint64(math.Ceil(float64(hw) / 8.0)))) // We sample ceil(hw/8) bytes
pointer := uint8(0)
ts.prng.Read(randomBytes)
if _, err := ts.prng.Read(randomBytes); err != nil {
panic(err)
}
level := ts.baseRing.level
@@ -233,7 +241,6 @@ func (ts *TernarySampler) sampleSparse(pol *Poly) {
for k := 0; k < level+1; k++ {
pol.Coeffs[k][i] = 0
}
}
}
@@ -273,7 +280,9 @@ func (ts *TernarySampler) kysampling(prng sampling.PRNG, randomBytes []byte, poi
if bytePointer >= byteLength {
bytePointer = 0
prng.Read(randomBytes)
if _, err := prng.Read(randomBytes); err != nil {
panic(err)
}
}
sign = uint8(randomBytes[bytePointer]) & 1
@@ -298,7 +307,9 @@ func (ts *TernarySampler) kysampling(prng sampling.PRNG, randomBytes []byte, poi
if bytePointer >= byteLength {
bytePointer = 0
prng.Read(randomBytes)
if _, err := prng.Read(randomBytes); err != nil {
panic(err)
}
}
}

View File

@@ -9,6 +9,12 @@ import (
"github.com/tuneinsight/lattigo/v4/utils/factorization"
)
const (
// MinimuRingDegree is the minimum ring degree
// necessary for memory safe loop unrolling
MinimuRingDegree = 16
)
// SubRing is a struct storing precomputation
// for fast modular reduction and NTT for
// a given modulus.
@@ -46,8 +52,8 @@ func NewSubRing(N int, Modulus uint64) (s *SubRing, err error) {
func NewSubRingWithCustomNTT(N int, Modulus uint64, ntt func(*SubRing, int) NumberTheoreticTransformer, NthRoot int) (s *SubRing, err error) {
// Checks if N is a power of 2
if (N < 16) || (N&(N-1)) != 0 && N != 0 {
return nil, fmt.Errorf("invalid degree (must be a power of 2 >= 8)")
if (N < MinimuRingDegree) || (N&(N-1)) != 0 && N != 0 {
return nil, fmt.Errorf("invalid degree (must be a power of 2 >= %d)", MinimuRingDegree)
}
s = &SubRing{}

View File

@@ -9,8 +9,12 @@ func addvec(p1, p2, p3 []uint64, modulus uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = CRed(x[0]+y[0], modulus)
@@ -29,8 +33,12 @@ func addlazyvec(p1, p2, p3 []uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = x[0] + y[0]
@@ -49,8 +57,12 @@ func subvec(p1, p2, p3 []uint64, modulus uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = CRed((x[0]+modulus)-y[0], modulus)
@@ -69,8 +81,12 @@ func sublazyvec(p1, p2, p3 []uint64, modulus uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = x[0] + modulus - y[0]
@@ -89,7 +105,10 @@ func negvec(p1, p2 []uint64, modulus uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = modulus - x[0]
@@ -108,7 +127,10 @@ func reducevec(p1, p2 []uint64, modulus uint64, brc []uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = BRedAdd(x[0], modulus, brc)
@@ -128,7 +150,9 @@ func reducelazyvec(p1, p2 []uint64, modulus uint64, brc []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = BRedAddLazy(x[0], modulus, brc)
@@ -148,8 +172,11 @@ func mulcoeffslazyvec(p1, p2, p3 []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = x[0] * y[0]
@@ -169,8 +196,11 @@ func mulcoeffslazythenaddlazyvec(p1, p2, p3 []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += x[0] * y[0]
@@ -190,8 +220,11 @@ func mulcoeffsbarrettvec(p1, p2, p3 []uint64, modulus uint64, brc []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = BRed(x[0], y[0], modulus, brc)
@@ -211,8 +244,11 @@ func mulcoeffsbarrettlazyvec(p1, p2, p3 []uint64, modulus uint64, brc []uint64)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = BRedLazy(x[0], y[0], modulus, brc)
@@ -232,8 +268,11 @@ func mulcoeffsthenaddvec(p1, p2, p3 []uint64, modulus uint64, brc []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = CRed(z[0]+BRed(x[0], y[0], modulus, brc), modulus)
@@ -253,8 +292,11 @@ func mulcoeffsbarrettthenaddlazyvec(p1, p2, p3 []uint64, modulus uint64, brc []u
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += BRed(x[0], y[0], modulus, brc)
@@ -273,8 +315,11 @@ func mulcoeffsmontgomeryvec(p1, p2, p3 []uint64, modulus, mrc uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = MRed(x[0], y[0], modulus, mrc)
@@ -294,8 +339,11 @@ func mulcoeffsmontgomerylazyvec(p1, p2, p3 []uint64, modulus, mrc uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = MRedLazy(x[0], y[0], modulus, mrc)
@@ -314,8 +362,11 @@ func mulcoeffsmontgomerythenaddvec(p1, p2, p3 []uint64, modulus, mrc uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = CRed(z[0]+MRed(x[0], y[0], modulus, mrc), modulus)
@@ -334,8 +385,12 @@ func mulcoeffsmontgomerythenaddlazyvec(p1, p2, p3 []uint64, modulus, mrc uint64)
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += MRed(x[0], y[0], modulus, mrc)
@@ -354,8 +409,12 @@ func mulcoeffsmontgomerylazythenaddlazyvec(p1, p2, p3 []uint64, modulus, mrc uin
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += MRedLazy(x[0], y[0], modulus, mrc)
@@ -374,8 +433,12 @@ func mulcoeffsmontgomerythensubvec(p1, p2, p3 []uint64, modulus, mrc uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = CRed(z[0]+(modulus-MRed(x[0], y[0], modulus, mrc)), modulus)
@@ -394,8 +457,12 @@ func mulcoeffsmontgomerythensublazyvec(p1, p2, p3 []uint64, modulus, mrc uint64)
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += (modulus - MRed(x[0], y[0], modulus, mrc))
@@ -415,8 +482,12 @@ func mulcoeffsmontgomerylazythensublazyvec(p1, p2, p3 []uint64, modulus, mrc uin
twomodulus := modulus << 1
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] += twomodulus - MRedLazy(x[0], y[0], modulus, mrc)
@@ -436,8 +507,12 @@ func mulcoeffsmontgomerylazythenNegvec(p1, p2, p3 []uint64, modulus, mrc uint64)
twomodulus := modulus << 1
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = twomodulus - MRedLazy(x[0], y[0], modulus, mrc)
@@ -457,8 +532,11 @@ func addlazythenmulscalarmontgomeryvec(p1, p2 []uint64, scalarMont uint64, p3 []
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = MRed(x[0]+y[0], scalarMont, modulus, mrc)
@@ -478,7 +556,9 @@ func addscalarlazythenmulscalarmontgomeryvec(p1 []uint64, scalar0, scalarMont1 u
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = MRed(x[0]+scalar0, scalarMont1, modulus, mrc)
@@ -497,7 +577,10 @@ func addscalarvec(p1 []uint64, scalar uint64, p2 []uint64, modulus uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = CRed(x[0]+scalar, modulus)
@@ -516,7 +599,10 @@ func addscalarlazyvec(p1 []uint64, scalar uint64, p2 []uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = x[0] + scalar
@@ -536,7 +622,10 @@ func addscalarlazythenNegTwoModuluslazyvec(p1 []uint64, scalar uint64, p2 []uint
twomodulus := modulus << 1
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = scalar + twomodulus - x[0]
@@ -556,7 +645,9 @@ func subscalarvec(p1 []uint64, scalar uint64, p2 []uint64, modulus uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = CRed(x[0]+modulus-scalar, modulus)
@@ -576,7 +667,9 @@ func mulscalarmontgomeryvec(p1 []uint64, scalarMont uint64, p2 []uint64, modulus
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = MRed(x[0], scalarMont, modulus, mrc)
@@ -596,7 +689,9 @@ func mulscalarmontgomerylazyvec(p1 []uint64, scalarMont uint64, p2 []uint64, mod
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = MRedLazy(x[0], scalarMont, modulus, mrc)
@@ -616,7 +711,9 @@ func mulscalarmontgomerythenaddvec(p1 []uint64, scalarMont uint64, p2 []uint64,
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = CRed(z[0]+MRed(x[0], scalarMont, modulus, mrc), modulus)
@@ -636,7 +733,9 @@ func mulscalarmontgomerythenaddscalarvec(p1 []uint64, scalar0, scalarMont1 uint6
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = CRed(MRed(x[0], scalarMont1, modulus, mrc)+scalar0, modulus)
@@ -657,8 +756,11 @@ func subthenmulscalarmontgomeryTwoModulusvec(p1, p2 []uint64, scalarMont uint64,
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
y := (*[8]uint64)(unsafe.Pointer(&p2[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p3[j]))
z[0] = MRed(twomodulus-y[0]+x[0], scalarMont, modulus, mrc)
@@ -678,7 +780,10 @@ func mformvec(p1, p2 []uint64, modulus uint64, brc []uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = MForm(x[0], modulus, brc)
@@ -697,7 +802,10 @@ func mformlazyvec(p1, p2 []uint64, modulus uint64, brc []uint64) {
N := len(p1)
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = MFormLazy(x[0], modulus, brc)
@@ -717,7 +825,9 @@ func imformvec(p1, p2 []uint64, modulus, mrc uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = IMForm(x[0], modulus, mrc)
@@ -740,6 +850,7 @@ func ZeroVec(p1 []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p1[j]))
z[0] = 0
@@ -762,7 +873,9 @@ func MaskVec(p1 []uint64, w int, mask uint64, p2 []uint64) {
for j := 0; j < N; j = j + 8 {
/* #nosec G103 -- behavior and consequences well understood */
x := (*[8]uint64)(unsafe.Pointer(&p1[j]))
/* #nosec G103 -- behavior and consequences well understood */
z := (*[8]uint64)(unsafe.Pointer(&p2[j]))
z[0] = (x[0] >> w) & mask

View File

@@ -4,7 +4,8 @@ import (
"encoding/binary"
"fmt"
"io"
"unsafe"
"github.com/tuneinsight/lattigo/v4/utils"
)
// Reader defines a interface comprising of the minimum subset
@@ -19,11 +20,20 @@ type Reader interface {
}
func ReadInt(r Reader, c *int) (n int, err error) {
return ReadUint64(r, (*uint64)(unsafe.Pointer(c)))
if c == nil {
return 0, fmt.Errorf("cannot ReadInt: c is nil")
}
return ReadUint64(r, utils.PointyIntToPointUint64(c))
}
func ReadUint8(r Reader, c *uint8) (n int, err error) {
if c == nil {
return 0, fmt.Errorf("cannot ReadUint8: c is nil")
}
var bb = [1]byte{}
if n, err = r.Read(bb[:]); err != nil {
@@ -42,6 +52,10 @@ func ReadUint8Slice(r Reader, c []uint8) (n int, err error) {
func ReadUint16(r Reader, c *uint16) (n int, err error) {
if c == nil {
return 0, fmt.Errorf("cannot ReadUint16: c is nil")
}
var bb = [2]byte{}
if n, err = r.Read(bb[:]); err != nil {
@@ -104,6 +118,10 @@ func ReadUint16Slice(r Reader, c []uint16) (n int, err error) {
func ReadUint32(r Reader, c *uint32) (n int, err error) {
if c == nil {
return 0, fmt.Errorf("cannot ReadUint32: c is nil")
}
var bb = [4]byte{}
if n, err = r.Read(bb[:]); err != nil {
@@ -166,6 +184,10 @@ func ReadUint32Slice(r Reader, c []uint32) (n int, err error) {
func ReadUint64(r Reader, c *uint64) (n int, err error) {
if c == nil {
return 0, fmt.Errorf("cannot ReadUint64: c is nil")
}
var bb = [8]byte{}
if n, err = r.Read(bb[:]); err != nil {

View File

@@ -1,5 +1,9 @@
package utils
import (
"unsafe"
)
// PointyInt creates a new int variable and returns its pointer.
func PointyInt(x int) *int {
return &x
@@ -9,3 +13,9 @@ func PointyInt(x int) *int {
func PointyUint64(x uint64) *uint64 {
return &x
}
// PointyIntToPointUint64 converts *int to *uint64.
func PointyIntToPointUint64(x *int) *uint64 {
/* #nosec G103 -- behavior and consequences well understood */
return (*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer(x))))
}