From e8a2746ac8f81129651f6fba3e45d12130a0d193 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Thu, 30 Mar 2023 12:33:47 +0200 Subject: [PATCH] gosec --- ckks/bootstrapping/bootstrapping.go | 6 +- ckks/ckks_vector_ops.go | 52 ++++++++++++- ckks/encoder.go | 4 +- examples/ckks/euler/main.go | 4 +- ring/automorphism.go | 4 + ring/basis_extension.go | 7 ++ ring/ntt.go | 97 ++++++++++++++++++++++++ ring/ring_sampler_uniform.go | 25 +++--- ring/sampler_gaussian.go | 24 ++++-- ring/sampler_ternary.go | 25 ++++-- ring/subring.go | 10 ++- ring/vec_ops.go | 113 ++++++++++++++++++++++++++++ utils/buffer/reader.go | 26 ++++++- utils/pointy.go | 10 +++ 14 files changed, 372 insertions(+), 35 deletions(-) diff --git a/ckks/bootstrapping/bootstrapping.go b/ckks/bootstrapping/bootstrapping.go index 2a733052..d0b2a630 100644 --- a/ckks/bootstrapping/bootstrapping.go +++ b/ckks/bootstrapping/bootstrapping.go @@ -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) diff --git a/ckks/ckks_vector_ops.go b/ckks/ckks_vector_ops.go index 13ab0e49..0c90cb6c 100644 --- a/ckks/ckks_vector_ops.go +++ b/ckks/ckks_vector_ops.go @@ -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)<>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) { diff --git a/examples/ckks/euler/main.go b/examples/ckks/euler/main.go index 468daec1..99512d7d 100644 --- a/examples/ckks/euler/main.go +++ b/examples/ckks/euler/main.go @@ -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)) diff --git a/ring/automorphism.go b/ring/automorphism.go index 9688d7e4..58e16312 100644 --- a/ring/automorphism.go +++ b/ring/automorphism.go @@ -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] diff --git a/ring/basis_extension.go b/ring/basis_extension.go index f224d259..3d7e5bad 100644 --- a/ring/basis_extension.go +++ b/ring/basis_extension.go @@ -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) diff --git a/ring/ntt.go b/ring/ntt.go index 6b056b1d..95dc7e42 100644 --- a/ring/ntt.go +++ b/ring/ntt.go @@ -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) diff --git a/ring/ring_sampler_uniform.go b/ring/ring_sampler_uniform.go index 5c080fa3..0646cda1 100644 --- a/ring/ring_sampler_uniform.go +++ b/ring/ring_sampler_uniform.go @@ -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) } diff --git a/ring/sampler_gaussian.go b/ring/sampler_gaussian.go index 0cb67f11..cd6746c6 100644 --- a/ring/sampler_gaussian.go +++ b/ring/sampler_gaussian.go @@ -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 } diff --git a/ring/sampler_ternary.go b/ring/sampler_ternary.go index d74ce0e1..758364ba 100644 --- a/ring/sampler_ternary.go +++ b/ring/sampler_ternary.go @@ -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) + } } } diff --git a/ring/subring.go b/ring/subring.go index 9027d6c0..d58d5c37 100644 --- a/ring/subring.go +++ b/ring/subring.go @@ -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{} diff --git a/ring/vec_ops.go b/ring/vec_ops.go index a2ccadc9..febe035d 100644 --- a/ring/vec_ops.go +++ b/ring/vec_ops.go @@ -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 diff --git a/utils/buffer/reader.go b/utils/buffer/reader.go index ea026335..bda81a97 100644 --- a/utils/buffer/reader.go +++ b/utils/buffer/reader.go @@ -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 { diff --git a/utils/pointy.go b/utils/pointy.go index d3d380e7..079228ee 100644 --- a/utils/pointy.go +++ b/utils/pointy.go @@ -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)))) +}