diff --git a/bfv/bfv_test.go b/bfv/bfv_test.go index ffeeaac7..41764952 100644 --- a/bfv/bfv_test.go +++ b/bfv/bfv_test.go @@ -14,6 +14,7 @@ import ( "github.com/tuneinsight/lattigo/v4/ring" "github.com/tuneinsight/lattigo/v4/rlwe" "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) var flagLongTest = flag.Bool("long", false, "run the long test suite (all parameters). Overrides -short and requires -timeout=0.") @@ -28,7 +29,7 @@ type testContext struct { params Parameters ringQ *ring.Ring ringT *ring.Ring - prng utils.PRNG + prng sampling.PRNG uSampler *ring.UniformSampler encoder Encoder kgen *rlwe.KeyGenerator @@ -117,7 +118,7 @@ func genTestParams(params Parameters) (tc *testContext, err error) { tc = new(testContext) tc.params = params - if tc.prng, err = utils.NewPRNG(); err != nil { + if tc.prng, err = sampling.NewPRNG(); err != nil { return nil, err } diff --git a/bfv/evaluator.go b/bfv/evaluator.go index 69acb4bc..e72496e6 100644 --- a/bfv/evaluator.go +++ b/bfv/evaluator.go @@ -402,13 +402,17 @@ func (eval *evaluator) quantizeLvl(level, levelQMul int, ctOut *rlwe.Ciphertext) // Mul multiplies ctIn by op1 and returns the result in ctOut. func (eval *evaluator) Mul(ctIn *rlwe.Ciphertext, op1 rlwe.Operand, ctOut *rlwe.Ciphertext) { - eval.CheckBinary(ctIn, op1, ctOut, ctIn.Degree()+op1.Degree()) + switch op1 := op1.(type) { case *PlaintextMul: + eval.CheckBinary(ctIn, op1, ctOut, ctIn.Degree()+op1.Degree()) eval.mulPlaintextMul(ctIn, op1, ctOut) case *PlaintextRingT: + // Special case where we do not want ctOut to be resized to level 0 + eval.CheckBinary(ctIn, ctIn, ctOut, ctIn.Degree()+op1.Degree()) eval.mulPlaintextRingT(ctIn, op1, ctOut) case *rlwe.Plaintext, *rlwe.Ciphertext: + eval.CheckBinary(ctIn, op1, ctOut, ctIn.Degree()+op1.Degree()) eval.tensorAndRescale(ctIn, op1.El(), ctOut) default: panic(fmt.Errorf("cannot Mul: invalid rlwe.Operand type for Mul: %T", op1)) @@ -461,7 +465,7 @@ func (eval *evaluator) mulPlaintextRingT(ctIn *rlwe.Ciphertext, ptRt *PlaintextR ringQ.MForm(ctOut.Value[i], ctOut.Value[i]) // For each qi in Q - for j, s := range ringQ.SubRings[:ctIn.Level()+1] { + for j, s := range ringQ.SubRings[:level+1] { tmp := ctOut.Value[i].Coeffs[j] diff --git a/bgv/bgv_test.go b/bgv/bgv_test.go index 6b686a1d..5472bb8a 100644 --- a/bgv/bgv_test.go +++ b/bgv/bgv_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) var flagPrintNoise = flag.Bool("print-noise", false, "print the residual noise") @@ -80,7 +81,7 @@ type testContext struct { params Parameters ringQ *ring.Ring ringT *ring.Ring - prng utils.PRNG + prng sampling.PRNG uSampler *ring.UniformSampler encoder Encoder kgen *rlwe.KeyGenerator @@ -98,7 +99,7 @@ func genTestParams(params Parameters) (tc *testContext, err error) { tc = new(testContext) tc.params = params - if tc.prng, err = utils.NewPRNG(); err != nil { + if tc.prng, err = sampling.NewPRNG(); err != nil { return nil, err } diff --git a/ckks/advanced/homomorphic_DFT_test.go b/ckks/advanced/homomorphic_DFT_test.go index dbc01d1f..97c302bc 100644 --- a/ckks/advanced/homomorphic_DFT_test.go +++ b/ckks/advanced/homomorphic_DFT_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tuneinsight/lattigo/v4/ckks" "github.com/tuneinsight/lattigo/v4/rlwe" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) var printPrecisionStats = flag.Bool("print-precision", false, "print precision stats") @@ -178,7 +178,7 @@ func testCoeffsToSlots(params ckks.Parameters, t *testing.T) { // Generates the vector of random complex values values := make([]complex128, params.Slots()) for i := range values { - values[i] = complex(utils.RandFloat64(-1, 1), utils.RandFloat64(-1, 1)) + values[i] = complex(sampling.RandFloat64(-1, 1), sampling.RandFloat64(-1, 1)) } // Splits between real and imaginary @@ -345,13 +345,13 @@ func testSlotsToCoeffs(params ckks.Parameters, t *testing.T) { // Generates the n first slots of the test vector (real part to encode) valuesReal := make([]complex128, params.Slots()) for i := range valuesReal { - valuesReal[i] = complex(utils.RandFloat64(-1, 1), 0) + valuesReal[i] = complex(sampling.RandFloat64(-1, 1), 0) } // Generates the n first slots of the test vector (imaginary part to encode) valuesImag := make([]complex128, params.Slots()) for i := range valuesImag { - valuesImag[i] = complex(utils.RandFloat64(-1, 1), 0) + valuesImag[i] = complex(sampling.RandFloat64(-1, 1), 0) } // If sparse, there there is the space to store both vectors in one diff --git a/ckks/advanced/homomorphic_mod_test.go b/ckks/advanced/homomorphic_mod_test.go index 0b602ebe..444b5ac8 100644 --- a/ckks/advanced/homomorphic_mod_test.go +++ b/ckks/advanced/homomorphic_mod_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/tuneinsight/lattigo/v4/ckks" "github.com/tuneinsight/lattigo/v4/rlwe" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) func TestHomomorphicMod(t *testing.T) { @@ -202,7 +202,7 @@ func newTestVectorsEvalMod(params ckks.Parameters, encryptor rlwe.Encryptor, enc Q := float64(params.Q()[0]) / math.Exp2(math.Round(math.Log2(float64(params.Q()[0])))) * evm.MessageRatio() for i := uint64(0); i < 1< RKG Phase") @@ -337,7 +337,7 @@ func rkgphase(params bfv.Parameters, crs utils.PRNG, P []*party) *rlwe.Relineari return rlk } -func gkgphase(params bfv.Parameters, crs utils.PRNG, P []*party) (galKeys []*rlwe.GaloisKey) { +func gkgphase(params bfv.Parameters, crs sampling.PRNG, P []*party) (galKeys []*rlwe.GaloisKey) { l := log.New(os.Stderr, "", 0) diff --git a/examples/dbfv/psi/main.go b/examples/dbfv/psi/main.go index 615ee6a3..10767f3d 100644 --- a/examples/dbfv/psi/main.go +++ b/examples/dbfv/psi/main.go @@ -11,7 +11,7 @@ import ( "github.com/tuneinsight/lattigo/v4/dbfv" "github.com/tuneinsight/lattigo/v4/drlwe" "github.com/tuneinsight/lattigo/v4/rlwe" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) func check(err error) { @@ -95,7 +95,7 @@ func main() { panic(err) } - crs, err := utils.NewKeyedPRNG([]byte{'l', 'a', 't', 't', 'i', 'g', 'o'}) + crs, err := sampling.NewKeyedPRNG([]byte{'l', 'a', 't', 't', 'i', 'g', 'o'}) if err != nil { panic(err) } @@ -281,7 +281,7 @@ func genInputs(params bfv.Parameters, P []*party) (expRes []uint64) { pi.input = make([]uint64, params.N()) for i := range pi.input { - if utils.RandFloat64(0, 1) > 0.3 || i == 4 { + if sampling.RandFloat64(0, 1) > 0.3 || i == 4 { pi.input[i] = 1 } expRes[i] *= pi.input[i] @@ -326,7 +326,7 @@ func pcksPhase(params bfv.Parameters, tpk *rlwe.PublicKey, encRes *rlwe.Cipherte return } -func rkgphase(params bfv.Parameters, crs utils.PRNG, P []*party) *rlwe.RelinearizationKey { +func rkgphase(params bfv.Parameters, crs sampling.PRNG, P []*party) *rlwe.RelinearizationKey { l := log.New(os.Stderr, "", 0) l.Println("> RKG Phase") @@ -371,7 +371,7 @@ func rkgphase(params bfv.Parameters, crs utils.PRNG, P []*party) *rlwe.Relineari return rlk } -func ckgphase(params bfv.Parameters, crs utils.PRNG, P []*party) *rlwe.PublicKey { +func ckgphase(params bfv.Parameters, crs sampling.PRNG, P []*party) *rlwe.PublicKey { l := log.New(os.Stderr, "", 0) diff --git a/examples/drlwe/thresh_eval_key_gen/main.go b/examples/drlwe/thresh_eval_key_gen/main.go index 5d70b005..4199d4b2 100644 --- a/examples/drlwe/thresh_eval_key_gen/main.go +++ b/examples/drlwe/thresh_eval_key_gen/main.go @@ -10,7 +10,7 @@ import ( "github.com/tuneinsight/lattigo/v4/drlwe" "github.com/tuneinsight/lattigo/v4/rlwe" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) // This example showcases the use of the drlwe package to generate an evaluation key in a multiparty setting. @@ -87,7 +87,7 @@ func (p *party) Run(wg *sync.WaitGroup, params rlwe.Parameters, N int, P []*part p.GenShare(sk, galEl, crp[galEl], rtgShare) C.aggTaskQueue <- genTaskResult{galEl: galEl, rtgShare: rtgShare} nShares++ - byteSent += len(rtgShare.Value) * len(rtgShare.Value[0]) * rtgShare.Value[0][0].MarshalBinarySize64() + byteSent += len(rtgShare.Value) * len(rtgShare.Value[0]) * rtgShare.Value[0][0].MarshalBinarySize() } nTasks++ cpuTime += time.Since(start) @@ -132,7 +132,7 @@ func (c *cloud) Run(galEls []uint64, params rlwe.Parameters, t int) { } i++ cpuTime += time.Since(start) - byteRecv += len(acc.share.Value) * len(acc.share.Value[0]) * acc.share.Value[0][0].MarshalBinarySize64() + byteRecv += len(acc.share.Value) * len(acc.share.Value[0]) * acc.share.Value[0][0].MarshalBinarySize() } close(c.finDone) fmt.Printf("\tCloud finished aggregating %d shares in %s, received %s\n", i, cpuTime, formatByteSize(byteRecv)) @@ -199,7 +199,7 @@ func main() { kg := rlwe.NewKeyGenerator(params) - crs, err := utils.NewPRNG() + crs, err := sampling.NewPRNG() if err != nil { panic(err) } diff --git a/examples/main_test.go b/examples/main_test.go index 3c5c1636..0acb67d1 100644 --- a/examples/main_test.go +++ b/examples/main_test.go @@ -5,7 +5,8 @@ import ( "testing" "github.com/tuneinsight/lattigo/v4/ring" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/buffer" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) func Benchmark(b *testing.B) { @@ -21,7 +22,7 @@ func Benchmark(b *testing.B) { b.Fatal(err) } - prng, err := utils.NewPRNG() + prng, err := sampling.NewPRNG() if err != nil { b.Fatal(err) } @@ -40,9 +41,9 @@ func Benchmark(b *testing.B) { } }) - b.Run("WriteTo(utils.Writer)", func(b *testing.B) { + b.Run("WriteTo(buffer.Writer)", func(b *testing.B) { writer := NewWriter(pol.MarshalBinarySize()) - w := utils.NewWriter(writer) + w := buffer.NewWriter(writer) b.ResetTimer() for i := 0; i < b.N; i++ { if _, err = pol.WriteTo(w); err != nil { @@ -77,7 +78,7 @@ func Benchmark(b *testing.B) { writer := NewWriter(pol.MarshalBinarySize()) - w := utils.NewWriter(writer) + w := buffer.NewWriter(writer) if _, err = pol.WriteTo(w); err != nil { b.Fatal(err) @@ -89,7 +90,7 @@ func Benchmark(b *testing.B) { reader := NewReader(writer.buff) - r := utils.NewReader(reader) + r := buffer.NewReader(reader) b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/examples/ring/vOLE/main.go b/examples/ring/vOLE/main.go index f1464d12..f5432d4f 100644 --- a/examples/ring/vOLE/main.go +++ b/examples/ring/vOLE/main.go @@ -7,7 +7,7 @@ import ( "time" "github.com/tuneinsight/lattigo/v4/ring" - "github.com/tuneinsight/lattigo/v4/utils" + "github.com/tuneinsight/lattigo/v4/utils/sampling" ) // Vectorized oblivious evaluation is a two-party protocol for the function f(x) = ax + b where a sender @@ -159,7 +159,7 @@ func main() { fmt.Printf("Params : n=%d logN=%d qlevel=%d plevel=%d mlevel=%d\n", n, param.logN, qlevel, plevel, mlevel) - prng, err := utils.NewPRNG() + prng, err := sampling.NewPRNG() if err != nil { panic(err) } diff --git a/utils/factorization/factorization.go b/utils/factorization/factorization.go index 14631900..c5d4e769 100644 --- a/utils/factorization/factorization.go +++ b/utils/factorization/factorization.go @@ -1,3 +1,4 @@ +// Package factorization implements various algorithms for efficient factoring integers of small to medium size. package factorization import ( diff --git a/utils/sampling/sampling.go b/utils/sampling/sampling.go index 028ed8c3..b8e0fb5c 100644 --- a/utils/sampling/sampling.go +++ b/utils/sampling/sampling.go @@ -1,3 +1,4 @@ +// Package sampling implements secure sanmpling bytes and integers. package sampling import ( diff --git a/utils/utils.go b/utils/utils.go index ca93d493..4ad1cca7 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,3 +1,4 @@ +// Package utils implements various helper functions. package utils import (