mirror of
https://github.com/tuneinsight/lattigo.git
synced 2025-09-13 03:27:14 +00:00
staticcheck
This commit is contained in:
@@ -22,15 +22,12 @@ type KeyGenerator interface {
|
||||
// keyGenerator is a structure that stores the elements required to create new keys,
|
||||
// as well as a small memory pool for intermediate values.
|
||||
type keyGenerator struct {
|
||||
params *Parameters
|
||||
ringQP *ring.Ring
|
||||
pBigInt *big.Int
|
||||
polypool [2]*ring.Poly
|
||||
gaussianSampler *ring.GaussianSampler
|
||||
uniformSampler *ring.UniformSampler
|
||||
galElRotRow uint64 // Rows rotation generator
|
||||
galElRotColLeft []uint64 // Columns right rotations generators
|
||||
galElRotColRight []uint64 // Columsn left rotations generators
|
||||
params *Parameters
|
||||
ringQP *ring.Ring
|
||||
pBigInt *big.Int
|
||||
polypool [2]*ring.Poly
|
||||
gaussianSampler *ring.GaussianSampler
|
||||
uniformSampler *ring.UniformSampler
|
||||
}
|
||||
|
||||
// SecretKey is a structure that stores the SecretKey.
|
||||
@@ -55,10 +52,6 @@ const (
|
||||
|
||||
// RotationKeys is a structure that stores the switching-keys required during the homomorphic rotations.
|
||||
type RotationKeys struct {
|
||||
permuteNTTLeftIndex map[uint64][]uint64
|
||||
permuteNTTRightIndex map[uint64][]uint64
|
||||
permuteNTTRowIndex []uint64
|
||||
|
||||
evakeyRotColLeft map[uint64]*SwitchingKey
|
||||
evakeyRotColRight map[uint64]*SwitchingKey
|
||||
evakeyRotRow *SwitchingKey
|
||||
@@ -103,15 +96,12 @@ func NewKeyGenerator(params *Parameters) KeyGenerator {
|
||||
}
|
||||
|
||||
return &keyGenerator{
|
||||
params: params.Copy(),
|
||||
ringQP: ringQP,
|
||||
pBigInt: pBigInt,
|
||||
polypool: [2]*ring.Poly{ringQP.NewPoly(), ringQP.NewPoly()},
|
||||
gaussianSampler: ring.NewGaussianSampler(prng, ringQP, params.Sigma(), uint64(6*params.Sigma())),
|
||||
uniformSampler: ring.NewUniformSampler(prng, ringQP),
|
||||
galElRotColLeft: ring.GenGaloisParams(params.N(), GaloisGen),
|
||||
galElRotColRight: ring.GenGaloisParams(params.N(), ring.ModExp(GaloisGen, 2*params.N()-1, 2*params.N())),
|
||||
galElRotRow: 2*params.N() - 1,
|
||||
params: params.Copy(),
|
||||
ringQP: ringQP,
|
||||
pBigInt: pBigInt,
|
||||
polypool: [2]*ring.Poly{ringQP.NewPoly(), ringQP.NewPoly()},
|
||||
gaussianSampler: ring.NewGaussianSampler(prng, ringQP, params.Sigma(), uint64(6*params.Sigma())),
|
||||
uniformSampler: ring.NewUniformSampler(prng, ringQP),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +301,9 @@ func NewRotationKeys() (rotKey *RotationKeys) {
|
||||
// GenRot populates the target RotationKeys with a SwitchingKey for the desired rotation type and amount.
|
||||
func (keygen *keyGenerator) GenRot(rotType Rotation, sk *SecretKey, k uint64, rotKey *RotationKeys) {
|
||||
|
||||
if keygen.ringQP == nil {
|
||||
ringQP := keygen.ringQP
|
||||
|
||||
if ringQP == nil {
|
||||
panic("Cannot GenRot: modulus P is empty")
|
||||
}
|
||||
|
||||
@@ -323,7 +315,7 @@ func (keygen *keyGenerator) GenRot(rotType Rotation, sk *SecretKey, k uint64, ro
|
||||
}
|
||||
|
||||
if rotKey.evakeyRotColLeft[k] == nil && k != 0 {
|
||||
rotKey.evakeyRotColLeft[k] = keygen.genrotKey(sk.Get(), keygen.galElRotColRight[k])
|
||||
rotKey.evakeyRotColLeft[k] = keygen.genrotKey(sk.Get(), ring.ModExp(GaloisGen, 2*ringQP.N-k, 2*ringQP.N))
|
||||
}
|
||||
|
||||
case RotationRight:
|
||||
@@ -333,11 +325,11 @@ func (keygen *keyGenerator) GenRot(rotType Rotation, sk *SecretKey, k uint64, ro
|
||||
}
|
||||
|
||||
if rotKey.evakeyRotColRight[k] == nil && k != 0 {
|
||||
rotKey.evakeyRotColRight[k] = keygen.genrotKey(sk.Get(), keygen.galElRotColLeft[k])
|
||||
rotKey.evakeyRotColRight[k] = keygen.genrotKey(sk.Get(), ring.ModExp(GaloisGen, k, 2*ringQP.N))
|
||||
}
|
||||
|
||||
case RotationRow:
|
||||
rotKey.evakeyRotRow = keygen.genrotKey(sk.Get(), keygen.galElRotRow)
|
||||
rotKey.evakeyRotRow = keygen.genrotKey(sk.Get(), 2*ringQP.N-1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,18 +22,6 @@ const MaxModuliCount = 34
|
||||
// MaxModuliSize is the largest bit-length supported for the moduli in the RNS representation.
|
||||
const MaxModuliSize = 60
|
||||
|
||||
// Plaintext moduli allowing batching for the corresponding N in ascending bit-size.
|
||||
var tBatching = map[uint64][]uint64{
|
||||
4096: {40961, 114689, 188417, 417793, 1032193, 2056193, 4169729, 8380417, 16760833, 33538049, 67084289, 134176769,
|
||||
268369921, 536813569, 1073692673, 2147377153, 4294828033},
|
||||
8192: {65537, 114689, 163841, 1032193, 1785857, 4079617, 8273921, 16760833, 33538049, 67043329, 133857281,
|
||||
268369921, 536690689, 1073692673, 2147352577, 4294475777},
|
||||
16384: {65537, 163841, 786433, 1769473, 3735553, 8257537, 16580609, 33292289, 67043329, 133857281, 268369921,
|
||||
536641537, 1073643521, 2147352577, 4294475777},
|
||||
32768: {65537, 786433, 1769473, 3735553, 8257537, 16580609, 33292289, 67043329, 132710401, 268369921, 536608769,
|
||||
1073479681, 2147352577, 4293918721},
|
||||
}
|
||||
|
||||
const (
|
||||
// PN12QP109 is a set of parameters with N = 2^12 and log(QP) = 109
|
||||
PN12QP109 = iota
|
||||
@@ -251,11 +239,11 @@ func (p *Parameters) WithT(T uint64) (pCopy *Parameters) {
|
||||
// LogModuli generates a LogModuli struct from the parameters' Moduli struct and returns it.
|
||||
func (p *Parameters) LogModuli() (lm *LogModuli) {
|
||||
lm = new(LogModuli)
|
||||
lm.LogQi = make([]uint64, len(p.qi), len(p.qi))
|
||||
lm.LogQi = make([]uint64, len(p.qi))
|
||||
for i := range p.qi {
|
||||
lm.LogQi[i] = uint64(math.Round(math.Log2(float64(p.qi[i]))))
|
||||
}
|
||||
lm.LogPi = make([]uint64, len(p.pi), len(p.pi))
|
||||
lm.LogPi = make([]uint64, len(p.pi))
|
||||
for i := range p.pi {
|
||||
lm.LogPi[i] = uint64(math.Round(math.Log2(float64(p.pi[i]))))
|
||||
}
|
||||
@@ -471,8 +459,8 @@ func (p *Parameters) UnmarshalBinary(data []byte) error {
|
||||
|
||||
p.t = b.ReadUint64()
|
||||
p.sigma = math.Float64frombits(b.ReadUint64())
|
||||
p.qi = make([]uint64, lenQi, lenQi)
|
||||
p.pi = make([]uint64, lenPi, lenPi)
|
||||
p.qi = make([]uint64, lenQi)
|
||||
p.pi = make([]uint64, lenPi)
|
||||
|
||||
b.ReadUint64Slice(p.qi)
|
||||
b.ReadUint64Slice(p.pi)
|
||||
|
||||
@@ -45,7 +45,7 @@ func BenchmarkBootstrapp(b *testing.B) {
|
||||
// ModUp ct_{Q_0} -> ct_{Q_L}
|
||||
t = time.Now()
|
||||
ct = btp.modUp(ct)
|
||||
b.Log("After ModUp :", time.Now().Sub(t), ct.Level(), ct.Scale())
|
||||
b.Log("After ModUp :", time.Since(t), ct.Level(), ct.Scale())
|
||||
|
||||
// Brings the ciphertext scale to sineQi/(Q0/scale) if its under
|
||||
btp.evaluator.ScaleUp(ct, math.Round(btp.postscale/ct.Scale()), ct)
|
||||
@@ -53,23 +53,23 @@ func BenchmarkBootstrapp(b *testing.B) {
|
||||
//SubSum X -> (N/dslots) * Y^dslots
|
||||
t = time.Now()
|
||||
ct = btp.subSum(ct)
|
||||
b.Log("After SubSum :", time.Now().Sub(t), ct.Level(), ct.Scale())
|
||||
b.Log("After SubSum :", time.Since(t), ct.Level(), ct.Scale())
|
||||
// Part 1 : Coeffs to slots
|
||||
|
||||
t = time.Now()
|
||||
ct0, ct1 = btp.coeffsToSlots(ct)
|
||||
b.Log("After CtS :", time.Now().Sub(t), ct0.Level(), ct0.Scale())
|
||||
b.Log("After CtS :", time.Since(t), ct0.Level(), ct0.Scale())
|
||||
|
||||
// Part 2 : SineEval
|
||||
t = time.Now()
|
||||
ct0, ct1 = btp.evaluateSine(ct0, ct1)
|
||||
b.Log("After Sine :", time.Now().Sub(t), ct0.Level(), ct0.Scale())
|
||||
b.Log("After Sine :", time.Since(t), ct0.Level(), ct0.Scale())
|
||||
|
||||
// Part 3 : Slots to coeffs
|
||||
t = time.Now()
|
||||
ct0 = btp.slotsToCoeffs(ct0, ct1)
|
||||
ct0.SetScale(math.Exp2(math.Round(math.Log2(ct0.Scale()))))
|
||||
b.Log("After StC :", time.Now().Sub(t), ct0.Level(), ct0.Scale())
|
||||
b.Log("After StC :", time.Since(t), ct0.Level(), ct0.Scale())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package ckks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"math/cmplx"
|
||||
|
||||
@@ -41,8 +40,6 @@ type Bootstrapper struct {
|
||||
|
||||
ctxpool *Ciphertext // Memory pool
|
||||
|
||||
decryptor Decryptor
|
||||
|
||||
poolQ [1]*ring.Poly // Memory pool for the matrix evaluation
|
||||
poolP [2]*ring.Poly // Memory pool for the matrix evaluation
|
||||
}
|
||||
@@ -62,17 +59,6 @@ func cos2pi(x complex128) complex128 {
|
||||
return cmplx.Cos(6.283185307179586 * x)
|
||||
}
|
||||
|
||||
func (btp *Bootstrapper) printDebug(message string, ciphertext *Ciphertext) {
|
||||
|
||||
coeffs := btp.encoder.Decode(btp.decryptor.DecryptNew(ciphertext), btp.dslots)
|
||||
|
||||
if btp.dslots == 2 {
|
||||
log.Printf(message+"%.10f %.10f...\n", coeffs[0], coeffs[1])
|
||||
} else {
|
||||
log.Printf(message+"%.10f %.10f %.10f %.10f...\n", coeffs[0], coeffs[1], coeffs[2], coeffs[3])
|
||||
}
|
||||
}
|
||||
|
||||
// NewBootstrapper creates a new Bootstrapper.
|
||||
func NewBootstrapper(params *Parameters, btpParams *BootstrappParams, btpKey *BootstrappingKey) (btp *Bootstrapper, err error) {
|
||||
|
||||
@@ -237,8 +223,6 @@ func (btp *Bootstrapper) genDFTMatrices() {
|
||||
|
||||
log.Println("Switching-Keys size (GB) :", float64(nbKeys*nbPoly*nbCoefficients*bytesPerCoeff)/float64(1000000000), "(", nbKeys, "keys)")
|
||||
*/
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (btp *Bootstrapper) genSinePoly() {
|
||||
|
||||
@@ -54,21 +54,6 @@ func chebyshevNodes(n int, a, b complex128) (u []complex128) {
|
||||
return
|
||||
}
|
||||
|
||||
func evaluateChebyshevPolynomial(coeffs []complex128, x complex128, a, b complex128) (y complex128) {
|
||||
var u, Tprev, Tnext, T complex128
|
||||
u = (2*x - a - b) / (b - a)
|
||||
Tprev = 1
|
||||
T = u
|
||||
y = coeffs[0]
|
||||
for i := 1; i < len(coeffs); i++ {
|
||||
y = y + T*coeffs[i]
|
||||
Tnext = 2*u*T - Tprev
|
||||
Tprev = T
|
||||
T = Tnext
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func chebyCoeffs(nodes, fi []complex128, a, b complex128) (coeffs []complex128) {
|
||||
|
||||
var u, Tprev, T, Tnext complex128
|
||||
|
||||
@@ -946,7 +946,6 @@ func testRotateColumns(testContext *testParams, t *testing.T) {
|
||||
values1, _, ciphertext1 := newTestVectors(testContext, testContext.encryptorSk, complex(-1, -1), complex(1, 1), t)
|
||||
|
||||
values2 := make([]complex128, len(values1))
|
||||
ciphertext2 := NewCiphertext(testContext.params, ciphertext1.Degree(), ciphertext1.Level(), ciphertext1.Scale())
|
||||
|
||||
for n := 1; n < len(values1); n <<= 1 {
|
||||
|
||||
@@ -955,9 +954,7 @@ func testRotateColumns(testContext *testParams, t *testing.T) {
|
||||
values2[i] = values1[(i+n)%len(values1)]
|
||||
}
|
||||
|
||||
ciphertext2 = testContext.evaluator.RotateNew(ciphertext1, uint64(n), rotKey)
|
||||
|
||||
verifyTestVectors(testContext, testContext.decryptor, values2, ciphertext2, t)
|
||||
verifyTestVectors(testContext, testContext.decryptor, values2, testContext.evaluator.RotateNew(ciphertext1, uint64(n), rotKey), t)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
@@ -138,22 +138,6 @@ func (eval *evaluator) getElemAndCheckBinary(op0, op1, opOut Operand, opOutMinDe
|
||||
return
|
||||
}
|
||||
|
||||
func (eval *evaluator) getElemAndCheckUnary(op0, opOut Operand, opOutMinDegree uint64) (el0, elOut *Element) {
|
||||
if op0 == nil || opOut == nil {
|
||||
panic("operand cannot be nil")
|
||||
}
|
||||
|
||||
if op0.Degree() == 0 {
|
||||
panic("operand cannot be plaintext")
|
||||
}
|
||||
|
||||
if opOut.Degree() < opOutMinDegree {
|
||||
panic("receiver operand degree is too small")
|
||||
}
|
||||
el0, elOut = op0.El(), opOut.El()
|
||||
return
|
||||
}
|
||||
|
||||
func (eval *evaluator) newCiphertextBinary(op0, op1 Operand) (ctOut *Ciphertext) {
|
||||
|
||||
maxDegree := utils.MaxUint64(op0.Degree(), op1.Degree())
|
||||
@@ -385,31 +369,28 @@ func (eval *evaluator) AddConstNew(ct0 *Ciphertext, constant interface{}) (ctOut
|
||||
// AddConst adds the input constant (which can be a uint64, int64, float64 or complex128) to ct0 and returns the result in ctOut.
|
||||
func (eval *evaluator) AddConst(ct0 *Ciphertext, constant interface{}, ctOut *Ciphertext) {
|
||||
|
||||
var level uint64
|
||||
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
var cReal, cImag float64
|
||||
|
||||
switch constant.(type) {
|
||||
switch constant := constant.(type) {
|
||||
case complex128:
|
||||
cReal = real(constant.(complex128))
|
||||
cImag = imag(constant.(complex128))
|
||||
cReal = real(constant)
|
||||
cImag = imag(constant)
|
||||
|
||||
case float64:
|
||||
cReal = constant.(float64)
|
||||
cReal = constant
|
||||
cImag = float64(0)
|
||||
|
||||
case uint64:
|
||||
cReal = float64(constant.(uint64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int64:
|
||||
cReal = float64(constant.(int64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int:
|
||||
cReal = float64(constant.(int))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
}
|
||||
|
||||
@@ -485,9 +466,7 @@ func (eval *evaluator) AddConst(ct0 *Ciphertext, constant interface{}, ctOut *Ci
|
||||
// The scale of the receiver element will be set to the scale that the input element would have after the multiplication by the constant.
|
||||
func (eval *evaluator) MultByConstAndAdd(ct0 *Ciphertext, constant interface{}, ctOut *Ciphertext) {
|
||||
|
||||
var level uint64
|
||||
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
// Forces a drop of ctOut level to ct0 level
|
||||
if ctOut.Level() > level {
|
||||
@@ -499,10 +478,10 @@ func (eval *evaluator) MultByConstAndAdd(ct0 *Ciphertext, constant interface{},
|
||||
|
||||
// Converts to float64 and determines if a scaling is required (which is the case if either real or imag have a rational part)
|
||||
scale = 1
|
||||
switch constant.(type) {
|
||||
switch constant := constant.(type) {
|
||||
case complex128:
|
||||
cReal = real(constant.(complex128))
|
||||
cImag = imag(constant.(complex128))
|
||||
cReal = real(constant)
|
||||
cImag = imag(constant)
|
||||
|
||||
if cReal != 0 {
|
||||
valueInt := int64(cReal)
|
||||
@@ -523,7 +502,7 @@ func (eval *evaluator) MultByConstAndAdd(ct0 *Ciphertext, constant interface{},
|
||||
}
|
||||
|
||||
case float64:
|
||||
cReal = constant.(float64)
|
||||
cReal = constant
|
||||
cImag = float64(0)
|
||||
|
||||
if cReal != 0 {
|
||||
@@ -536,15 +515,15 @@ func (eval *evaluator) MultByConstAndAdd(ct0 *Ciphertext, constant interface{},
|
||||
}
|
||||
|
||||
case uint64:
|
||||
cReal = float64(constant.(uint64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int64:
|
||||
cReal = float64(constant.(int64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int:
|
||||
cReal = float64(constant.(int))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
}
|
||||
|
||||
@@ -679,19 +658,16 @@ func (eval *evaluator) MultByConstNew(ct0 *Ciphertext, constant interface{}) (ct
|
||||
// needs to be scaled (its rational part is not zero)). The constant can be a uint64, int64, float64 or complex128.
|
||||
func (eval *evaluator) MultByConst(ct0 *Ciphertext, constant interface{}, ctOut *Ciphertext) {
|
||||
|
||||
var level uint64
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
var cReal, cImag float64
|
||||
var scale float64
|
||||
var scale, cReal, cImag float64
|
||||
|
||||
// Converts to float64 and determines if a scaling is required (which is the case if either real or imag have a rational part)
|
||||
scale = 1
|
||||
switch constant.(type) {
|
||||
switch constant := constant.(type) {
|
||||
case complex128:
|
||||
cReal = real(constant.(complex128))
|
||||
cImag = imag(constant.(complex128))
|
||||
cReal = real(constant)
|
||||
cImag = imag(constant)
|
||||
|
||||
if cReal != 0 {
|
||||
valueInt := int64(cReal)
|
||||
@@ -712,7 +688,7 @@ func (eval *evaluator) MultByConst(ct0 *Ciphertext, constant interface{}, ctOut
|
||||
}
|
||||
|
||||
case float64:
|
||||
cReal = constant.(float64)
|
||||
cReal = constant
|
||||
cImag = float64(0)
|
||||
|
||||
if cReal != 0 {
|
||||
@@ -725,15 +701,15 @@ func (eval *evaluator) MultByConst(ct0 *Ciphertext, constant interface{}, ctOut
|
||||
}
|
||||
|
||||
case uint64:
|
||||
cReal = float64(constant.(uint64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int64:
|
||||
cReal = float64(constant.(int64))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
|
||||
case int:
|
||||
cReal = float64(constant.(int))
|
||||
cReal = float64(constant)
|
||||
cImag = float64(0)
|
||||
}
|
||||
|
||||
@@ -996,9 +972,7 @@ func (eval *evaluator) MultByiNew(ct0 *Ciphertext) (ctOut *Ciphertext) {
|
||||
// It does not change the scale.
|
||||
func (eval *evaluator) MultByi(ct0 *Ciphertext, ctOut *Ciphertext) {
|
||||
|
||||
var level uint64
|
||||
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
ringQ := eval.ringQ
|
||||
|
||||
@@ -1068,9 +1042,7 @@ func (eval *evaluator) DivByiNew(ct0 *Ciphertext) (ctOut *Ciphertext) {
|
||||
// It does not change the scale.
|
||||
func (eval *evaluator) DivByi(ct0 *Ciphertext, ctOut *Ciphertext) {
|
||||
|
||||
var level uint64
|
||||
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
|
||||
ringQ := eval.ringQ
|
||||
|
||||
@@ -1139,7 +1111,6 @@ func (eval *evaluator) ScaleUpNew(ct0 *Ciphertext, scale float64) (ctOut *Cipher
|
||||
func (eval *evaluator) ScaleUp(ct0 *Ciphertext, scale float64, ctOut *Ciphertext) {
|
||||
eval.MultByConst(ct0, uint64(scale), ctOut)
|
||||
ctOut.SetScale(ct0.Scale() * scale)
|
||||
return
|
||||
}
|
||||
|
||||
// SetScale sets the scale of the ciphertext to the input scale (consumes a level)
|
||||
@@ -1169,8 +1140,7 @@ func (eval *evaluator) MulByPow2New(ct0 *Ciphertext, pow2 uint64) (ctOut *Cipher
|
||||
|
||||
// MulByPow2 multiplies ct0 by 2^pow2 and returns the result in ctOut.
|
||||
func (eval *evaluator) MulByPow2(ct0 *Element, pow2 uint64, ctOut *Element) {
|
||||
var level uint64
|
||||
level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
var level = utils.MinUint64(ct0.Level(), ctOut.Level())
|
||||
for i := range ctOut.Value() {
|
||||
eval.ringQ.MulByPow2Lvl(level, ct0.value[i], pow2, ctOut.Value()[i])
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ func (el *Element) NTT(ringQ *ring.Ring, c *Element) error {
|
||||
if el.Degree() != c.Degree() {
|
||||
return errors.New("error: receiver element has invalid degree (it does not match)")
|
||||
}
|
||||
if el.IsNTT() != true {
|
||||
if !el.IsNTT() {
|
||||
for i := range el.value {
|
||||
ringQ.NTTLvl(el.Level(), el.Value()[i], c.Value()[i])
|
||||
}
|
||||
@@ -110,7 +110,7 @@ func (el *Element) InvNTT(ringQ *ring.Ring, c *Element) error {
|
||||
if el.Degree() != c.Degree() {
|
||||
return errors.New("error: receiver element invalid degree (it does not match)")
|
||||
}
|
||||
if el.IsNTT() != false {
|
||||
if el.IsNTT() {
|
||||
for i := range el.value {
|
||||
ringQ.InvNTTLvl(el.Level(), el.Value()[i], c.Value()[i])
|
||||
}
|
||||
|
||||
@@ -252,9 +252,9 @@ func NewParametersFromModuli(logN uint64, m *Moduli) (p *Parameters, err error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.qi = make([]uint64, len(m.Qi), len(m.Qi))
|
||||
p.qi = make([]uint64, len(m.Qi))
|
||||
copy(p.qi, m.Qi)
|
||||
p.pi = make([]uint64, len(m.Pi), len(m.Pi))
|
||||
p.pi = make([]uint64, len(m.Pi))
|
||||
copy(p.pi, m.Pi)
|
||||
|
||||
p.sigma = DefaultSigma
|
||||
@@ -365,12 +365,12 @@ func (p *Parameters) LogModuli() (lm *LogModuli) {
|
||||
|
||||
lm = new(LogModuli)
|
||||
|
||||
lm.LogQi = make([]uint64, len(p.qi), len(p.qi))
|
||||
lm.LogQi = make([]uint64, len(p.qi))
|
||||
for i := range p.qi {
|
||||
lm.LogQi[i] = uint64(math.Round(math.Log2(float64(p.qi[i]))))
|
||||
}
|
||||
|
||||
lm.LogPi = make([]uint64, len(p.pi), len(p.pi))
|
||||
lm.LogPi = make([]uint64, len(p.pi))
|
||||
for i := range p.pi {
|
||||
lm.LogPi[i] = uint64(math.Round(math.Log2(float64(p.pi[i]))))
|
||||
}
|
||||
@@ -381,8 +381,8 @@ func (p *Parameters) LogModuli() (lm *LogModuli) {
|
||||
// Moduli returns a struct Moduli with the moduli of the parameters
|
||||
func (p *Parameters) Moduli() (m *Moduli) {
|
||||
m = new(Moduli)
|
||||
m.Qi = make([]uint64, p.QiCount(), p.QiCount())
|
||||
m.Pi = make([]uint64, p.PiCount(), p.PiCount())
|
||||
m.Qi = make([]uint64, p.QiCount())
|
||||
m.Pi = make([]uint64, p.PiCount())
|
||||
copy(m.Qi, p.qi)
|
||||
copy(m.Pi, p.pi)
|
||||
return
|
||||
@@ -520,9 +520,9 @@ func (p *Parameters) Copy() (paramsCopy *Parameters) {
|
||||
paramsCopy.logSlots = p.logSlots
|
||||
paramsCopy.scale = p.scale
|
||||
paramsCopy.sigma = p.sigma
|
||||
paramsCopy.qi = make([]uint64, len(p.qi), len(p.qi))
|
||||
paramsCopy.qi = make([]uint64, len(p.qi))
|
||||
copy(paramsCopy.qi, p.qi)
|
||||
paramsCopy.pi = make([]uint64, len(p.pi), len(p.pi))
|
||||
paramsCopy.pi = make([]uint64, len(p.pi))
|
||||
copy(paramsCopy.pi, p.pi)
|
||||
return
|
||||
}
|
||||
@@ -597,8 +597,8 @@ func (p *Parameters) UnmarshalBinary(data []byte) (err error) {
|
||||
lenQi := b.ReadUint8()
|
||||
lenPi := b.ReadUint8()
|
||||
|
||||
p.qi = make([]uint64, lenQi, lenQi)
|
||||
p.pi = make([]uint64, lenPi, lenPi)
|
||||
p.qi = make([]uint64, lenQi)
|
||||
p.pi = make([]uint64, lenPi)
|
||||
|
||||
b.ReadUint64Slice(p.qi)
|
||||
b.ReadUint64Slice(p.pi)
|
||||
|
||||
@@ -18,7 +18,7 @@ type Poly struct {
|
||||
func NewPoly(coeffs []complex128) (p *Poly) {
|
||||
|
||||
p = new(Poly)
|
||||
p.coeffs = make([]complex128, len(coeffs), len(coeffs))
|
||||
p.coeffs = make([]complex128, len(coeffs))
|
||||
copy(p.coeffs, coeffs)
|
||||
p.maxDeg = uint64(len(coeffs) - 1)
|
||||
p.lead = true
|
||||
@@ -49,36 +49,6 @@ func (p *Poly) Degree() uint64 {
|
||||
return uint64(len(p.coeffs) - 1)
|
||||
}
|
||||
|
||||
func optimalSplit(logDegree uint64) (logSplit uint64) {
|
||||
logSplit = logDegree >> 1
|
||||
a := (1 << logSplit) + (1 << (logDegree - logSplit)) + logDegree - logSplit - 3
|
||||
b := (1 << (logSplit + 1)) + (1 << (logDegree - logSplit - 1)) + logDegree - logSplit - 4
|
||||
if a > b {
|
||||
logSplit++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func computeSmallPoly(split uint64, coeffs *Poly) (polyList []*Poly) {
|
||||
|
||||
if coeffs.Degree() < (1 << split) {
|
||||
return []*Poly{coeffs}
|
||||
}
|
||||
|
||||
var nextPower = uint64(1 << split)
|
||||
for nextPower < (coeffs.Degree()>>1)+1 {
|
||||
nextPower <<= 1
|
||||
}
|
||||
|
||||
coeffsq, coeffsr := splitCoeffsCheby(coeffs, nextPower)
|
||||
|
||||
a := computeSmallPoly(split, coeffsq)
|
||||
b := computeSmallPoly(split, coeffsr)
|
||||
|
||||
return append(a, b...)
|
||||
}
|
||||
|
||||
// EvaluatePoly evaluates a polynomial in standard basis on the input Ciphertext in ceil(log2(deg+1)) levels.
|
||||
// Returns an error if the input ciphertext does not have enough level to carry out the full polynomial evaluation.
|
||||
// Returns an error if something is wrong with the scale.
|
||||
@@ -105,7 +75,7 @@ func (eval *evaluator) EvaluatePoly(ct0 *Ciphertext, pol *Poly, evakey *Evaluati
|
||||
|
||||
opOut, err = recurse(eval.scale, logSplit, logDegree, pol, C, eval, evakey)
|
||||
C = nil
|
||||
return opOut, nil
|
||||
return opOut, err
|
||||
}
|
||||
|
||||
// EvaluateCheby evaluates a polynomial in Chebyshev basis on the input Ciphertext in ceil(log2(deg+1))+1 levels.
|
||||
|
||||
@@ -40,13 +40,13 @@ func GetPrecisionStats(params *Parameters, encoder Encoder, decryptor Decryptor,
|
||||
logSlots := params.LogSlots()
|
||||
slots := uint64(1 << logSlots)
|
||||
|
||||
switch element.(type) {
|
||||
switch element := element.(type) {
|
||||
case *Ciphertext:
|
||||
valuesTest = encoder.Decode(decryptor.DecryptNew(element.(*Ciphertext)), logSlots)
|
||||
valuesTest = encoder.Decode(decryptor.DecryptNew(element), logSlots)
|
||||
case *Plaintext:
|
||||
valuesTest = encoder.Decode(element.(*Plaintext), logSlots)
|
||||
valuesTest = encoder.Decode(element, logSlots)
|
||||
case []complex128:
|
||||
valuesTest = element.([]complex128)
|
||||
valuesTest = element
|
||||
}
|
||||
|
||||
var deltaReal, deltaImag float64
|
||||
|
||||
@@ -2,15 +2,10 @@ package ckks
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"math/cmplx"
|
||||
|
||||
"github.com/ldsec/lattigo/v2/ring"
|
||||
)
|
||||
|
||||
func exp2pi(x complex128) complex128 {
|
||||
return cmplx.Exp(2 * 3.141592653589793 * complex(0, 1) * x)
|
||||
}
|
||||
|
||||
func scaleUpExact(value float64, n float64, q uint64) (res uint64) {
|
||||
|
||||
var isNegative bool
|
||||
@@ -85,8 +80,6 @@ func scaleUpVecExact(values []float64, n float64, moduli []uint64, coeffs [][]ui
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func scaleUpVecExactBigFloat(values []*big.Float, scale float64, moduli []uint64, coeffs [][]uint64) {
|
||||
@@ -127,15 +120,6 @@ func scaleUpVecExactBigFloat(values []*big.Float, scale float64, moduli []uint64
|
||||
coeffs[j][i] = tmp.Uint64()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func modVec(values []*big.Int, q uint64, coeffs []uint64) {
|
||||
tmp := new(big.Int)
|
||||
for i := range values {
|
||||
coeffs[i] = tmp.Mod(values[i], ring.NewUint(q)).Uint64()
|
||||
}
|
||||
}
|
||||
|
||||
// Divides x by n^2, returns a float
|
||||
@@ -221,23 +205,3 @@ func sliceBitReverseInPlaceRingComplex(slice []*ring.Complex, N uint64) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func max(array []complex128) (m float64) {
|
||||
m = real(array[0])
|
||||
for _, i := range array[1:] {
|
||||
if real(i) > m {
|
||||
m = real(i)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func min(array []complex128) (m float64) {
|
||||
m = real(array[0])
|
||||
for _, i := range array[1:] {
|
||||
if real(i) < m {
|
||||
m = real(i)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -144,7 +144,6 @@ func benchRelinKeyGenNaive(testCtx *testContext, b *testing.B) {
|
||||
|
||||
type Party struct {
|
||||
*RKGProtocolNaive
|
||||
u *ring.Poly
|
||||
s *ring.Poly
|
||||
share1 RKGNaiveShareRoundOne
|
||||
share2 RKGNaiveShareRoundTwo
|
||||
|
||||
@@ -28,7 +28,6 @@ type testContext struct {
|
||||
prng utils.PRNG
|
||||
|
||||
encoder bfv.Encoder
|
||||
kgen *bfv.KeyGenerator
|
||||
|
||||
sk0Shards []*bfv.SecretKey
|
||||
sk0 *bfv.SecretKey
|
||||
@@ -256,7 +255,6 @@ func testRelinKeyGenNaive(testCtx *testContext, t *testing.T) {
|
||||
|
||||
type Party struct {
|
||||
*RKGProtocolNaive
|
||||
u *ring.Poly
|
||||
s *ring.Poly
|
||||
share1 RKGNaiveShareRoundOne
|
||||
share2 RKGNaiveShareRoundTwo
|
||||
@@ -561,12 +559,10 @@ func testRefresh(testCtx *testContext, t *testing.T) {
|
||||
ciphertextTmp := ciphertext.CopyNew().Ciphertext()
|
||||
coeffsTmp := make([]uint64, len(coeffs))
|
||||
|
||||
for i := range coeffs {
|
||||
coeffsTmp[i] = coeffs[i]
|
||||
}
|
||||
copy(coeffsTmp, coeffs)
|
||||
|
||||
// Finds the maximum multiplicative depth
|
||||
for true {
|
||||
for {
|
||||
|
||||
testCtx.evaluator.Relinearize(testCtx.evaluator.MulNew(ciphertextTmp, ciphertextTmp), rlk, ciphertextTmp)
|
||||
|
||||
|
||||
@@ -49,8 +49,7 @@ func (share *RefreshShare) MarshalBinary() ([]byte, error) {
|
||||
}
|
||||
|
||||
ptr += tmp
|
||||
tmp, err = (*share.RefreshShareRecrypt).WriteTo(data[ptr : ptr+lenRecrypt])
|
||||
if err != nil {
|
||||
if _, err = (*share.RefreshShareRecrypt).WriteTo(data[ptr : ptr+lenRecrypt]); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
|
||||
@@ -178,8 +178,6 @@ func (ekg *RKGProtocol) GenShareRoundOne(u, sk *ring.Poly, crp []*ring.Poly, sha
|
||||
}
|
||||
|
||||
ekg.polypool.Zero()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AggregateShareRoundOne adds share1 and share2 on shareOut.
|
||||
|
||||
@@ -50,7 +50,7 @@ func (share *RTGShare) MarshalBinary() ([]byte, error) {
|
||||
// UnmarshalBinary decodes a slice of bytes on the target element.
|
||||
func (share *RTGShare) UnmarshalBinary(data []byte) error {
|
||||
if len(data) <= 24 {
|
||||
return errors.New("Unsufficient data length")
|
||||
return errors.New("unsufficient data length")
|
||||
}
|
||||
share.K = binary.BigEndian.Uint64(data[0:8])
|
||||
share.Type = bfv.Rotation(binary.BigEndian.Uint64(data[8:16]))
|
||||
@@ -189,8 +189,6 @@ func (rtg *RTGProtocol) genShare(sk *ring.Poly, galEl uint64, crp []*ring.Poly,
|
||||
|
||||
rtg.tmpPoly[0].Zero()
|
||||
rtg.tmpPoly[1].Zero()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Aggregate is the second part of the unique round of the rotkg protocol. Uppon receiving the j-1 public shares,
|
||||
|
||||
@@ -32,6 +32,7 @@ func BenchmarkDCKKS(b *testing.B) {
|
||||
benchPublicKeySwitching(testCtx, b)
|
||||
benchRotKeyGen(testCtx, b)
|
||||
benchRefresh(testCtx, b)
|
||||
benchRefreshAndPermute(testCtx, b)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +133,6 @@ func benchRelinKeyGenNaive(testCtx *testContext, b *testing.B) {
|
||||
|
||||
type Party struct {
|
||||
*RKGProtocolNaive
|
||||
u *ring.Poly
|
||||
s *ring.Poly
|
||||
share1 RKGNaiveShareRoundOne
|
||||
share2 RKGNaiveShareRoundTwo
|
||||
|
||||
@@ -266,7 +266,6 @@ func testRelinKeyGenNaive(testCtx *testContext, t *testing.T) {
|
||||
|
||||
type Party struct {
|
||||
*RKGProtocolNaive
|
||||
u *ring.Poly
|
||||
s *ring.Poly
|
||||
share1 RKGNaiveShareRoundOne
|
||||
share2 RKGNaiveShareRoundTwo
|
||||
@@ -696,11 +695,11 @@ func verifyTestVectors(testCtx *testContext, decryptor ckks.Decryptor, valuesWan
|
||||
var plaintextTest *ckks.Plaintext
|
||||
var valuesTest []complex128
|
||||
|
||||
switch element.(type) {
|
||||
switch element := element.(type) {
|
||||
case *ckks.Ciphertext:
|
||||
plaintextTest = decryptor.DecryptNew(element.(*ckks.Ciphertext))
|
||||
plaintextTest = decryptor.DecryptNew(element)
|
||||
case *ckks.Plaintext:
|
||||
plaintextTest = element.(*ckks.Plaintext)
|
||||
plaintextTest = element
|
||||
}
|
||||
|
||||
slots := testCtx.params.Slots()
|
||||
|
||||
@@ -40,6 +40,8 @@ func NewCKSProtocol(params *ckks.Parameters, sigmaSmudging float64) (cks *CKSPro
|
||||
cks.tmpDelta = dckksContext.ringQ.NewPoly()
|
||||
cks.hP = dckksContext.ringP.NewPoly()
|
||||
|
||||
cks.sigmaSmudging = sigmaSmudging
|
||||
|
||||
cks.baseconverter = ring.NewFastBasisExtender(dckksContext.ringQ, dckksContext.ringP)
|
||||
prng, err := utils.NewPRNG()
|
||||
if err != nil {
|
||||
|
||||
@@ -39,6 +39,8 @@ func NewPCKSProtocol(params *ckks.Parameters, sigmaSmudging float64) *PCKSProtoc
|
||||
pcks.share0tmp = dckksContext.ringQP.NewPoly()
|
||||
pcks.share1tmp = dckksContext.ringQP.NewPoly()
|
||||
|
||||
pcks.sigmaSmudging = sigmaSmudging
|
||||
|
||||
pcks.baseconverter = ring.NewFastBasisExtender(dckksContext.ringQ, dckksContext.ringP)
|
||||
prng, err := utils.NewPRNG()
|
||||
if err != nil {
|
||||
|
||||
@@ -175,8 +175,6 @@ func (ekg *RKGProtocol) GenShareRoundOne(u, sk *ring.Poly, crp []*ring.Poly, sha
|
||||
// s*a + e_2i
|
||||
ringQP.MulCoeffsMontgomeryAndAdd(sk, crp[i], shareOut[i][1])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AggregateShareRoundOne adds share1 and share2 on shareOut.
|
||||
|
||||
@@ -144,8 +144,6 @@ func (rtg *RTGProtocol) genShare(sk *ring.Poly, galEl uint64, crp []*ring.Poly,
|
||||
|
||||
rtg.tmpPoly[0].Zero()
|
||||
rtg.tmpPoly[1].Zero()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Aggregate is the second part of the unique round of the rotkg protocol. Uppon receiving the j-1 public shares,
|
||||
|
||||
@@ -24,13 +24,10 @@ func chebyshevinterpolation() {
|
||||
|
||||
// Keys
|
||||
kgen := ckks.NewKeyGenerator(params)
|
||||
var sk *ckks.SecretKey
|
||||
var pk *ckks.PublicKey
|
||||
sk, pk = kgen.GenKeyPair()
|
||||
sk, pk := kgen.GenKeyPair()
|
||||
|
||||
// Relinearization key
|
||||
var rlk *ckks.EvaluationKey
|
||||
rlk = kgen.GenRelinKey(sk)
|
||||
rlk := kgen.GenRelinKey(sk)
|
||||
|
||||
// Encryptor
|
||||
encryptor := ckks.NewEncryptorFromPk(params, pk)
|
||||
@@ -98,8 +95,7 @@ func f(x complex128) complex128 {
|
||||
}
|
||||
|
||||
func round(x complex128) complex128 {
|
||||
var factor float64
|
||||
factor = 100000000
|
||||
var factor float64 = 100000000
|
||||
a := math.Round(real(x)*factor) / factor
|
||||
b := math.Round(imag(x)*factor) / factor
|
||||
return complex(a, b)
|
||||
|
||||
@@ -113,7 +113,7 @@ func main() {
|
||||
ternarySamplerMontgomery := ring.NewTernarySampler(lattigoPRNG, ringQP, 0.5, true)
|
||||
|
||||
// Create each party, and allocate the memory for all the shares that the protocols will need
|
||||
P := make([]*party, N, N)
|
||||
P := make([]*party, N)
|
||||
for i := range P {
|
||||
pi := &party{}
|
||||
pi.sk = kgen.GenSecretKey()
|
||||
@@ -121,7 +121,7 @@ func main() {
|
||||
pi.rlkEphemSk = ternarySamplerMontgomery.ReadNew()
|
||||
ringQP.NTT(pi.rlkEphemSk, pi.rlkEphemSk)
|
||||
|
||||
pi.input = make([]uint64, 1<<params.LogN(), 1<<params.LogN())
|
||||
pi.input = make([]uint64, 1<<params.LogN())
|
||||
for j := range pi.input {
|
||||
pi.input[j] = uint64(i)
|
||||
}
|
||||
@@ -223,9 +223,9 @@ func main() {
|
||||
// Pre-loading memory
|
||||
encoder := bfv.NewEncoder(params)
|
||||
l.Println("> Memory alloc Phase")
|
||||
encInputs := make([]*bfv.Ciphertext, N, N)
|
||||
plainMask := make([]*bfv.PlaintextMul, N, N)
|
||||
encPartial := make([]*bfv.Ciphertext, N, N)
|
||||
encInputs := make([]*bfv.Ciphertext, N)
|
||||
plainMask := make([]*bfv.PlaintextMul, N)
|
||||
encPartial := make([]*bfv.Ciphertext, N)
|
||||
|
||||
// Ciphertexts to be retrieved
|
||||
for i := range encInputs {
|
||||
|
||||
@@ -90,7 +90,7 @@ func main() {
|
||||
// Target private and public keys
|
||||
tsk, tpk := bfv.NewKeyGenerator(params).GenKeyPair()
|
||||
|
||||
expRes := make([]uint64, 1<<params.LogN(), 1<<params.LogN())
|
||||
expRes := make([]uint64, 1<<params.LogN())
|
||||
for i := range expRes {
|
||||
expRes[i] = 1
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func main() {
|
||||
ternarySamplerMontgomery := ring.NewTernarySampler(prng, ringQP, 0.5, true)
|
||||
|
||||
// Create each party, and allocate the memory for all the shares that the protocols will need
|
||||
P := make([]*party, N, N)
|
||||
P := make([]*party, N)
|
||||
for i := range P {
|
||||
pi := &party{}
|
||||
pi.sk = bfv.NewKeyGenerator(params).GenSecretKey()
|
||||
@@ -113,7 +113,7 @@ func main() {
|
||||
pi.rlkEphemSk = ternarySamplerMontgomery.ReadNew()
|
||||
ringQP.NTT(pi.rlkEphemSk, pi.rlkEphemSk)
|
||||
|
||||
pi.input = make([]uint64, 1<<params.LogN(), 1<<params.LogN())
|
||||
pi.input = make([]uint64, 1<<params.LogN())
|
||||
for i := range pi.input {
|
||||
if utils.RandFloat64(0, 1) > 0.3 || i == 4 {
|
||||
pi.input[i] = 1
|
||||
@@ -187,7 +187,7 @@ func main() {
|
||||
|
||||
// Pre-loading memory
|
||||
l.Println("> Memory alloc Phase")
|
||||
encInputs := make([]*bfv.Ciphertext, N, N)
|
||||
encInputs := make([]*bfv.Ciphertext, N)
|
||||
for i := range encInputs {
|
||||
encInputs[i] = bfv.NewCiphertext(params, 1)
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func main() {
|
||||
encLvls := make([][]*bfv.Ciphertext, 0)
|
||||
encLvls = append(encLvls, encInputs)
|
||||
for nLvl := N / 2; nLvl > 0; nLvl = nLvl >> 1 {
|
||||
encLvl := make([]*bfv.Ciphertext, nLvl, nLvl)
|
||||
encLvl := make([]*bfv.Ciphertext, nLvl)
|
||||
for i := range encLvl {
|
||||
encLvl[i] = bfv.NewCiphertext(params, 2)
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ func BenchmarkDivRound(b *testing.B) {
|
||||
|
||||
func BenchmarkDivRoundDebug(b *testing.B) {
|
||||
y := int64(123456789)
|
||||
x := int64(987654321)
|
||||
for i := 0; i < b.N; i++ {
|
||||
x := int64(987654321)
|
||||
x = int64(math.Round(float64(x / y)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func NextNTTPrime(q, NthRoot uint64) (qNext uint64, err error) {
|
||||
qNext += NthRoot
|
||||
|
||||
if bits.Len64(qNext) > 61 {
|
||||
return 0, fmt.Errorf("Next NTT prime exceeds the maximum bit-size of 61 bits")
|
||||
return 0, fmt.Errorf("next NTT prime exceeds the maximum bit-size of 61 bits")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func NextNTTPrime(q, NthRoot uint64) (qNext uint64, err error) {
|
||||
func PreviousNTTPrime(q, NthRoot uint64) (qPrev uint64, err error) {
|
||||
|
||||
if q < NthRoot {
|
||||
return 0, fmt.Errorf("Previous NTT prime is smaller than NthRoot")
|
||||
return 0, fmt.Errorf("previous NTT prime is smaller than NthRoot")
|
||||
}
|
||||
|
||||
qPrev = q - NthRoot
|
||||
@@ -57,7 +57,7 @@ func PreviousNTTPrime(q, NthRoot uint64) (qPrev uint64, err error) {
|
||||
for !IsPrime(qPrev) {
|
||||
|
||||
if q < NthRoot {
|
||||
return 0, fmt.Errorf("Previous NTT prime is smaller than NthRoot")
|
||||
return 0, fmt.Errorf("previous NTT prime is smaller than NthRoot")
|
||||
}
|
||||
|
||||
qPrev -= NthRoot
|
||||
@@ -83,10 +83,10 @@ func GenerateNTTPrimesQ(logQ, NthRoot, levels uint64) (primes []uint64) {
|
||||
checkfornextprime = true
|
||||
checkforpreviousprime = true
|
||||
|
||||
for true {
|
||||
for {
|
||||
|
||||
if !(checkfornextprime || checkforpreviousprime) {
|
||||
panic("GenerateNTTPrimesQ error: cannot generate enough primes for the given parameters")
|
||||
panic("generateNTTPrimesQ error: cannot generate enough primes for the given parameters")
|
||||
}
|
||||
|
||||
if checkfornextprime {
|
||||
@@ -149,7 +149,7 @@ func GenerateNTTPrimesP(logP, NthRoot, n uint64) (primes []uint64) {
|
||||
|
||||
x = Ppow2 + 1
|
||||
|
||||
for true {
|
||||
for {
|
||||
|
||||
// We start by subtracting 2N to ensure that the prime bit-length is smaller than LogP
|
||||
|
||||
@@ -167,7 +167,7 @@ func GenerateNTTPrimesP(logP, NthRoot, n uint64) (primes []uint64) {
|
||||
}
|
||||
|
||||
} else {
|
||||
panic("GenerateNTTPrimesP error: cannot generate enough primes for the given parameters")
|
||||
panic("generateNTTPrimesP error: cannot generate enough primes for the given parameters")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ func (r *Ring) genNTTParams() error {
|
||||
}
|
||||
}
|
||||
|
||||
r.RescaleParams = make([][]uint64, len(r.Modulus)-1, len(r.Modulus)-1)
|
||||
r.RescaleParams = make([][]uint64, len(r.Modulus)-1)
|
||||
|
||||
for j := len(r.Modulus) - 1; j > 0; j-- {
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ func benchBRed(testContext *testParams, b *testing.B) {
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
b.Run(fmt.Sprintf("BRed"), func(b *testing.B) {
|
||||
b.Run("BRed", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
x = BRed(x, y, q, u)
|
||||
}
|
||||
@@ -439,7 +439,7 @@ func benchMRed(testContext *testParams, b *testing.B) {
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
b.Run(fmt.Sprintf("MRed"), func(b *testing.B) {
|
||||
b.Run("MRed", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
x = MRed(x, y, q, m)
|
||||
}
|
||||
@@ -454,7 +454,7 @@ func benchBRedAdd(testContext *testParams, b *testing.B) {
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
b.Run(fmt.Sprintf("BRedAdd"), func(b *testing.B) {
|
||||
b.Run("BRedAdd", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
BRedAdd(x, q, u)
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func (pol *Poly) WriteTo(data []byte) (uint64, error) {
|
||||
|
||||
if uint64(len(data)) < pol.GetDataLen(true) {
|
||||
// The data is not big enough to write all the information
|
||||
return 0, errors.New("Data array is too small to write ring.Poly")
|
||||
return 0, errors.New("data array is too small to write ring.Poly")
|
||||
}
|
||||
data[0] = uint8(bits.Len64(uint64(N)) - 1)
|
||||
data[1] = uint8(numberModuli)
|
||||
@@ -160,7 +160,7 @@ func (pol *Poly) WriteTo32(data []byte) (uint64, error) {
|
||||
|
||||
if uint64(len(data)) < pol.GetDataLen32(true) {
|
||||
//the data is not big enough to write all the information
|
||||
return 0, errors.New("Data array is too small to write ring.Poly")
|
||||
return 0, errors.New("data array is too small to write ring.Poly")
|
||||
}
|
||||
data[0] = uint8(bits.Len64(uint64(N)) - 1)
|
||||
data[1] = uint8(numberModuli)
|
||||
@@ -256,7 +256,7 @@ func (pol *Poly) UnmarshalBinary(data []byte) (err error) {
|
||||
pointer := uint64(2)
|
||||
|
||||
if ((uint64(len(data)) - pointer) >> 3) != N*numberModulies {
|
||||
return errors.New("error: invalid polynomial encoding")
|
||||
return errors.New("invalid polynomial encoding")
|
||||
}
|
||||
|
||||
if _, err = pol.DecodePolyNew(data); err != nil {
|
||||
|
||||
@@ -63,8 +63,6 @@ func (uniformSampler *UniformSampler) Read(Pol *Poly) {
|
||||
ptmp[i] = randomUint
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Readlvl generates a new polynomial with coefficients following a uniform distribution over [0, Qi-1].
|
||||
@@ -109,8 +107,6 @@ func (uniformSampler *UniformSampler) Readlvl(level uint64, Pol *Poly) {
|
||||
ptmp[i] = randomUint
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ReadNew generates a new polynomial with coefficients following a uniform distribution over [0, Qi-1].
|
||||
|
||||
@@ -15,10 +15,8 @@ type Scaler interface {
|
||||
// RNSScaler implements the Scaler interface by performing a scaling by t/Q in the RNS domain.
|
||||
// This implementation of the Scaler interface is preferred over the SimpleScaler implementation.
|
||||
type RNSScaler struct {
|
||||
ringQ *Ring
|
||||
paramsQT *modupParams
|
||||
modDownParamsQT uint64
|
||||
polypoolT *Poly
|
||||
ringQ *Ring
|
||||
polypoolT *Poly
|
||||
|
||||
qHalf *big.Int // (q-1)/2
|
||||
qHalfModT uint64 // (q-1)/2 mod t
|
||||
@@ -26,7 +24,6 @@ type RNSScaler struct {
|
||||
t uint64
|
||||
qInv uint64 //(q mod t)^-1 mod t
|
||||
|
||||
bredParamsT []uint64
|
||||
mredParamsT uint64
|
||||
|
||||
paramsQP *modupParams
|
||||
@@ -468,7 +465,6 @@ func (r *Ring) DivRoundByLastModulus(p0 *Poly) {
|
||||
pHalf = (r.Modulus[level] - 1) >> 1
|
||||
p0tmp := p0.Coeffs[level]
|
||||
pj := r.Modulus[level]
|
||||
pHalf = (r.Modulus[level] - 1) >> 1
|
||||
|
||||
for i := uint64(0); i < r.N; i = i + 8 {
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ func TestRing(t *testing.T) {
|
||||
testTernarySampler(testContext, t)
|
||||
testGaloisShift(testContext, t)
|
||||
testModularReduction(testContext, t)
|
||||
testMForm(testContext, t)
|
||||
testMulScalarBigint(testContext, t)
|
||||
testMulPoly(testContext, t)
|
||||
testExtendBasis(testContext, t)
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestBuffer_WriteReadUint64Slice(t *testing.T) {
|
||||
b := NewBuffer(make([]byte, 0, 8))
|
||||
b.WriteUint64Slice([]uint64{0x1122334455667788})
|
||||
assert.Equal(t, []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, b.Bytes())
|
||||
s := make([]uint64, 1, 1)
|
||||
s := make([]uint64, 1)
|
||||
b.ReadUint64Slice(s)
|
||||
assert.Equal(t, []uint64{0x1122334455667788}, s)
|
||||
assert.Equal(t, []byte{}, b.Bytes())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -9,7 +8,7 @@ import (
|
||||
|
||||
func Test_PRNG(t *testing.T) {
|
||||
|
||||
t.Run(fmt.Sprintf("PRNG"), func(t *testing.T) {
|
||||
t.Run("PRNG", func(t *testing.T) {
|
||||
|
||||
key := []byte{0x49, 0x0a, 0x42, 0x3d, 0x97, 0x9d, 0xc1, 0x07, 0xa1, 0xd7, 0xe9, 0x7b, 0x3b, 0xce, 0xa1, 0xdb,
|
||||
0x42, 0xf3, 0xa6, 0xd5, 0x75, 0xd2, 0x0c, 0x92, 0xb7, 0x35, 0xce, 0x0c, 0xee, 0x09, 0x7c, 0x98}
|
||||
|
||||
Reference in New Issue
Block a user