From e280a38bbcd7badaccd0fc043ce587b1bf667369 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Wed, 22 Jul 2020 13:00:36 +0200 Subject: [PATCH] Fixed merge conflicts and go fmt --- ckks/boot_bench_test.go | 27 ++- ckks/boot_test.go | 8 +- ckks/bootstrapp.go | 6 +- ckks/ckks_benchmarks_test.go | 4 +- ckks/ckks_test.go | 173 ++++++++----------- ckks/encoder.go | 1 + ckks/utils.go | 4 +- dbfv/public_permute.go | 6 +- dckks/dckks_benchmark_test.go | 2 +- experiments/boot_precision/boot_precision.go | 11 +- ring/ring_test.go | 4 +- 11 files changed, 119 insertions(+), 127 deletions(-) diff --git a/ckks/boot_bench_test.go b/ckks/boot_bench_test.go index d3a62eb3..ebe06a6d 100644 --- a/ckks/boot_bench_test.go +++ b/ckks/boot_bench_test.go @@ -2,6 +2,7 @@ package ckks import ( "fmt" + "github.com/ldsec/lattigo/utils" "testing" ) @@ -23,6 +24,11 @@ func BenchmarkBootstrapp(b *testing.B) { bootparams.Gen() + prng, err := utils.NewPRNG() + if err != nil { + panic(err) + } + ctsDepth := uint64(len(bootparams.CtSLevel)) sinDepth := bootparams.SinDepth @@ -38,7 +44,7 @@ func BenchmarkBootstrapp(b *testing.B) { b.Run(testString("ModUp/", parameters), func(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ciphertext = NewCiphertextRandom(parameters, 1, 0, LTScale) + ciphertext = NewCiphertextRandom(prng, parameters, 1, 0, LTScale) b.StartTimer() ciphertext = bootcontext.modUp(ciphertext) @@ -58,7 +64,7 @@ func BenchmarkBootstrapp(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ciphertext = NewCiphertextRandom(parameters, 1, parameters.MaxLevel, LTScale) + ciphertext = NewCiphertextRandom(prng, parameters, 1, parameters.MaxLevel, LTScale) b.StartTimer() ct0, ct1 = bootcontext.coeffsToSlots(ciphertext) @@ -72,9 +78,9 @@ func BenchmarkBootstrapp(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ct0 = NewCiphertextRandom(parameters, 1, parameters.MaxLevel-ctsDepth, LTScale) + ct0 = NewCiphertextRandom(prng, parameters, 1, parameters.MaxLevel-ctsDepth, LTScale) if parameters.LogSlots == parameters.LogN-1 { - ct1 = NewCiphertextRandom(parameters, 1, parameters.MaxLevel-ctsDepth, LTScale) + ct1 = NewCiphertextRandom(prng, parameters, 1, parameters.MaxLevel-ctsDepth, LTScale) } else { ct1 = nil } @@ -100,9 +106,9 @@ func BenchmarkBootstrapp(b *testing.B) { for i := 0; i < b.N; i++ { b.StopTimer() - ct2 = NewCiphertextRandom(parameters, 1, parameters.MaxLevel-ctsDepth-sinDepth, LTScale) + ct2 = NewCiphertextRandom(prng, parameters, 1, parameters.MaxLevel-ctsDepth-sinDepth, LTScale) if parameters.LogSlots == parameters.LogN-1 { - ct3 = NewCiphertextRandom(parameters, 1, parameters.MaxLevel-ctsDepth-sinDepth, LTScale) + ct3 = NewCiphertextRandom(prng, parameters, 1, parameters.MaxLevel-ctsDepth-sinDepth, LTScale) } else { ct3 = nil } @@ -137,6 +143,11 @@ func BenchmarkBootstrappMultiplications(b *testing.B) { LTScale = 1 << 45 //SineScale = 1 << 55 + prng, err := utils.NewPRNG() + if err != nil { + panic(err) + } + bootParams := new(Parameters) bootParams.LogN = 16 bootParams.LogSlots = 15 @@ -152,8 +163,8 @@ func BenchmarkBootstrappMultiplications(b *testing.B) { rlk = kgen.GenRelinKey(sk) eval = NewEvaluator(bootParams) - ct0 := NewCiphertextRandom(bootParams, 1, bootParams.MaxLevel, LTScale) - ct1 := NewCiphertextRandom(bootParams, 1, bootParams.MaxLevel, LTScale) + ct0 := NewCiphertextRandom(prng, bootParams, 1, bootParams.MaxLevel, LTScale) + ct1 := NewCiphertextRandom(prng, bootParams, 1, bootParams.MaxLevel, LTScale) for true { diff --git a/ckks/boot_test.go b/ckks/boot_test.go index 2229c135..a95d80d6 100644 --- a/ckks/boot_test.go +++ b/ckks/boot_test.go @@ -69,7 +69,7 @@ func TestBootstrapp(t *testing.T) { fmt.Printf("Elapsed : %s \n", time.Since(start)) fmt.Println(ciphertext.Level()) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) params.params.Scale = DefaultScale parameters.Scale = DefaultScale @@ -136,7 +136,7 @@ func TestBootstrapp(t *testing.T) { fmt.Printf("Elapsed : %s \n", time.Since(start)) fmt.Println(ciphertext.Level(), ciphertext.Scale()) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) params.params.Scale = DefaultScale parameters.Scale = DefaultScale @@ -158,7 +158,7 @@ func TestBootstrapp(t *testing.T) { values := make([]complex128, slots) for i := range values { - values[i] = complex(RandomFloat(-1, 1), RandomFloat(-1, 1)) + values[i] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } values[0] = complex(0.9238795325112867, 0.3826834323650898) @@ -179,7 +179,7 @@ func TestBootstrapp(t *testing.T) { //params.evaluator.SetScale(ciphertext, parameters.Scale) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) //fmt.Println() } diff --git a/ckks/bootstrapp.go b/ckks/bootstrapp.go index f55dca5f..3ffba104 100644 --- a/ckks/bootstrapp.go +++ b/ckks/bootstrapp.go @@ -228,7 +228,7 @@ func (bootcontext *BootContext) multiplyByDiagMatrice(vec *Ciphertext, plainVect for _, i := range rotations { if i != 0 { ring.PermuteNTTWithIndexLvl(levelQ, c0, bootcontext.rotkeys.permuteNTTLeftIndex[i], tmpQ0) // phi(P*c0) - contextQ.AddLvl(levelQ, vecRotQ[i].value[0], tmpQ0, vecRotQ[i].value[0]) // phi(d0_Q) += phi(P*c0) + contextQ.AddLvl(levelQ, vecRotQ[i].value[0], tmpQ0, vecRotQ[i].value[0]) // phi(d0_Q) += phi(P*c0) } } @@ -271,7 +271,7 @@ func (bootcontext *BootContext) multiplyByDiagMatrice(vec *Ciphertext, plainVect // Hoisting of the ModDown of sum(sum(phi(d0 + P*c0) * plaintext)) and sum(sum(phi(d1) * plaintext)) eval.baseconverter.ModDownSplitedNTTPQ(levelQ, tmpQ2, tmpP2, tmpResQ0) // sum(phi(d0) * plaintext)/P eval.baseconverter.ModDownSplitedNTTPQ(levelQ, tmpQ3, tmpP3, tmpResQ1) // sum(phi(d1) * plaintext)/P - + // If i == 0 if state { N1Rot++ @@ -344,7 +344,7 @@ func (bootcontext *BootContext) multiplyByDiagMatrice(vec *Ciphertext, plainVect contextQ.AddLvl(levelQ, res.value[0], tmpQ0, res.value[0]) // res += sum(phi(c0 * P + d0_QP))/P contextQ.AddLvl(levelQ, res.value[1], tmpQ1, res.value[1]) // res += sum(phi(d1_QP))/P - if state { // Rotation by zero + if state { // Rotation by zero N1Rot++ contextQ.MulCoeffsMontgomeryAndAddLvl(levelQ, plainVectors.Vec[0][0], vec.value[0], res.value[0]) // res += c0_Q * plaintext contextQ.MulCoeffsMontgomeryAndAddLvl(levelQ, plainVectors.Vec[0][0], vec.value[1], res.value[1]) // res += c1_Q * plaintext diff --git a/ckks/ckks_benchmarks_test.go b/ckks/ckks_benchmarks_test.go index b5a288c6..9861611a 100644 --- a/ckks/ckks_benchmarks_test.go +++ b/ckks/ckks_benchmarks_test.go @@ -28,7 +28,7 @@ func benchEncoder(b *testing.B) { values := make([]complex128, slots) for i := uint64(0); i < slots; i++ { - values[i] = complex(RandomFloat(-1, 1), RandomFloat(-1, 1)) + values[i] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } plaintext := NewPlaintext(parameters, parameters.MaxLevel, parameters.Scale) @@ -42,7 +42,7 @@ func benchEncoder(b *testing.B) { values := make([]complex128, slots) for i := uint64(0); i < slots; i++ { - values[i] = complex(RandomFloat(-1, 1), RandomFloat(-1, 1)) + values[i] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } plaintext := NewPlaintext(parameters, parameters.MaxLevel, parameters.Scale) diff --git a/ckks/ckks_test.go b/ckks/ckks_test.go index 0e3e0bc5..f5c7eabc 100644 --- a/ckks/ckks_test.go +++ b/ckks/ckks_test.go @@ -9,9 +9,9 @@ import ( "testing" "time" - "github.com/ldsec/lattigo/ring" - "github.com/ldsec/lattigo/utils" "github.com/stretchr/testify/require" + + "github.com/ldsec/lattigo/utils" ) func testString(opname string, params *Parameters) string { @@ -49,14 +49,14 @@ type ckksTestParameters struct { var err error var testParams = new(ckksTestParameters) -var printPrecisionStats = flag.Bool("print-precision", false, "print precision stats") +var printPrecisionStats = flag.Bool("print-precision", true, "print precision stats") func init() { rand.Seed(time.Now().UnixNano()) testParams.medianprec = 15 - testParams.ckksParameters = DefaultParams[PN12QP109 : PN12QP109+2] + testParams.ckksParameters = DefaultParams[PN12QP109 : PN12QP109+3] } func TestCKKS(t *testing.T) { @@ -93,7 +93,7 @@ func genCkksParams(contextParameters *Parameters) (params *ckksParams) { params.kgen = NewKeyGenerator(contextParameters) - params.sk, params.pk = params.kgen.GenKeyPairSparse(192) + params.sk, params.pk = params.kgen.GenKeyPairSparse(128) params.encoder = NewEncoder(contextParameters) @@ -137,7 +137,7 @@ func newTestVectorsReals(contextParams *ckksParams, encryptor Encryptor, a, b fl values = make([]complex128, slots) for i := uint64(0); i < slots; i++ { - values[i] = complex(RandomFloat(a, b), 0) + values[i] = complex(randomFloat(a, b), 0) } values[0] = complex(0.607538, 0) @@ -160,11 +160,9 @@ func newTestVectorsSineBoot(contextParams *ckksParams, encryptor Encryptor, a, b values = make([]complex128, slots) for i := uint64(0); i < slots; i++ { - values[i] = complex(math.Round(RandomFloat(a, b))+RandomFloat(-1, 1)/1000, 0) + values[i] = complex(math.Round(randomFloat(a, b))+randomFloat(-1, 1)/1000, 0) } - values[0] = complex(math.Round(RandomFloat(a, b))+0.9238795325112867/1000, 0) - plaintext = NewPlaintext(contextParams.params, contextParams.params.MaxLevel, contextParams.params.Scale) contextParams.encoder.EncodeNTT(plaintext, values, slots) @@ -176,9 +174,10 @@ func newTestVectorsSineBoot(contextParams *ckksParams, encryptor Encryptor, a, b return values, plaintext, ciphertext } -func verifyTestVectors(params *Parameters, encoder Encoder, decryptor Decryptor, valuesWant []complex128, element interface{}, t *testing.T) { +func verifyTestVectors(contextParams *ckksParams, decryptor Decryptor, valuesWant []complex128, element interface{}, t *testing.T) { - prec := GetPrecisionStats(params, encoder, decryptor, valuesWant, element) + var plaintextTest *Plaintext + var valuesTest []complex128 switch element.(type) { case *Ciphertext: @@ -248,8 +247,8 @@ func verifyTestVectors(params *Parameters, encoder Encoder, decryptor Decryptor, t.Log() } - require.GreaterOrEqual(t, math.Log2(1/real(prec.MeanDelta)), testParams.medianprec) - require.GreaterOrEqual(t, math.Log2(1/imag(prec.MedianDelta)), testParams.medianprec) + require.GreaterOrEqual(t, math.Log2(1/real(medianprec)), testParams.medianprec) + require.GreaterOrEqual(t, math.Log2(1/imag(medianprec)), testParams.medianprec) } func testEncoder(t *testing.T) { @@ -262,7 +261,7 @@ func testEncoder(t *testing.T) { values, plaintext, _ := newTestVectors(params, nil, 1, t) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, plaintext, t) + verifyTestVectors(params, params.decryptor, values, plaintext, t) }) t.Run(testString("EncodeCoeffs/", parameters), func(t *testing.T) { @@ -272,7 +271,7 @@ func testEncoder(t *testing.T) { valuesWant := make([]float64, slots) for i := uint64(0); i < slots; i++ { - valuesWant[i] = RandomFloat(-1, 1) + valuesWant[i] = randomFloat(-1, 1) } valuesWant[0] = 0.607538 @@ -293,48 +292,6 @@ func testEncoder(t *testing.T) { require.GreaterOrEqual(t, math.Log2(1/meanprec), testParams.medianprec) }) - - t.Run(testString("EncodeBigComplex/", parameters), func(t *testing.T) { - - prec := uint64(parameters.LogQP >> 1) - - encoder := NewEncoderBigComplex(parameters, prec+15) - - scale := math.Pow(2, float64(prec)) - - values := make([]*ring.Complex, parameters.Slots) - - for i := range values { - values[i] = ring.NewComplex(ring.NewFloat(float64(i+1), prec), ring.NewFloat(0, prec)) - } - - plaintext := NewPlaintext(parameters, parameters.MaxLevel, scale) - - encoder.EncodeNTT(plaintext, values, parameters.Slots) - - valuesTest := encoder.Decode(plaintext, parameters.Slots) - - error := ring.NewFloat(math.Pow(2, -float64(prec-15)), prec) - - for i := range values { - values[i].Sub(values[i], valuesTest[i]) - values[i].Real().Abs(values[i].Real()) - values[i].Imag().Abs(values[i].Imag()) - - /* - if i == 0 { - fmt.Println(prec) - fmt.Println(error.Float64()) - fmt.Println(values[i].Float64()) - fmt.Println(error.Cmp(values[i].Real())) - } - */ - - // Checks that 2^-{prec} > abs(have-want) - require.Greater(t, error.Cmp(values[i].Real()), 0) - require.Greater(t, error.Cmp(values[i].Imag()), 0) - } - }) } } @@ -348,7 +305,7 @@ func testEncryptor(t *testing.T) { values, _, ciphertext := newTestVectors(params, params.encryptorPk, 1, t) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) t.Run(testString("EncryptFromPkFast/", parameters), func(t *testing.T) { @@ -367,14 +324,14 @@ func testEncryptor(t *testing.T) { params.encoder.Encode(plaintext, values, slots) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, params.encryptorPk.EncryptFastNew(plaintext), t) + verifyTestVectors(params, params.decryptor, values, params.encryptorPk.EncryptFastNew(plaintext), t) }) t.Run(testString("EncryptFromSk/", parameters), func(t *testing.T) { values, _, ciphertext := newTestVectors(params, params.encryptorSk, 1, t) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) t.Run(testString("EncryptFromSkFast/", parameters), func(t *testing.T) { @@ -393,7 +350,7 @@ func testEncryptor(t *testing.T) { params.encoder.Encode(plaintext, values, slots) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, params.encryptorSk.EncryptFastNew(plaintext), t) + verifyTestVectors(params, params.decryptor, values, params.encryptorSk.EncryptFastNew(plaintext), t) }) } } @@ -415,7 +372,7 @@ func testEvaluatorAdd(t *testing.T) { params.evaluator.Add(ciphertext1, ciphertext2, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext1, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext1, t) }) t.Run(testString("CtCtNew/", parameters), func(t *testing.T) { @@ -429,7 +386,7 @@ func testEvaluatorAdd(t *testing.T) { ciphertext3 := params.evaluator.AddNew(ciphertext1, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext3, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext3, t) }) t.Run(testString("CtPlainInPlace/", parameters), func(t *testing.T) { @@ -443,7 +400,7 @@ func testEvaluatorAdd(t *testing.T) { params.evaluator.Add(ciphertext1, plaintext2, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext1, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext1, t) for i := range values1 { values1[i] += values2[i] @@ -451,7 +408,7 @@ func testEvaluatorAdd(t *testing.T) { params.evaluator.Add(plaintext2, ciphertext1, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext1, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext1, t) }) t.Run(testString("CtPlainInPlaceNew/", parameters), func(t *testing.T) { @@ -465,11 +422,11 @@ func testEvaluatorAdd(t *testing.T) { ciphertext3 := params.evaluator.AddNew(ciphertext1, plaintext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext3, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext3, t) ciphertext3 = params.evaluator.AddNew(plaintext2, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext3, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext3, t) }) } } @@ -491,7 +448,7 @@ func testEvaluatorSub(t *testing.T) { params.evaluator.Sub(ciphertext1, ciphertext2, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext1, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext1, t) }) t.Run(testString("CtCtNew/", parameters), func(t *testing.T) { @@ -505,7 +462,7 @@ func testEvaluatorSub(t *testing.T) { ciphertext3 := params.evaluator.SubNew(ciphertext1, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext3, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext3, t) }) t.Run(testString("CtPlainInPlace/", parameters), func(t *testing.T) { @@ -520,7 +477,7 @@ func testEvaluatorSub(t *testing.T) { params.evaluator.Sub(ciphertext1, plaintext2, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, valuesTest, ciphertext2, t) + verifyTestVectors(params, params.decryptor, valuesTest, ciphertext2, t) for i := range values1 { valuesTest[i] = values2[i] - values1[i] @@ -528,7 +485,7 @@ func testEvaluatorSub(t *testing.T) { params.evaluator.Sub(plaintext2, ciphertext1, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, valuesTest, ciphertext2, t) + verifyTestVectors(params, params.decryptor, valuesTest, ciphertext2, t) }) t.Run(testString("CtPlainNew/", parameters), func(t *testing.T) { @@ -543,7 +500,7 @@ func testEvaluatorSub(t *testing.T) { ciphertext3 := params.evaluator.SubNew(ciphertext1, plaintext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, valuesTest, ciphertext3, t) + verifyTestVectors(params, params.decryptor, valuesTest, ciphertext3, t) for i := range values1 { valuesTest[i] = values2[i] - values1[i] @@ -551,7 +508,7 @@ func testEvaluatorSub(t *testing.T) { ciphertext3 = params.evaluator.SubNew(plaintext2, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, valuesTest, ciphertext3, t) + verifyTestVectors(params, params.decryptor, valuesTest, ciphertext3, t) }) } } @@ -574,7 +531,7 @@ func testEvaluatorRescale(t *testing.T) { params.evaluator.Rescale(ciphertext, parameters.Scale, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) t.Run(testString("Many/", parameters), func(t *testing.T) { @@ -591,7 +548,7 @@ func testEvaluatorRescale(t *testing.T) { params.evaluator.RescaleMany(ciphertext, nbRescales, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } @@ -615,7 +572,7 @@ func testEvaluatorAddConst(t *testing.T) { params.evaluator.AddConst(ciphertext, constant, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -638,7 +595,7 @@ func testEvaluatorMultByConst(t *testing.T) { params.evaluator.MultByConst(ciphertext, constant, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -662,7 +619,7 @@ func testEvaluatorMultByConstAndAdd(t *testing.T) { params.evaluator.MultByConstAndAdd(ciphertext1, constant, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) }) } } @@ -684,7 +641,7 @@ func testEvaluatorMul(t *testing.T) { params.evaluator.MulRelin(ciphertext1, ciphertext2, nil, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) }) t.Run(testString("CtCtNew/", parameters), func(t *testing.T) { @@ -699,7 +656,7 @@ func testEvaluatorMul(t *testing.T) { var ciphertext3 *Ciphertext ciphertext3 = params.evaluator.MulRelinNew(ciphertext1, ciphertext2, nil) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext3, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext3, t) }) t.Run(testString("CtPlain/", parameters), func(t *testing.T) { @@ -714,11 +671,11 @@ func testEvaluatorMul(t *testing.T) { params.evaluator.MulRelin(ciphertext1, plaintext1, nil, ciphertext1) - verifyTestVectors(parameters, params.encoder, params.decryptor, values1, ciphertext1, t) + verifyTestVectors(params, params.decryptor, values1, ciphertext1, t) params.evaluator.MulRelin(plaintext2, ciphertext2, nil, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) }) t.Run(testString("Relinearize/", parameters), func(t *testing.T) { @@ -738,7 +695,7 @@ func testEvaluatorMul(t *testing.T) { require.Equal(t, ciphertext2.Degree(), uint64(1)) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) }) } } @@ -772,7 +729,7 @@ func testFunctions(t *testing.T) { params.evaluator.PowerOf2(ciphertext, n, rlk, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, valuesWant, ciphertext, t) + verifyTestVectors(params, params.decryptor, valuesWant, ciphertext, t) }) } @@ -790,7 +747,7 @@ func testFunctions(t *testing.T) { params.evaluator.Power(ciphertext, n, rlk, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } @@ -807,7 +764,7 @@ func testFunctions(t *testing.T) { ciphertext = params.evaluator.InverseNew(ciphertext, n, rlk) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -823,7 +780,7 @@ func testEvaluatePoly(t *testing.T) { if parameters.MaxLevel > 4 { - t.Run(testString("Exp/", parameters), func(t *testing.T) { + t.Run(testString("Fast/Exp/", parameters), func(t *testing.T) { values, _, ciphertext := newTestVectorsReals(params, params.encryptorSk, -1, 1, t) @@ -835,7 +792,25 @@ func testEvaluatePoly(t *testing.T) { ciphertext = params.evaluator.EvaluatePolyFast(ciphertext, coeffs, rlk) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) + }) + } + + if parameters.MaxLevel > 3 { + + t.Run(testString("Eco/Exp/", parameters), func(t *testing.T) { + + values, _, ciphertext := newTestVectorsReals(params, params.encryptorSk, -1, 1, t) + + coeffs := []float64{1.0, 1.0, 1.0 / 2, 1.0 / 6, 1.0 / 24, 1.0 / 120, 1.0 / 720, 1.0 / 5040} + + for i := range values { + values[i] = cmplx.Exp(values[i]) + } + + ciphertext = params.evaluator.EvaluatePolyEco(ciphertext, coeffs, rlk) + + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -863,7 +838,7 @@ func testChebyshevInterpolator(t *testing.T) { ciphertext = params.evaluator.EvaluateCheby(ciphertext, cheby, rlk) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -885,7 +860,7 @@ func testSwitchKeys(t *testing.T) { params.evaluator.SwitchKeys(ciphertext, switchingKey, ciphertext) - verifyTestVectors(parameters, params.encoder, decryptorSk2, values, ciphertext, t) + verifyTestVectors(params, decryptorSk2, values, ciphertext, t) }) t.Run(testString("New/", parameters), func(t *testing.T) { @@ -894,7 +869,7 @@ func testSwitchKeys(t *testing.T) { ciphertext = params.evaluator.SwitchKeysNew(ciphertext, switchingKey) - verifyTestVectors(parameters, params.encoder, decryptorSk2, values, ciphertext, t) + verifyTestVectors(params, decryptorSk2, values, ciphertext, t) }) } } @@ -918,7 +893,7 @@ func testConjugate(t *testing.T) { params.evaluator.Conjugate(ciphertext, rotKey, ciphertext) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) t.Run(testString("New/", parameters), func(t *testing.T) { @@ -931,7 +906,7 @@ func testConjugate(t *testing.T) { ciphertext = params.evaluator.ConjugateNew(ciphertext, rotKey) - verifyTestVectors(parameters, params.encoder, params.decryptor, values, ciphertext, t) + verifyTestVectors(params, params.decryptor, values, ciphertext, t) }) } } @@ -960,7 +935,7 @@ func testRotateColumns(t *testing.T) { params.evaluator.RotateColumns(ciphertext1, uint64(n), rotKey, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) } }) @@ -981,7 +956,7 @@ func testRotateColumns(t *testing.T) { ciphertext2 = params.evaluator.RotateColumnsNew(ciphertext1, uint64(n), rotKey) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) } }) @@ -1004,7 +979,7 @@ func testRotateColumns(t *testing.T) { params.evaluator.RotateColumns(ciphertext1, rand, rotKey, ciphertext2) - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertext2, t) + verifyTestVectors(params, params.decryptor, values2, ciphertext2, t) } }) @@ -1014,8 +989,7 @@ func testRotateColumns(t *testing.T) { values1, _, ciphertext1 := newTestVectorsReals(params, params.encryptorSk, -1, 1, t) values2 := make([]complex128, len(values1)) - rotations := []uint64{1, 2, 3, 4, 5, 17, 31, 97, 127, 511} - + rotations := []uint64{0, 1, 2, 3, 4, 5} for _, n := range rotations { params.kgen.GenRot(RotationLeft, params.sk, n, rotKey) } @@ -1028,8 +1002,9 @@ func testRotateColumns(t *testing.T) { values2[i] = values1[(i+int(n))%len(values1)] } - verifyTestVectors(parameters, params.encoder, params.decryptor, values2, ciphertexts[n], t) + verifyTestVectors(params, params.decryptor, values2, ciphertexts[n], t) } + }) } } diff --git a/ckks/encoder.go b/ckks/encoder.go index 6d0a9b03..1ebb7723 100644 --- a/ckks/encoder.go +++ b/ckks/encoder.go @@ -136,6 +136,7 @@ func (encoder *encoderComplex128) scaleUp(pol *ring.Poly, scale float64, moduli scaleUpVecExact(encoder.valuesfloat, scale, moduli, pol.Coeffs) } +func (encoder *encoderComplex128) wipeInternalMemory() { for i := range encoder.values { encoder.values[i] = 0 } diff --git a/ckks/utils.go b/ckks/utils.go index c2b47dc0..ee029aa4 100644 --- a/ckks/utils.go +++ b/ckks/utils.go @@ -11,12 +11,12 @@ func exp2pi(x complex128) complex128 { return cmplx.Exp(2 * 3.141592653589793 * complex(0, 1) * x) } -func RandomFloat(min, max float64) float64 { +func randomFloat(min, max float64) float64 { return min + rand.Float64()*(max-min) } func randomComplex(min, max float64) complex128 { - return complex(RandomFloat(min, max), RandomFloat(min, max)) + return complex(randomFloat(min, max), randomFloat(min, max)) } func scaleUpExact(value float64, n float64, q uint64) (res uint64) { diff --git a/dbfv/public_permute.go b/dbfv/public_permute.go index c2098530..0f8e870b 100644 --- a/dbfv/public_permute.go +++ b/dbfv/public_permute.go @@ -14,6 +14,7 @@ type PermuteProtocol struct { tmp2 *ring.Poly hP *ring.Poly baseconverter *ring.FastBasisExtender + scaler ring.Scaler gaussianSampler *ring.GaussianSampler uniformSampler *ring.UniformSampler } @@ -57,6 +58,7 @@ func NewPermuteProtocol(params *bfv.Parameters) (refreshProtocol *PermuteProtoco } refreshProtocol.indexMatrix = indexMatrix + refreshProtocol.scaler = ring.NewRNSScaler(params.T, context.contextQ) prng, err := utils.NewPRNG() if err != nil { @@ -162,9 +164,7 @@ func (pp *PermuteProtocol) Permute(sharePlaintext *ring.Poly, permutation []uint contextT := pp.context.contextT - scaler := ring.NewSimpleScaler(pp.context.params.T, pp.context.contextQ) - - scaler.Scale(sharePlaintext, sharePlaintextOut) + pp.scaler.DivByQOverTRounded(sharePlaintext, sharePlaintextOut) contextT.NTT(sharePlaintextOut, sharePlaintextOut) diff --git a/dckks/dckks_benchmark_test.go b/dckks/dckks_benchmark_test.go index 4b223775..ccfe0324 100644 --- a/dckks/dckks_benchmark_test.go +++ b/dckks/dckks_benchmark_test.go @@ -463,7 +463,7 @@ func benchRefreshAndPermute(b *testing.B) { crpGenerator := ring.NewUniformSampler(prng, params.dckksContext.contextQP) crp := crpGenerator.ReadNew() - ciphertext := ckks.NewCiphertextRandom(parameters, 1, levelStart, parameters.Scale) + ciphertext := ckks.NewCiphertextRandom(prng, parameters, 1, levelStart, parameters.Scale) crpGenerator.Readlvl(levelStart, ciphertext.Value()[0]) crpGenerator.Readlvl(levelStart, ciphertext.Value()[1]) diff --git a/experiments/boot_precision/boot_precision.go b/experiments/boot_precision/boot_precision.go index 3189e03e..239a8c78 100644 --- a/experiments/boot_precision/boot_precision.go +++ b/experiments/boot_precision/boot_precision.go @@ -7,10 +7,15 @@ import ( "github.com/ldsec/lattigo/ckks" "io" "log" + "math/rand" "os" "text/template" ) +func randomFloat(min, max float64) float64 { + return min + rand.Float64()*(max-min) +} + var paramSet = flag.Int("paramSet", 1, "index in BootStrappParams") var nboot = flag.Int("nboot", 1, "number of bootstrapping (on the same ct for successive and on different ct for slotdist)") var logslot = flag.Uint64("logslot", 8, "number of slots per ciphertext (max number for slotcount)") @@ -44,7 +49,7 @@ func main() { log.Println("Generating a plaintext of", params.Slots, "random values...") values := make([]complex128, params.Slots) for i := range values { - values[i] = complex(ckks.RandomFloat(-1, 1), ckks.RandomFloat(-1, 1)) + values[i] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } plaintext := ckks.NewPlaintext(¶ms.Parameters, params.MaxLevel, params.Scale) @@ -68,7 +73,7 @@ func main() { for i := range stats { values := make([]complex128, params.Slots) for i := range values { - values[i] = complex(ckks.RandomFloat(-1, 1), ckks.RandomFloat(-1, 1)) + values[i] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } plaintext := ckks.NewPlaintext(¶ms.Parameters, params.MaxLevel, params.Scale) @@ -91,7 +96,7 @@ func main() { values := make([]complex128, params.Slots) for j := range values { - values[j] = complex(ckks.RandomFloat(-1, 1), ckks.RandomFloat(-1, 1)) + values[j] = complex(randomFloat(-1, 1), randomFloat(-1, 1)) } plaintext := ckks.NewPlaintext(¶ms.Parameters, params.MaxLevel, params.Scale) diff --git a/ring/ring_test.go b/ring/ring_test.go index 5dbca1bc..3925203b 100644 --- a/ring/ring_test.go +++ b/ring/ring_test.go @@ -35,8 +35,8 @@ func init() { {DefaultParamsQi[12], DefaultParamsPi[12]}, {DefaultParamsQi[13], DefaultParamsPi[13]}, {DefaultParamsQi[14], DefaultParamsPi[14]}, - {DefaultParamsQi[15], DefaultParamsPi[15]}, - {DefaultParamsQi[16], DefaultParamsPi[16]}, + //{DefaultParamsQi[15], DefaultParamsPi[15]}, + //{DefaultParamsQi[16], DefaultParamsPi[16]}, } testParams.sigma = 3.19