From 65bea67ade2e0c5c3bccda53b4b1736c6664893e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Fri, 17 Jun 2022 18:37:42 +0200 Subject: [PATCH] Method name update, godoc, fmt --- bfv/bfv_test.go | 16 ++++---- bfv/params.go | 42 +++++++++---------- ckks/advanced/homomorphic_encoding_test.go | 6 +-- ckks/advanced/homomorphic_mod_test.go | 4 +- ckks/bootstrapping/default_params.go | 48 +++++++++++----------- ckks/ckks_test.go | 8 ++-- ckks/params.go | 32 +++++++-------- dbfv/dbfv_test.go | 2 +- examples/ckks/euler/main.go | 10 ++--- ring/ring_benchmark_test.go | 2 +- rlwe/gadget/ciphertext.go | 7 ++-- rlwe/keys.go | 2 +- rlwe/lut/evaluator.go | 12 ++++-- rlwe/lut/keys.go | 13 +++--- rlwe/lut/lut_test.go | 25 ++++++++++- rlwe/params.go | 2 +- rlwe/rgsw/ciphertext.go | 6 +-- rlwe/rlwe_benchmark_test.go | 2 +- rlwe/rlwe_test_params.go | 22 +++++----- 19 files changed, 144 insertions(+), 117 deletions(-) diff --git a/bfv/bfv_test.go b/bfv/bfv_test.go index 0288a96d..33559146 100644 --- a/bfv/bfv_test.go +++ b/bfv/bfv_test.go @@ -45,9 +45,9 @@ var ( // TESTTDivQN2Q1P is a set of test parameters where T = Q[0]. TESTTDivQN2Q1P = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 14, - Q: []uint64{0x10001, 0xffffffffffe8001, 0xffffffffffd8001, 0xffffffffffc0001, 0xffffffffff28001}, - P: []uint64{0x1fffffffffe10001, 0x1fffffffffe00001}, + LogN: 14, + Q: []uint64{0x10001, 0xffffffffffe8001, 0xffffffffffd8001, 0xffffffffffc0001, 0xffffffffff28001}, + P: []uint64{0x1fffffffffe10001, 0x1fffffffffe00001}, }, T: 0x10001, } @@ -55,9 +55,9 @@ var ( // TESTTCPrimeQN2Q1P is a set of test parameters where T is coprime with Q. TESTTCPrimeQN2Q1P = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 14, - Q: []uint64{0xffffffffffe8001, 0xffffffffffd8001, 0xffffffffffc0001, 0xffffffffff28001}, - P: []uint64{0x1fffffffffe10001, 0x1fffffffffe00001}, + LogN: 14, + Q: []uint64{0xffffffffffe8001, 0xffffffffffd8001, 0xffffffffffc0001, 0xffffffffff28001}, + P: []uint64{0x1fffffffffe10001, 0x1fffffffffe00001}, }, T: 0x10001, } @@ -749,7 +749,7 @@ func testPolyEval(tc *testContext, t *testing.T) { var err error if ciphertext, err = tc.evaluator.EvaluatePoly(ciphertext, poly); err != nil { - + t.Fatal(err) } verifyTestVectors(tc, tc.decryptor, values, ciphertext, t) @@ -791,7 +791,7 @@ func testPolyEval(tc *testContext, t *testing.T) { var err error if ciphertext, err = tc.evaluator.EvaluatePolyVector(ciphertext, polyVec, tc.encoder, slotIndex); err != nil { - + t.Fatal(err) } verifyTestVectors(tc, tc.decryptor, values, ciphertext, t) diff --git a/bfv/params.go b/bfv/params.go index fdc90a45..3800a63f 100644 --- a/bfv/params.go +++ b/bfv/params.go @@ -16,9 +16,9 @@ var ( // PN11QP54 is a set of default parameters with logN=11 and logQP=54 PN11QP54 = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 11, - Q: []uint64{0x3001, 0x15400000001}, // 13.5 + 40.4 bits - P: []uint64{}, + LogN: 11, + Q: []uint64{0x3001, 0x15400000001}, // 13.5 + 40.4 bits + P: []uint64{}, LogBase2: 6, }, T: 0x3001, @@ -27,18 +27,18 @@ var ( // PN12QP109 is a set of default parameters with logN=12 and logQP=109 PN12QP109 = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 12, - Q: []uint64{0x7ffffec001, 0x8000016001}, // 39 + 39 bits - P: []uint64{0x40002001}, // 30 bits + LogN: 12, + Q: []uint64{0x7ffffec001, 0x8000016001}, // 39 + 39 bits + P: []uint64{0x40002001}, // 30 bits }, T: 65537, } // PN13QP218 is a set of default parameters with logN=13 and logQP=218 PN13QP218 = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 13, - Q: []uint64{0x3fffffffef8001, 0x4000000011c001, 0x40000000120001}, // 54 + 54 + 54 bits - P: []uint64{0x7ffffffffb4001}, // 55 bits + LogN: 13, + Q: []uint64{0x3fffffffef8001, 0x4000000011c001, 0x40000000120001}, // 54 + 54 + 54 bits + P: []uint64{0x7ffffffffb4001}, // 55 bits }, T: 65537, } @@ -49,7 +49,7 @@ var ( LogN: 14, Q: []uint64{0x100000000060001, 0x80000000068001, 0x80000000080001, 0x3fffffffef8001, 0x40000000120001, 0x3fffffffeb8001}, // 56 + 55 + 55 + 54 + 54 + 54 bits - P: []uint64{0x80000000130001, 0x7fffffffe90001}, // 55 + 55 bits + P: []uint64{0x80000000130001, 0x7fffffffe90001}, // 55 + 55 bits }, T: 65537, } @@ -62,7 +62,7 @@ var ( 0x400000000270001, 0x400000000350001, 0x400000000360001, // 58 + 58 + 58 bits 0x3ffffffffc10001, 0x3ffffffffbe0001, 0x3ffffffffbd0001, // 58 + 58 + 58 bits 0x4000000004d0001, 0x400000000570001, 0x400000000660001}, // 58 + 58 + 58 bits - P: []uint64{0xffffffffffc0001, 0x10000000001d0001, 0x10000000006e0001}, // 60 + 60 + 60 bits + P: []uint64{0xffffffffffc0001, 0x10000000001d0001, 0x10000000006e0001}, // 60 + 60 + 60 bits }, T: 65537, } @@ -70,9 +70,9 @@ var ( // PN12QP101pq is a set of default (post quantum) parameters with logN=12 and logQP=101 PN12QP101pq = ParametersLiteral{ // LogQP = 101.00005709794536 ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 12, - Q: []uint64{0x800004001, 0x800008001}, // 2*35 - P: []uint64{0x80014001}, // 1*31 + LogN: 12, + Q: []uint64{0x800004001, 0x800008001}, // 2*35 + P: []uint64{0x80014001}, // 1*31 }, T: 65537, } @@ -80,9 +80,9 @@ var ( // PN13QP202pq is a set of default (post quantum) parameters with logN=13 and logQP=202 PN13QP202pq = ParametersLiteral{ // LogQP = 201.99999999994753 ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 13, - Q: []uint64{0x7fffffffe0001, 0x7fffffffcc001, 0x3ffffffffc001}, // 2*51 + 50 - P: []uint64{0x4000000024001}, // 50 + LogN: 13, + Q: []uint64{0x7fffffffe0001, 0x7fffffffcc001, 0x3ffffffffc001}, // 2*51 + 50 + P: []uint64{0x4000000024001}, // 50 }, T: 65537, } @@ -90,9 +90,9 @@ var ( // PN14QP411pq is a set of default (post quantum) parameters with logN=14 and logQP=411 PN14QP411pq = ParametersLiteral{ // LogQP = 410.9999999999886 ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 14, - Q: []uint64{0x7fffffffff18001, 0x8000000000f8001, 0x7ffffffffeb8001, 0x800000000158001, 0x7ffffffffe70001}, // 5*59 - P: []uint64{0x7ffffffffe10001, 0x400000000068001}, // 59+58 + LogN: 14, + Q: []uint64{0x7fffffffff18001, 0x8000000000f8001, 0x7ffffffffeb8001, 0x800000000158001, 0x7ffffffffe70001}, // 5*59 + P: []uint64{0x7ffffffffe10001, 0x400000000068001}, // 59+58 }, T: 65537, } @@ -104,7 +104,7 @@ var ( Q: []uint64{0x7ffffffffe70001, 0x7ffffffffe10001, 0x7ffffffffcc0001, 0x7ffffffffba0001, 0x8000000004a0001, 0x7ffffffffb00001, 0x800000000890001, 0x8000000009d0001, 0x7ffffffff630001, 0x800000000a70001, 0x7ffffffff510001}, // 11*59 - P: []uint64{0x800000000b80001, 0x800000000bb0001, 0xffffffffffc0001}, // 2*59+60 + P: []uint64{0x800000000b80001, 0x800000000bb0001, 0xffffffffffc0001}, // 2*59+60 }, T: 65537, } diff --git a/ckks/advanced/homomorphic_encoding_test.go b/ckks/advanced/homomorphic_encoding_test.go index 6d507d62..a906e69e 100644 --- a/ckks/advanced/homomorphic_encoding_test.go +++ b/ckks/advanced/homomorphic_encoding_test.go @@ -36,9 +36,9 @@ func TestHomomorphicEncoding(t *testing.T) { 0x1fffffffffe00001, // Pi 61 0x1fffffffffc80001, // Pi 61 }, - - H: 0, - Sigma: rlwe.DefaultSigma, + + H: 0, + Sigma: rlwe.DefaultSigma, }, LogSlots: 12, DefaultScale: 1 << 45, diff --git a/ckks/advanced/homomorphic_mod_test.go b/ckks/advanced/homomorphic_mod_test.go index 6adc0c6e..a899b686 100644 --- a/ckks/advanced/homomorphic_mod_test.go +++ b/ckks/advanced/homomorphic_mod_test.go @@ -44,8 +44,8 @@ func TestHomomorphicMod(t *testing.T) { 0x1fffffffff500001, // Pi 61 0x1fffffffff420001, // Pi 61 }, - H: 0, - Sigma: rlwe.DefaultSigma, + H: 0, + Sigma: rlwe.DefaultSigma, }, LogSlots: 13, DefaultScale: 1 << 45, diff --git a/ckks/bootstrapping/default_params.go b/ckks/bootstrapping/default_params.go index e2f03291..0ebe45c7 100644 --- a/ckks/bootstrapping/default_params.go +++ b/ckks/bootstrapping/default_params.go @@ -30,9 +30,9 @@ var ( N16QP1546H192H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 192, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 192, Q: []uint64{ 0x10000000006e0001, // 60 Q0 0x10000140001, // 40 @@ -121,9 +121,9 @@ var ( N16QP1547H192H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 192, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 192, Q: []uint64{ 0x10000000006e0001, // 60 Q0 0x2000000a0001, // 45 @@ -210,9 +210,9 @@ var ( N16QP1553H192H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 192, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 192, Q: []uint64{ 0x80000000080001, // 55 Q0 0xffffffffffc0001, // 60 @@ -297,9 +297,9 @@ var ( N15QP768H192H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 15, - Sigma: rlwe.DefaultSigma, - H: 192, + LogN: 15, + Sigma: rlwe.DefaultSigma, + H: 192, Q: []uint64{ 0x1fff90001, // 32 Q0 0x4000000420001, // 50 @@ -370,9 +370,9 @@ var ( N16QP1767H32768H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 32768, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 32768, Q: []uint64{ 0x10000000006e0001, // 60 Q0 0x10000140001, // 40 @@ -466,9 +466,9 @@ var ( N16QP1788H32768H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 32768, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 32768, Q: []uint64{ 0x10000000006e0001, // 60 Q0 0x2000000a0001, // 45 @@ -560,9 +560,9 @@ var ( N16QP1793H32768H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 16, - Sigma: rlwe.DefaultSigma, - H: 32768, + LogN: 16, + Sigma: rlwe.DefaultSigma, + H: 32768, Q: []uint64{ 0x80000000080001, // 55 Q0 0xffffffffffc0001, // 60 @@ -651,9 +651,9 @@ var ( N15QP880H16384H32 = defaultParametersLiteral{ ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 15, - Sigma: rlwe.DefaultSigma, - H: 16384, + LogN: 15, + Sigma: rlwe.DefaultSigma, + H: 16384, Q: []uint64{ 0x10000140001, // 40 Q0 0x7ffe0001, // 31 diff --git a/ckks/ckks_test.go b/ckks/ckks_test.go index 0fb20104..714630cd 100644 --- a/ckks/ckks_test.go +++ b/ckks/ckks_test.go @@ -911,12 +911,12 @@ func testChebyshevInterpolator(tc *testContext, t *testing.T) { eval.AddConst(ciphertext, (-poly.A-poly.B)/(poly.B-poly.A), ciphertext) if err = eval.Rescale(ciphertext, tc.params.DefaultScale(), ciphertext); err != nil { t.Error(err) - + } if ciphertext, err = eval.EvaluatePoly(ciphertext, poly, ciphertext.Scale); err != nil { t.Error(err) - + } verifyTestVectors(tc.params, tc.encoder, tc.decryptor, values, ciphertext, tc.params.LogSlots(), 0, t) @@ -947,12 +947,12 @@ func testDecryptPublic(tc *testContext, t *testing.T) { eval.AddConst(ciphertext, (-poly.A-poly.B)/(poly.B-poly.A), ciphertext) if err := eval.Rescale(ciphertext, tc.params.DefaultScale(), ciphertext); err != nil { t.Error(err) - + } if ciphertext, err = eval.EvaluatePoly(ciphertext, poly, ciphertext.Scale); err != nil { t.Error(err) - + } plaintext := tc.decryptor.DecryptNew(ciphertext) diff --git a/ckks/params.go b/ckks/params.go index 0da2b8e3..e1e8ba3d 100644 --- a/ckks/params.go +++ b/ckks/params.go @@ -21,9 +21,9 @@ var ( // PN12QP109 is a default parameter set for logN=12 and logQP=109 PN12QP109 = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 12, - Q: []uint64{0x200000e001, 0x100006001}, // 37 + 32}, - P: []uint64{0x3ffffea001}, // 38 + LogN: 12, + Q: []uint64{0x200000e001, 0x100006001}, // 37 + 32}, + P: []uint64{0x3ffffea001}, // 38 }, LogSlots: 11, DefaultScale: 1 << 32, @@ -39,7 +39,7 @@ var ( 0x40020001, 0x40038001, 0x3ffc0001}, - P: []uint64{0x800004001}, // 35 + P: []uint64{0x800004001}, // 35 }, LogSlots: 12, DefaultScale: 1 << 30, @@ -54,7 +54,7 @@ var ( 0x400068001, 0x3fff90001, 0x400080001, 0x4000a8001, 0x400108001, 0x3ffeb8001}, - P: []uint64{0x7fffffd8001, 0x7fffffc8001}, // 43, 43 + P: []uint64{0x7fffffd8001, 0x7fffffc8001}, // 43, 43 }, LogSlots: 13, DefaultScale: 1 << 34, @@ -70,7 +70,7 @@ var ( 0x10000500001, 0x10000650001, 0xffff940001, 0xffff8a0001, 0xffff820001, 0xffff780001, 0x10000890001, 0xffff750001, 0x10000960001}, - P: []uint64{0x40000001b0001, 0x3ffffffdf0001, 0x4000000270001}, // 50, 50, 50 + P: []uint64{0x40000001b0001, 0x3ffffffdf0001, 0x4000000270001}, // 50, 50, 50 }, LogSlots: 14, DefaultScale: 1 << 40, @@ -88,7 +88,7 @@ var ( 0x2000019a0001, 0x1ffffe640001, 0x200001a00001, 0x1ffffe520001, 0x200001e80001, 0x1ffffe0c0001, 0x1ffffdee0001, 0x200002480001, 0x1ffffdb60001, 0x200002560001}, - P: []uint64{0x80000000440001, 0x7fffffffba0001, 0x80000000500001, 0x7fffffffaa0001}, // 4 x 55 + P: []uint64{0x80000000440001, 0x7fffffffba0001, 0x80000000500001, 0x7fffffffaa0001}, // 4 x 55 }, LogSlots: 15, DefaultScale: 1 << 45, @@ -179,9 +179,9 @@ var ( // PN12QP101pq is a default (post quantum) parameter set for logN=12 and logQP=101 PN12QP101pq = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 12, - Q: []uint64{0x800004001, 0x40002001}, // 35 + 30 - P: []uint64{0x1000002001}, // 36 + LogN: 12, + Q: []uint64{0x800004001, 0x40002001}, // 35 + 30 + P: []uint64{0x1000002001}, // 36 }, LogSlots: 11, DefaultScale: 1 << 30, @@ -189,9 +189,9 @@ var ( // PN13QP202pq is a default (post quantum) parameter set for logN=13 and logQP=202 PN13QP202pq = ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 13, - Q: []uint64{0x1fffec001, 0x8008001, 0x8020001, 0x802c001, 0x7fa8001, 0x7f74001}, // 33 + 5 x 27 - P: []uint64{0x400018001}, // 34 + LogN: 13, + Q: []uint64{0x1fffec001, 0x8008001, 0x8020001, 0x802c001, 0x7fa8001, 0x7f74001}, // 33 + 5 x 27 + P: []uint64{0x400018001}, // 34 }, LogSlots: 12, DefaultScale: 1 << 27, @@ -203,7 +203,7 @@ var ( LogN: 14, Q: []uint64{0x10000048001, 0x200038001, 0x1fff90001, 0x200080001, 0x1fff60001, 0x2000b8001, 0x200100001, 0x1fff00001, 0x1ffef0001, 0x200128001}, // 40 + 9 x 33 - P: []uint64{0x1ffffe0001, 0x1ffffc0001}, // 37, 37 + P: []uint64{0x1ffffe0001, 0x1ffffc0001}, // 37, 37 }, LogSlots: 13, DefaultScale: 1 << 33, @@ -217,7 +217,7 @@ var ( 0x3fffcf0001, 0x40003f0001, 0x3fffc10001, 0x4000450001, 0x3fffb80001, 0x3fffb70001, 0x40004a0001, 0x3fffb20001, 0x4000510001, 0x3fffaf0001, 0x4000540001, 0x4000560001, 0x4000590001}, // 46 + 17 x 38 - P: []uint64{0x2000000a0001, 0x2000000e0001, 0x2000001d0001}, // 3 x 45 + P: []uint64{0x2000000a0001, 0x2000000e0001, 0x2000001d0001}, // 3 x 45 }, LogSlots: 14, DefaultScale: 1 << 38, @@ -233,7 +233,7 @@ var ( 0x1ffffeca0001, 0x1ffffeb40001, 0x200001520001, 0x1ffffe760001, 0x2000019a0001, 0x1ffffe640001, 0x200001a00001, 0x1ffffe520001, 0x200001e80001, 0x1ffffe0c0001, 0x1ffffdee0001, 0x200002480001}, // 55 + 31 x 45 - P: []uint64{0x7fffffffe0001, 0x80000001c0001, 0x80000002c0001, 0x7ffffffd20001}, // 4 x 51 + P: []uint64{0x7fffffffe0001, 0x80000001c0001, 0x80000002c0001, 0x7ffffffd20001}, // 4 x 51 }, LogSlots: 15, DefaultScale: 1 << 45, diff --git a/dbfv/dbfv_test.go b/dbfv/dbfv_test.go index feed5539..2f2af58e 100644 --- a/dbfv/dbfv_test.go +++ b/dbfv/dbfv_test.go @@ -60,7 +60,7 @@ func Test_DBFV(t *testing.T) { var err error - defaultParams := bfv.DefaultParams // the default test runs for ring degree N=2^12, 2^13, 2^14, 2^15 + defaultParams := bfv.DefaultParams[1:] // the default test runs for ring degree N=2^12, 2^13, 2^14, 2^15 if testing.Short() { defaultParams = bfv.DefaultParams[:2] // the short test suite runs for ring degree N=2^12, 2^13 } diff --git a/examples/ckks/euler/main.go b/examples/ckks/euler/main.go index 0d62a6d9..77235e76 100644 --- a/examples/ckks/euler/main.go +++ b/examples/ckks/euler/main.go @@ -19,11 +19,11 @@ func example() { params, err := ckks.NewParametersFromLiteral( ckks.ParametersLiteral{ ParametersLiteral: rlwe.ParametersLiteral{ - LogN: 14, - LogQ: []int{55, 40, 40, 40, 40, 40, 40, 40}, - LogP: []int{45, 45}, - H: 0, - Sigma: rlwe.DefaultSigma}, + LogN: 14, + LogQ: []int{55, 40, 40, 40, 40, 40, 40, 40}, + LogP: []int{45, 45}, + H: 0, + Sigma: rlwe.DefaultSigma}, LogSlots: 13, DefaultScale: 1 << 40, }) diff --git a/ring/ring_benchmark_test.go b/ring/ring_benchmark_test.go index 6b3c9e22..5722d67f 100644 --- a/ring/ring_benchmark_test.go +++ b/ring/ring_benchmark_test.go @@ -23,7 +23,7 @@ func BenchmarkRing(b *testing.B) { var testContext *testParams if testContext, err = genTestParams(defaultParam); err != nil { b.Fatal(err) - + } benchGenRing(testContext, b) diff --git a/rlwe/gadget/ciphertext.go b/rlwe/gadget/ciphertext.go index e14a1f0a..805ab9f5 100644 --- a/rlwe/gadget/ciphertext.go +++ b/rlwe/gadget/ciphertext.go @@ -1,5 +1,5 @@ // Package gadget implements the R-LWE gadget ciphertexts. A gadget ciphertext is a matrix of ciphertexts encrypting plaintexts -// decomposed in the RNS and power of two basis. +// decomposed in the RNS and optionally as well in the power of two basis. package gadget import ( @@ -12,8 +12,9 @@ type Ciphertext struct { Value [][][2]ringqp.Poly } -// NewCiphertextNTT returns a new Ciphertext key with pre-allocated zero-value -func NewCiphertextNTT(levelQ, levelP, decompRNS, decompBIT int, ringQP ringqp.Ring) (ct *Ciphertext) { +// NewCiphertext returns a new Ciphertext key with pre-allocated zero-value. +// Ciphertext is always in the NTT domain. +func NewCiphertext(levelQ, levelP, decompRNS, decompBIT int, ringQP ringqp.Ring) (ct *Ciphertext) { ct = new(Ciphertext) ct.Value = make([][][2]ringqp.Poly, decompRNS) for i := 0; i < decompRNS; i++ { diff --git a/rlwe/keys.go b/rlwe/keys.go index 116bcc6f..bd721c8f 100644 --- a/rlwe/keys.go +++ b/rlwe/keys.go @@ -110,7 +110,7 @@ func (rtks *RotationKeySet) GetRotationKey(galoisEl uint64) (*SwitchingKey, bool // NewSwitchingKey returns a new public switching key with pre-allocated zero-value func NewSwitchingKey(params Parameters, levelQ, levelP int) *SwitchingKey { - return &SwitchingKey{Ciphertext: *gadget.NewCiphertextNTT( + return &SwitchingKey{Ciphertext: *gadget.NewCiphertext( levelQ, levelP, params.DecompRNS(levelQ, levelP), diff --git a/rlwe/lut/evaluator.go b/rlwe/lut/evaluator.go index a5aa8733..a078188b 100644 --- a/rlwe/lut/evaluator.go +++ b/rlwe/lut/evaluator.go @@ -25,6 +25,8 @@ type Evaluator struct { Sk *rlwe.SecretKey tmpRGSW *rgsw.Ciphertext + + one *rgsw.Plaintext } // NewEvaluator creates a new Handler @@ -120,7 +122,9 @@ func NewEvaluator(paramsLUT, paramsLWE rlwe.Parameters, rtks *rlwe.RotationKeySe decompRNS := paramsLUT.DecompRNS(levelQ, levelP) decompBIT := paramsLUT.DecompBIT(levelQ, levelP) ringQP := paramsLUT.RingQP() - eval.tmpRGSW = rgsw.NewCiphertextNTT(levelQ, levelP, decompRNS, decompBIT, *ringQP) + eval.tmpRGSW = rgsw.NewCiphertext(levelQ, levelP, decompRNS, decompBIT, *ringQP) + + eval.one = rgsw.NewPlaintext(uint64(1), levelQ, levelP, paramsLUT.LogBase2(), decompBIT, *ringQP) return } @@ -131,7 +135,7 @@ func NewEvaluator(paramsLUT, paramsLWE rlwe.Parameters, rtks *rlwe.RotationKeySe // repackIndex : a map with [slot_index_have] -> slot_index_want // lutKey : LUTKey // Returns a *rlwe.Ciphertext -func (eval *Evaluator) EvaluateAndRepack(ct *rlwe.Ciphertext, lutPolyWihtSlotIndex map[int]*ring.Poly, repackIndex map[int]int, key Key) (res *rlwe.Ciphertext) { +func (eval *Evaluator) EvaluateAndRepack(ct *rlwe.Ciphertext, lutPolyWihtSlotIndex map[int]*ring.Poly, repackIndex map[int]int, key EvaluationKey) (res *rlwe.Ciphertext) { cts := eval.Evaluate(ct, lutPolyWihtSlotIndex, key) ciphertexts := make(map[int]*rlwe.Ciphertext) @@ -148,7 +152,7 @@ func (eval *Evaluator) EvaluateAndRepack(ct *rlwe.Ciphertext, lutPolyWihtSlotInd // lutPolyWihtSlotIndex : a map with [slot_index] -> LUT // lutKey : lut.Key // Returns a map[slot_index] -> LUT(ct[slot_index]) -func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, lutPolyWihtSlotIndex map[int]*ring.Poly, key Key) (res map[int]*rlwe.Ciphertext) { +func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, lutPolyWihtSlotIndex map[int]*ring.Poly, key EvaluationKey) (res map[int]*rlwe.Ciphertext) { bRLWEMod2N := eval.poolMod2N[0] aRLWEMod2N := eval.poolMod2N[1] @@ -206,7 +210,7 @@ func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, lutPolyWihtSlotIndex map[in // RGSW[(X^{a} - 1) * sk_{j}[0] + (X^{-a} - 1) * sk_{j}[1] + 1] rgsw.MulByXPowAlphaMinusOneConstantLvl(levelQ, levelP, key.SkPos[j], eval.xPowMinusOne[a[j]], ringQPLUT, eval.tmpRGSW) rgsw.MulByXPowAlphaMinusOneAndAddNoModLvl(levelQ, levelP, key.SkNeg[j], eval.xPowMinusOne[-a[j]&mask], ringQPLUT, eval.tmpRGSW) - rgsw.AddNoModLvl(levelQ, levelP, key.One, ringQPLUT, eval.tmpRGSW) + rgsw.AddNoModLvl(levelQ, levelP, eval.one, ringQPLUT, eval.tmpRGSW) // LUT[RLWE] = LUT[RLWE] x RGSW[(X^{a} - 1) * sk_{j}[0] + (X^{-a} - 1) * sk_{j}[1] + 1] eval.ExternalProduct(acc, eval.tmpRGSW, acc) diff --git a/rlwe/lut/keys.go b/rlwe/lut/keys.go index a262c51f..d5ce6074 100644 --- a/rlwe/lut/keys.go +++ b/rlwe/lut/keys.go @@ -8,14 +8,13 @@ import ( // Key is a struct storing the encryption // of the bits of the LWE key. -type Key struct { +type EvaluationKey struct { SkPos []*rgsw.Ciphertext SkNeg []*rgsw.Ciphertext - One *rgsw.Plaintext } -// GenKey generates the LUT evaluation key -func GenKey(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.Parameters, skLWE *rlwe.SecretKey) (key Key) { +// GenEvaluationKey generates the LUT evaluation key +func GenEvaluationKey(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.Parameters, skLWE *rlwe.SecretKey) (key EvaluationKey) { skLWEInvNTT := paramsLWE.RingQ().NewPoly() @@ -48,8 +47,8 @@ func GenKey(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.P for i, si := range skLWEInvNTT.Coeffs[0] { - skRGSWPos[i] = rgsw.NewCiphertextNTT(levelQ, levelP, decompRNS, decompBIT, ringQP) - skRGSWNeg[i] = rgsw.NewCiphertextNTT(levelQ, levelP, decompRNS, decompBIT, ringQP) + skRGSWPos[i] = rgsw.NewCiphertext(levelQ, levelP, decompRNS, decompBIT, ringQP) + skRGSWNeg[i] = rgsw.NewCiphertext(levelQ, levelP, decompRNS, decompBIT, ringQP) // sk_i = 1 -> [RGSW(1), RGSW(0)] if si == OneMForm { @@ -66,5 +65,5 @@ func GenKey(paramsRLWE rlwe.Parameters, skRLWE *rlwe.SecretKey, paramsLWE rlwe.P } } - return Key{SkPos: skRGSWPos, SkNeg: skRGSWNeg, One: rgsw.NewPlaintext(uint64(1), levelQ, levelP, paramsRLWE.LogBase2(), decompBIT, ringQP)} + return EvaluationKey{SkPos: skRGSWPos, SkNeg: skRGSWNeg} } diff --git a/rlwe/lut/lut_test.go b/rlwe/lut/lut_test.go index 6a784e9f..3eb61401 100644 --- a/rlwe/lut/lut_test.go +++ b/rlwe/lut/lut_test.go @@ -31,6 +31,7 @@ func TestLUT(t *testing.T) { } } +// Function to evaluate func sign(x float64) float64 { if x > 0 { return 1 @@ -44,6 +45,7 @@ func sign(x float64) float64 { func testLUT(t *testing.T) { var err error + // RLWE parameters of the LUT // N=1024, Q=0x7fff801 -> 2^131 paramsLUT, err := rlwe.NewParametersFromLiteral(rlwe.ParametersLiteral{ LogN: 10, @@ -55,6 +57,7 @@ func testLUT(t *testing.T) { assert.Nil(t, err) + // RLWE parameters of the samples // N=512, Q=0x3001 -> 2^135 paramsLWE, err := rlwe.NewParametersFromLiteral(rlwe.ParametersLiteral{ LogN: 9, @@ -67,26 +70,37 @@ func testLUT(t *testing.T) { t.Run(testString(paramsLUT, "LUT/"), func(t *testing.T) { + // Scale of the RLWE samples scaleLWE := float64(paramsLWE.Q()[0]) / 4.0 + + // Scale of the test poly scaleLUT := float64(paramsLUT.Q()[0]) / 4.0 + // Number of values samples stored in the RLWE sample slots := 16 + // Test poly LUTPoly := InitLUT(sign, scaleLUT, paramsLUT.RingQ(), -1, 1) + // Index map of which test poly to evaluate on which slot lutPolyMap := make(map[int]*ring.Poly) for i := 0; i < slots; i++ { lutPolyMap[i] = LUTPoly } + // RLWE secret for the samples skLWE := rlwe.NewKeyGenerator(paramsLWE).GenSecretKey() + + // RLWE encryptor for the samples encryptorLWE := rlwe.NewEncryptor(paramsLWE, skLWE) + // Values to encrypt in the RLWE sample values := make([]float64, slots) for i := 0; i < slots; i++ { values[i] = -1 + float64(2*i)/float64(slots) } + // Encode multiples values in a single RLWE ptLWE := rlwe.NewPlaintext(paramsLWE, paramsLWE.MaxLevel()) for i := range values { if values[i] < 0 { @@ -95,16 +109,25 @@ func testLUT(t *testing.T) { ptLWE.Value.Coeffs[0][i] = uint64(values[i] * scaleLWE) } } + + // Encrypt the multiples values in a single RLWE ctLWE := rlwe.NewCiphertextNTT(paramsLWE, 1, paramsLWE.MaxLevel()) encryptorLWE.Encrypt(ptLWE, ctLWE) + // Evaluator for the LUT evaluation eval := NewEvaluator(paramsLUT, paramsLWE, nil) + // Secret of the RGSW ciphertexts encrypting the bits of skLWE skLUT := rlwe.NewKeyGenerator(paramsLUT).GenSecretKey() - LUTKEY := GenKey(paramsLUT, skLUT, paramsLWE, skLWE) + // Collection of RGSW ciphertexts encrypting the bits of skLWE under skLUT + LUTKEY := GenEvaluationKey(paramsLUT, skLUT, paramsLWE, skLWE) + + // Evaluation of LUT(ctLWE) + // Returns one RLWE sample per slot in ctLWE ctsLUT := eval.Evaluate(ctLWE, lutPolyMap, LUTKEY) + // Decrypts, decodes and compares q := paramsLUT.Q()[0] qHalf := q >> 1 decryptorLUT := rlwe.NewDecryptor(paramsLUT, skLUT) diff --git a/rlwe/params.go b/rlwe/params.go index b8613c79..1979dc9e 100644 --- a/rlwe/params.go +++ b/rlwe/params.go @@ -75,7 +75,7 @@ type Parameters struct { // specified parameters are invalid. func NewParameters(logn int, q, p []uint64, logBase2, h int, sigma float64, ringType ring.Type) (Parameters, error) { - if logBase2 != 0 && len(p) > 1{ + if logBase2 != 0 && len(p) > 1 { return Parameters{}, fmt.Errorf("rlwe.NewParameters: invalid parameters, cannot have logbase2 > 0 if len(P) > 1") } diff --git a/rlwe/rgsw/ciphertext.go b/rlwe/rgsw/ciphertext.go index 2b70aeba..43734162 100644 --- a/rlwe/rgsw/ciphertext.go +++ b/rlwe/rgsw/ciphertext.go @@ -24,11 +24,11 @@ func (ct *Ciphertext) LevelP() int { } // NewCiphertextNTT allocates a new RGSW ciphertext in the NTT domain. -func NewCiphertextNTT(levelQ, levelP, decompRNS, decompBit int, ringQP ringqp.Ring) (ct *Ciphertext) { +func NewCiphertext(levelQ, levelP, decompRNS, decompBit int, ringQP ringqp.Ring) (ct *Ciphertext) { return &Ciphertext{ Value: [2]gadget.Ciphertext{ - *gadget.NewCiphertextNTT(levelQ, levelP, decompRNS, decompBit, ringQP), - *gadget.NewCiphertextNTT(levelQ, levelP, decompRNS, decompBit, ringQP), + *gadget.NewCiphertext(levelQ, levelP, decompRNS, decompBit, ringQP), + *gadget.NewCiphertext(levelQ, levelP, decompRNS, decompBit, ringQP), }, } } diff --git a/rlwe/rlwe_benchmark_test.go b/rlwe/rlwe_benchmark_test.go index 18b55bcb..ad4306b4 100644 --- a/rlwe/rlwe_benchmark_test.go +++ b/rlwe/rlwe_benchmark_test.go @@ -13,7 +13,7 @@ func BenchmarkRLWE(b *testing.B) { } if *flagParamString != "" { var jsonParams ParametersLiteral - if err := json.Unmarshal([]byte(*flagParamString), &jsonParams); err != nil{ + if err := json.Unmarshal([]byte(*flagParamString), &jsonParams); err != nil { b.Fatal(err) } defaultParams = []ParametersLiteral{jsonParams} // the custom test suite reads the parameters from the -params flag diff --git a/rlwe/rlwe_test_params.go b/rlwe/rlwe_test_params.go index b56697b0..aec5bc41 100644 --- a/rlwe/rlwe_test_params.go +++ b/rlwe/rlwe_test_params.go @@ -26,9 +26,9 @@ var ( } // TestPN13QP218 is a set of default parameters with logN=13 and logQP=218 TestPN13QP218 = ParametersLiteral{ - LogN: 13, - Q: []uint64{0x3fffffffef8001, 0x4000000011c001, 0x40000000120001}, // 54 + 54 + 54 bits - P: []uint64{0x7ffffffffb4001}, // 55 bits + LogN: 13, + Q: []uint64{0x3fffffffef8001, 0x4000000011c001, 0x40000000120001}, // 54 + 54 + 54 bits + P: []uint64{0x7ffffffffb4001}, // 55 bits } // TestPN14QP438 is a set of default parameters with logN=14 and logQP=438 @@ -36,7 +36,7 @@ var ( LogN: 14, Q: []uint64{0x100000000060001, 0x80000000068001, 0x80000000080001, 0x3fffffffef8001, 0x40000000120001, 0x3fffffffeb8001}, // 56 + 55 + 55 + 54 + 54 + 54 bits - P: []uint64{0x80000000130001, 0x7fffffffe90001}, // 55 + 55 bits + P: []uint64{0x80000000130001, 0x7fffffffe90001}, // 55 + 55 bits } // TestPN15QP880 is a set of default parameters with logN=15 and logQP=880 @@ -46,19 +46,19 @@ var ( 0x400000000270001, 0x400000000350001, 0x400000000360001, // 58 + 58 + 58 bits 0x3ffffffffc10001, 0x3ffffffffbe0001, 0x3ffffffffbd0001, // 58 + 58 + 58 bits 0x4000000004d0001, 0x400000000570001, 0x400000000660001}, // 58 + 58 + 58 bits - P: []uint64{0xffffffffffc0001, 0x10000000001d0001, 0x10000000006e0001}, // 60 + 60 + 60 bits + P: []uint64{0xffffffffffc0001, 0x10000000001d0001, 0x10000000006e0001}, // 60 + 60 + 60 bits } // TestPN16QP240 is a set of default parameters with logN=16 and logQP=240 TestPN16QP240 = ParametersLiteral{ - LogN: 16, - LogQ: []int{60, 60, 60}, // 58 + 58 + 58 bits - LogP: []int{60}, // 60 + 60 + 60 bits + LogN: 16, + LogQ: []int{60, 60, 60}, // 58 + 58 + 58 bits + LogP: []int{60}, // 60 + 60 + 60 bits } // TestPN17QP360 is a set of default parameters with logN=17 and logQP=360 TestPN17QP360 = ParametersLiteral{ - LogN: 17, - LogQ: []int{60, 60, 60, 60}, - LogP: []int{60, 60}, + LogN: 17, + LogQ: []int{60, 60, 60, 60}, + LogP: []int{60, 60}, } )