예제 #1
0
        private static BigPolyArray[] ReceiveEncryptedArray(int length, TcpClient client, NetworkStream nwStream,
                                                            BinaryFormatter binForm)
        {
            int bytesRead = 0;

            byte[] buffer           = new byte[client.ReceiveBufferSize];
            var    encryptedDataBat = new BigPolyArray[length];

            for (int i = 0; i < encryptedDataBat.Length; i++)
            {
                buffer    = new byte[client.ReceiveBufferSize];
                bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

                var arr = new BigPolyArray();
                using (var ms = new MemoryStream())
                {
                    ms.Write(buffer, 0, bytesRead);
                    ms.Seek(0, SeekOrigin.Begin);
                    arr.Load(ms);
                    ms.Flush();
                }
                encryptedDataBat[i] = arr;
                binForm.Serialize(nwStream, "OK");
            }
            return(encryptedDataBat);
        }
예제 #2
0
        public BigPolyArray MultiplyPlain(BigPolyArray encrypted1, int unencrypted2)
        {
            //encrypted1 = Relinearize(encrypted1);
            var encoded2 = encoder.Encode(unencrypted2);

            return(evaluator.MultiplyPlain(encrypted1, encoded2));
        }
예제 #3
0
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();

            var binForm    = new BinaryFormatter();
            int iterations = 1;

            //---listen at the specified IP and port no.---
            IPAddress   localAdd = IPAddress.Parse(SERVER_IP);
            TcpListener listener = new TcpListener(localAdd, PORT_NO);

            Console.WriteLine("Listening...");
            listener.Start();

            //---incoming client connected---
            TcpClient client = listener.AcceptTcpClient();

            client.ReceiveBufferSize = 131116;

            EncCal encCal;

            //---get the incoming data through a network stream---
            using (NetworkStream nwStream = client.GetStream())
            {
                //1. Receive the length of the array of encrypted values
                int length = (int)binForm.Deserialize(nwStream);
                binForm.Serialize(nwStream, "OK");

                //2. Receive the public key
                BigPolyArray publicKey = ReceiveEncryptedArray(1, client, nwStream, binForm)[0];

                //3. Initiate the Encryption Scheme
                //The other parameters should also be sent from the client
                //This is just for testing
                encCal = new EncCal(publicKey, "1x^4096 + 1", 4096, 40961);

                //4. Receive Encrypted data
                stopwatch.Start();
                var encryptedDataBat = ReceiveEncryptedArray(length, client, nwStream, binForm);
                stopwatch.Stop();
                Console.WriteLine("First Communication: {0}", stopwatch.Elapsed);
                stopwatch.Reset();

                int picWidth  = length / 3;
                int picLength = length / 3;

                //5. Negation operation
                stopwatch.Reset();
                stopwatch.Start();
                BigPolyArray[] encryptedResult = DoSomeOperation(encryptedDataBat, picWidth, picLength, encCal);
                stopwatch.Stop();
                Console.WriteLine("Negation: {0}", stopwatch.Elapsed);

                //6. Send encrypted results back to client
                SendEncryptedArray(encryptedResult, nwStream, binForm);
            }
            client.Close();
            listener.Stop();
            Console.ReadLine();
        }
예제 #4
0
        public void SaveLoadBigPolyArrayNET()
        {
            var stream = new MemoryStream();

            var arr = new BigPolyArray(3, 5, 10);

            arr[0][0].Set(1);
            arr[0][1].Set(2);
            arr[0][2].Set(3);
            arr[1][0].Set(4);
            arr[1][1].Set(5);
            arr[2][0].Set(6);

            var arr2 = new BigPolyArray();

            stream.Seek(0, SeekOrigin.Begin);
            arr.Save(stream);
            stream.Seek(0, SeekOrigin.Begin);
            arr2.Load(stream);

            Assert.AreEqual(3, arr2.Size);
            Assert.AreEqual(arr2.Size, 3);
            Assert.AreEqual(arr2.CoeffCount, 5);
            Assert.AreEqual(arr2.CoeffBitCount, 10);

            Assert.IsTrue(arr[0].Equals(arr2[0]));
            Assert.IsTrue(arr[1].Equals(arr2[1]));
            Assert.IsTrue(arr[2].Equals(arr2[2]));
        }
예제 #5
0
        public static BigPolyArray[] GetEncryptedDataInBatches(EncCal encCal, Pgm picture, int size = 3)
        {
            var encryptedData = new BigPolyArray[picture.Length * size];

            Parallel.For(0, picture.Length, l =>
            {
                int slotCount = encCal.CrtBuilder.SlotCount;
                var values1   = new BigUInt[encCal.CrtBuilder.SlotCount];
                var values2   = new BigUInt[encCal.CrtBuilder.SlotCount];
                var values3   = new BigUInt[encCal.CrtBuilder.SlotCount];
                Parallel.For(0, slotCount, i =>
                {
                    values1[i] = new BigUInt(encCal.GetBitCount(), 0);
                    values2[i] = new BigUInt(encCal.GetBitCount(), 0);
                    values3[i] = new BigUInt(encCal.GetBitCount(), 0);
                });
                Parallel.For(0, picture.Width, i =>
                {
                    values1[i].Set(picture.Data[(l * picture.Length) + i]);
                    values2[i + 1].Set(picture.Data[(l * picture.Length) + i]);
                    values3[i + 2].Set(picture.Data[(l * picture.Length) + i]);
                });
                encryptedData[size * l]     = encCal.GetEnc(encCal.CrtBuilder.Compose(values1.ToList()));
                encryptedData[size * l + 1] = encCal.GetEnc(encCal.CrtBuilder.Compose(values2.ToList()));
                encryptedData[size * l + 2] = encCal.GetEnc(encCal.CrtBuilder.Compose(values3.ToList()));
            });
            return(encryptedData);
        }
 private void PrintBigPolyArray(StringBuilder stBlder, String message, BigPolyArray array)
 {
     stBlder.AppendLine(message);
     for (int i = 0; i < array.Size; i++)
     {
         stBlder.Append(array[i] + "-");
     }
 }
예제 #7
0
        public void TransformEncryptedToFromNTTNET()
        {
            var parms = new EncryptionParameters(MemoryPoolHandle.AcquireNew());

            parms.SetDecompositionBitCount(4);
            parms.SetNoiseStandardDeviation(3.19);
            parms.SetNoiseMaxDeviation(35.06);

            var coeffModulus = new BigUInt(48);

            coeffModulus.Set("FFFFFFFFC001");
            parms.SetCoeffModulus(coeffModulus);

            var plainModulus = new BigUInt(7);

            plainModulus.Set(1 << 6);
            parms.SetPlainModulus(plainModulus);

            var polyModulus = new BigPoly(65, 1);

            polyModulus[0].Set(1);
            polyModulus[64].Set(1);
            parms.SetPolyModulus(polyModulus);

            parms.Validate();

            var keygen = new KeyGenerator(parms, MemoryPoolHandle.AcquireNew());

            keygen.Generate();

            var encryptor = new Encryptor(parms, keygen.PublicKey, MemoryPoolHandle.AcquireNew());
            var evaluator = new Evaluator(parms, MemoryPoolHandle.AcquireNew());
            var decryptor = new Decryptor(parms, keygen.SecretKey, MemoryPoolHandle.AcquireNew());

            var plain  = new BigPoly(65, 1);
            var cipher = new BigPolyArray(2, 65, 1);

            plain.Set("0");
            encryptor.Encrypt(plain, cipher);
            evaluator.TransformToNTT(cipher);
            evaluator.TransformFromNTT(cipher);
            decryptor.Decrypt(cipher, plain);
            Assert.IsTrue(plain.ToString() == "0");

            plain.Set("1");
            encryptor.Encrypt(plain, cipher);
            evaluator.TransformToNTT(cipher);
            evaluator.TransformFromNTT(cipher);
            decryptor.Decrypt(cipher, plain);
            Assert.IsTrue(plain.ToString() == "1");

            plain.Set("Fx^10 + Ex^9 + Dx^8 + Cx^7 + Bx^6 + Ax^5 + 1x^4 + 2x^3 + 3x^2 + 4x^1 + 5");
            encryptor.Encrypt(plain, cipher);
            evaluator.TransformToNTT(cipher);
            evaluator.TransformFromNTT(cipher);
            decryptor.Decrypt(cipher, plain);
            Assert.IsTrue(plain.ToString() == "Fx^10 + Ex^9 + Dx^8 + Cx^7 + Bx^6 + Ax^5 + 1x^4 + 2x^3 + 3x^2 + 4x^1 + 5");
        }
예제 #8
0
 private static int WriteToStream(MemoryStream ms, BigPolyArray ip, NetworkStream nwStream)
 {
     ms.Seek(0, SeekOrigin.Begin);
     ip.Save(ms);
     byte[] bytesToSend = ms.ToArray();
     nwStream.Write(bytesToSend, 0, bytesToSend.Length);
     ms.Flush();
     return(bytesToSend.Length);
 }
예제 #9
0
 private static void WriteToStream(MemoryStream ms, BigPolyArray ip, NetworkStream nwStream)
 {
     ms.Seek(0, SeekOrigin.Begin);
     ip.Save(ms);
     byte[] bytesToSend = ms.ToArray();
     nwStream.Write(bytesToSend, 0, bytesToSend.Length);
     //ms.WriteTo(nwStream);
     //Console.WriteLine(bytesToSend.Length);
     ms.Flush();
 }
예제 #10
0
        public EncCal(BigPolyArray publicKey, string polyMod, int coeffDefault, ulong plainMod)
        {
            // Create encryption parameters.
            parms = new EncryptionParameters();
            parms.PolyModulus.Set(polyMod);
            parms.CoeffModulus.Set(ChooserEvaluator.DefaultParameterOptions[coeffDefault]);
            parms.PlainModulus.Set(plainMod);
            //parms.DecompositionBitCount = 12;
            // Create encoder (for encoding and decoding)
            encoder = new IntegerEncoder(parms.PlainModulus);
            //encoder = new FractionalEncoder(parms.PlainModulus, parms.PolyModulus, 64, 32, 3);

            //Create Encryptor // not mandatory
            encryptor = new Encryptor(parms, publicKey);

            //Create Evaluator for arithmatic operations
            evaluator = new Evaluator(parms);

            CrtBuilder = new PolyCRTBuilder(parms);
        }
예제 #11
0
        public void EvaluationKeysNETSaveLoad()
        {
            var stream = new MemoryStream();

            var arr1 = new BigPolyArray(3, 5, 10);

            arr1[0][0].Set(1);
            arr1[0][1].Set(2);
            arr1[0][2].Set(3);
            arr1[1][0].Set(4);
            arr1[1][1].Set(5);
            arr1[2][0].Set(6);

            var arr2 = new BigPolyArray(3, 5, 10);

            arr2[0][0].Set(7);
            arr2[0][1].Set(8);
            arr2[0][2].Set(9);
            arr2[1][0].Set(10);
            arr2[1][1].Set(11);
            arr2[2][0].Set(12);

            var pair1 = new Tuple <BigPolyArray, BigPolyArray>(arr1, arr2);
            var list1 = new List <System.Tuple <Microsoft.Research.SEAL.BigPolyArray, Microsoft.Research.SEAL.BigPolyArray> >();

            list1.Add(pair1);
            var keys1 = new EvaluationKeys(list1);

            stream.Seek(0, SeekOrigin.Begin);
            keys1.Save(stream);

            var keys2 = new EvaluationKeys();

            stream.Seek(0, SeekOrigin.Begin);
            keys2.Load(stream);

            Assert.AreEqual(keys1[0].Item1[0].ToString(), keys2[0].Item1[0].ToString());
        }
예제 #12
0
 public EncCal(string polyMod, int coeffDefault, ulong plainMod, int dbc, int noOfEvaluationKeys)
 {
     // Create encryption parameters.
     parms = new EncryptionParameters();
     parms.PolyModulus.Set(polyMod);
     parms.CoeffModulus.Set(ChooserEvaluator.DefaultParameterOptions[coeffDefault]);
     parms.PlainModulus.Set(plainMod);
     // Generate keys.
     generator = new KeyGenerator(parms);
     generator.Generate(noOfEvaluationKeys);     //Integer
     // Generator contains the keys
     publicKey      = generator.PublicKey;
     secretKey      = generator.SecretKey;
     evaluationKeys = generator.EvaluationKeys;
     // Create encoder (for encoding and decoding)
     encoder = new IntegerEncoder(parms.PlainModulus);        //Integer
     //Create Encryptor
     encryptor = new Encryptor(parms, publicKey);
     //Create Decryptor
     decryptor = new Decryptor(parms, secretKey);
     //Create Evaluator for arithmatic operations
     evaluator  = new Evaluator(parms);
     CrtBuilder = new PolyCRTBuilder(parms);
 }
예제 #13
0
 public BigPolyArray Add(BigPolyArray encrypted1, BigPolyArray encrypted2)
 {
     return(evaluator.Add(encrypted1, encrypted2));
 }
예제 #14
0
 internal BigPolyArray MultiplyPlain(BigPolyArray encrypted, BigPoly encoded)
 {
     return(evaluator.MultiplyPlain(encrypted, encoded));
 }
예제 #15
0
        internal BigPoly GetDecrypted(BigPolyArray enc)
        {
            var decrypted = decryptor.Decrypt(enc);

            return(decrypted);
        }
예제 #16
0
 public BigPolyArray Negate(BigPolyArray encrypted1)
 {
     return(evaluator.Negate(encrypted1));
 }
예제 #17
0
 public BigPolyArray Square(BigPolyArray n)
 {
     return(evaluator.Square(n));
 }
예제 #18
0
 public BigPolyArray Multiply(BigPolyArray encrypted1, BigPolyArray encrypted2)
 {
     return(evaluator.Multiply(encrypted1, encrypted2));
 }
예제 #19
0
 public BigPolyArray Sub(BigPolyArray encrypted1, BigPolyArray encrypted2)
 {
     return(evaluator.Sub(encrypted1, encrypted2));
 }
예제 #20
0
        public static void ExampleRelinearization()
        {
            PrintExampleBanner("Example: Relinearization");

            /*
             * A valid ciphertext consists of at least two polynomials. To read the current size of a ciphertext the
             * user can use BigPolyArray.Size. A fresh ciphertext always has size 2, and performing homomorphic multiplication
             * results in the output ciphertext growing in size. More precisely, if the input ciphertexts have size M and N,
             * then the output ciphertext after homomorphic multiplication will have size M+N-1.
             *
             * The multiplication operation on input ciphertexts of size M and N will require M*N polynomial multiplications
             * to be performed. Therefore, if the ciphertexts grow to be large, multiplication could potentially become
             * computationally very costly and in some situations the user might prefer to reduce the size of the ciphertexts
             * by performing a so-called relinearization operation.
             *
             * The function Evaluator.Relinearize(...) can reduce the size of an input ciphertext of size M to any size in
             * 2, 3, ..., M. Relinearizing one or both of two ciphertexts before performing multiplication on them may significantly
             * reduce the computational cost of the multiplication. However, note that the relinearization process also requires
             * several polynomial multiplications to be performed. In particular relinearizing a ciphertext of size K to size L
             * will itself require 2*(K-L)*[floor(log_2(CoeffModulus)/dbc)+1] polynomial multiplications, where dbc is the
             * DecompositionBitCount (see below). It is also important to understand that relinearization grows the inherent noise
             * in a ciphertext by an additive factor proportional to 2^dbc, which can in some cases be very large. When using
             * relinearization it is necessary that the DecompositionBitCount is specified in the encryption parameters,
             * and that enough evaluation keys are given to the constructor of Evaluator.
             *
             * The DecompositionBitCount affects both performance and noise growth in relinearization, as was explained above.
             * Simply put, the larger dbc is, the faster relinearization is, and the larger the additive noise growth factor is
             * (see above). However, if some multiplications have already been performed on a ciphertext so that the noise has
             * grown to some reasonable level, relinearization might have no practical effect anymore on noise due to the additive
             * factor being possibly (much) smaller than what the current noise is. This is why it makes almost never sense to
             * relinearize after the first multiplication since the noise will still be so small that any reasonably large dbc
             * would increase the noise by a significant amount. In many cases it might not be beneficial to relinearize at all,
             * especially if the computation to be performed amounts to evaluating some fairly low degree polynomial. If the
             * degree is higher, then in some cases it might be beneficial to relinearize at some stage in the computation.
             * See below for how to choose a good value for the DecompositionBitCount.
             *
             * If the intention of the evaluating party is to hide the structure of the computation that has been performed on
             * the ciphertexts, it might be necessary to relinearize to hide the number of multiplications that the ciphertexts
             * have gone through. In addition, after relinearizing (to size 2) it might be a good idea to re-randomize the
             * ciphertext by adding to it a fresh encryption of 0.
             *
             * In this example we will demonstrate using Evaluator.Relinearize(...) and illustrate how it reduces the ciphertext
             * sizes. We will also observe the effects it has on noise.
             */

            // Set up encryption parameters
            var parms = new EncryptionParameters();

            parms.PolyModulus.Set("1x^2048 + 1");
            parms.CoeffModulus.Set(ChooserEvaluator.DefaultParameterOptions[2048]);
            parms.PlainModulus.Set(1 << 16);

            /*
             * The choice of DecompositionBitCount (dbc) can affect the performance of relinearization noticeably. A somewhat
             * optimal choice is to choose it between 1/5 and 1/2 of the significant bit count of the coefficient modulus (see
             * table below). It turns out that if dbc cannot (due to noise growth) be more than one fifth of the significant
             * bit count of the coefficient modulus, then it is in fact better to just move up to a larger PolyModulus and
             * CoeffModulus, and set dbc to be as large as possible.
             * /--------------------------------------------------------\
             | poly_modulus | coeff_modulus bound | dbc min | dbc max |
             | -------------|---------------------|------------------ |
             | 1x^1024 + 1  | 48 bits             | 10      | 24      |
             | 1x^2048 + 1  | 96 bits             | 20      | 48      |
             | 1x^4096 + 1  | 192 bits            | 39      | 96      |
             | 1x^8192 + 1  | 384 bits            | 77      | 192     |
             | 1x^16384 + 1 | 768 bits            | 154     | 384     |
             \--------------------------------------------------------/
             |
             | A smaller DecompositionBitCount will make relinearization slower. A higher DecompositionBitCount will increase
             | noise growth while not making relinearization any faster. Here, the CoeffModulus has 96 significant bits, so
             | we choose DecompositionBitCount to be half of this.
             */
            parms.DecompositionBitCount = 48;

            Console.WriteLine("Encryption parameters specify {0} coefficients with {1} bits per coefficient",
                              parms.PolyModulus.GetSignificantCoeffCount(), parms.CoeffModulus.GetSignificantBitCount());

            /*
             * Generate keys
             *
             * By default, KeyGenerator.Generate() will generate no evaluation keys. This means that we cannot perform any
             * relinearization. However, this is sufficient for performing all other homomorphic evaluation operations as
             * they do not use evaluation keys.
             */
            Console.WriteLine("Generating keys...");
            var generator = new KeyGenerator(parms);

            generator.Generate();
            Console.WriteLine("... key generation complete");
            BigPolyArray publicKey = generator.PublicKey;
            BigPoly      secretKey = generator.SecretKey;

            /*
             * Suppose we want to homomorphically multiply four ciphertexts together. Does it make sense to relinearize
             * at an intermediate step of the computation? We demonstrate how relinearization at different stages affects
             * the results.
             */

            // Encrypt the plaintexts to generate the four fresh ciphertexts
            var plain1 = new BigPoly("4");
            var plain2 = new BigPoly("3x^1");
            var plain3 = new BigPoly("2x^2");
            var plain4 = new BigPoly("1x^3");

            Console.WriteLine("Encrypting values as { encrypted1, encrypted2, encrypted3, encrypted4 }");
            var encryptor  = new Encryptor(parms, publicKey);
            var encrypted1 = encryptor.Encrypt(plain1);
            var encrypted2 = encryptor.Encrypt(plain2);
            var encrypted3 = encryptor.Encrypt(plain3);
            var encrypted4 = encryptor.Encrypt(plain4);

            // What are the noises in the four ciphertexts?
            var maxNoiseBitCount = Utilities.InherentNoiseMax(parms).GetSignificantBitCount();

            Console.WriteLine("Noises in the four ciphertexts: {0}/{1} bits, {2}/{3} bits, {4}/{5} bits, {6}/{7} bits",
                              Utilities.InherentNoise(encrypted1, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount,
                              Utilities.InherentNoise(encrypted2, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount,
                              Utilities.InherentNoise(encrypted3, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount,
                              Utilities.InherentNoise(encrypted4, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);

            // Construct an Evaluator
            var evaluator = new Evaluator(parms);

            // Perform first part of computation
            Console.WriteLine("Computing encProd1 as encrypted1*encrypted2");
            var encProd1 = evaluator.Multiply(encrypted1, encrypted2);

            Console.WriteLine("Computing encProd2 as encrypted3*encrypted4");
            var encProd2 = evaluator.Multiply(encrypted3, encrypted4);

            // Now encProd1 and encProd2 both have size 3
            Console.WriteLine($"Sizes of enc_prod1 and enc_prod2: {encProd1.Size}, {encProd2.Size}");

            // What are the noises in the products?
            Console.WriteLine("Noises in encProd1 and encProd2: {0}/{1} bits, {2}/{3} bits",
                              Utilities.InherentNoise(encProd1, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount,
                              Utilities.InherentNoise(encProd2, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);

            // Compute product of all four
            Console.WriteLine("Computing encResult as encProd1*encProd2");
            var encResult = evaluator.Multiply(encProd1, encProd2);

            // Now enc_result has size 5
            Console.WriteLine($"Size of enc_result: {encResult.Size}");

            // What is the noise in the result?
            Console.WriteLine("Noise in enc_result: {0}/{1} bits",
                              Utilities.InherentNoise(encResult, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);

            /*
             * We didn't create any evaluation keys, so we can't relinearize at all with the current Evaluator.
             * The size of our final ciphertext enc_result is 5, so for example to relinearize this down to size 2
             * we will need 3 evaluation keys. In general, relinearizing down from size K to any smaller size (but at least 2)
             * requires at least K-2 evaluation keys, so in this case we will need at least 2 evaluation keys.
             *
             * We can create these new evaluation keys by calling KeyGenerator.GenerateEvaluationKeys(...). Alternatively,
             * we could have created them already in the beginning by instead of calling generator.Generate(2) instead of
             * generator.Generate().
             *
             * We will also need a new Evaluator, as the previous one was constructed without enough (indeed, any)
             * evaluation keys. It is not possible to add new evaluation keys to a previously created Evaluator.
             */
            generator.GenerateEvaluationKeys(3);
            var evaluationKeys = generator.EvaluationKeys;
            var evaluator2     = new Evaluator(parms, evaluationKeys);

            /*
             * We can relinearize encResult back to size 2 if we want to. In fact, we could also relinearize it to size 3 or 4,
             * or more generally to any size less than the current size but at least 2. The way to do this would be to call
             * Evaluator.Relinearize(encResult, destinationSize).
             */
            Console.WriteLine("Relinearizing encResult to size 2 (stored in encRelinResult)");
            var encRelinResult = evaluator2.Relinearize(encResult);

            /*
             * What did that do to size and noise?
             * In fact noise remained essentially the same, because at this point the size of noise is already significantly
             * larger than the additive term contributed by the relinearization process. We still remain below the noise bound.
             */
            Console.WriteLine($"Size of enc_relin_result: {encRelinResult.Size}");
            Console.WriteLine("Noise in enc_relin_result: {0}/{1} bits",
                              Utilities.InherentNoise(encRelinResult, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);

            // What if we do intermediate relinearization of encProd1 and encProd2?
            Console.WriteLine("Relinearizing encProd1 and encProd2 to size 2");
            var encRelinProd1 = evaluator2.Relinearize(encProd1);
            var encRelinProd2 = evaluator2.Relinearize(encProd2);

            // What happened to sizes and noises? Noises grew by a significant amount!
            Console.WriteLine($"Sizes of encRelinProd1 and encRelinProd2: {encRelinProd1.Size}, {encRelinProd2.Size}");
            Console.WriteLine("Noises in encRelinProd1 and encRelinProd2: {0}/{1} bits, {2}/{3} bits",
                              Utilities.InherentNoise(encRelinProd1, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount,
                              Utilities.InherentNoise(encRelinProd2, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);

            // Now multiply the relinearized products together
            Console.WriteLine("Computing encIntermediateRelinResult as encRelinProd1*encRelinProd2");
            var encIntermediateRelinResult = evaluator2.Multiply(encRelinProd1, encRelinProd2);

            /*
             * What did that do to size and noise?
             * We are above the noise bound in this case. The resulting ciphertext is corrupted. It is instructive to
             * try and see how a smaller DecompositionBitCount affects the results, e.g. try setting it to 24.
             * Also here PlainModulus was set to be quite large to emphasize the effect.
             */
            Console.WriteLine($"Size of encIntermediateRelinResult: {encIntermediateRelinResult.Size}");
            Console.WriteLine("Noise in encIntermediateRelinResult: {0}/{1} bits",
                              Utilities.InherentNoise(encIntermediateRelinResult, parms, secretKey).GetSignificantBitCount(), maxNoiseBitCount);
        }
예제 #21
0
        public void BigPolyArrayTestNET()
        {
            var arr = new BigPolyArray();

            Assert.AreEqual(arr.Size, 0);
            Assert.AreEqual(arr.CoeffCount, 0);
            Assert.AreEqual(arr.CoeffBitCount, 0);
            Assert.AreEqual(arr.CoeffUInt64Count(), 0);

            arr.Reset();
            Assert.AreEqual(arr.Size, 0);
            Assert.AreEqual(arr.CoeffCount, 0);
            Assert.AreEqual(arr.CoeffBitCount, 0);
            Assert.AreEqual(arr.CoeffUInt64Count(), 0);

            arr.Resize(2, 5, 10);
            Assert.AreEqual(arr.Size, 2);
            Assert.AreEqual(arr.CoeffCount, 5);
            Assert.AreEqual(arr.CoeffBitCount, 10);
            Assert.AreEqual(arr.CoeffUInt64Count(), 1);

            arr.Resize(3, 13, 70);
            Assert.AreEqual(arr.Size, 3);
            Assert.AreEqual(arr.CoeffCount, 13);
            Assert.AreEqual(arr.CoeffBitCount, 70);
            Assert.AreEqual(arr.CoeffUInt64Count(), 2);

            arr[0][0].Set(1);
            arr[0][1].Set(2);
            arr[0][2].Set(3);
            arr[0][3].Set(4);
            arr[0][4].Set(5);
            arr[1][0].Set(6);
            arr[1][1].Set(7);
            arr[1][2].Set(8);
            arr[2][0].Set(9);
            arr[2][1].Set(10);

            Assert.IsTrue("5x^4 + 4x^3 + 3x^2 + 2x^1 + 1" == arr[0].ToString());
            Assert.IsTrue("8x^2 + 7x^1 + 6" == arr[1].ToString());
            Assert.IsTrue("Ax^1 + 9" == arr[2].ToString());

            var arr2 = new BigPolyArray();

            Assert.AreEqual(arr2.Size, 0);
            Assert.AreEqual(arr2.CoeffCount, 0);
            Assert.AreEqual(arr2.CoeffBitCount, 0);
            Assert.AreEqual(arr2.CoeffUInt64Count(), 0);

            arr2.Set(arr);
            Assert.AreEqual(arr.Size, 3);
            Assert.AreEqual(arr.CoeffCount, 13);
            Assert.AreEqual(arr.CoeffBitCount, 70);

            Assert.IsTrue("5x^4 + 4x^3 + 3x^2 + 2x^1 + 1" == arr2[0].ToString());
            Assert.IsTrue("8x^2 + 7x^1 + 6" == arr2[1].ToString());
            Assert.IsTrue("Ax^1 + 9" == arr2[2].ToString());

            arr2[1].SetZero();
            Assert.IsTrue("5x^4 + 4x^3 + 3x^2 + 2x^1 + 1" == arr2[0].ToString());
            Assert.IsTrue("Ax^1 + 9" == arr2[2].ToString());

            arr.Resize(2, 3, 10);
            Assert.AreEqual(arr.Size, 2);
            Assert.AreEqual(arr.CoeffCount, 3);
            Assert.AreEqual(arr.CoeffBitCount, 10);

            Assert.IsTrue("3x^2 + 2x^1 + 1" == arr[0].ToString());
            Assert.IsTrue("8x^2 + 7x^1 + 6" == arr[1].ToString());

            arr.Resize(1, 1, 10);
            Assert.AreEqual(arr.Size, 1);
            Assert.AreEqual(arr.CoeffCount, 1);
            Assert.AreEqual(arr.CoeffBitCount, 10);

            Assert.IsTrue("1" == arr[0].ToString());

            arr.Reset();
            Assert.AreEqual(arr.Size, 0);
            Assert.AreEqual(arr.CoeffCount, 0);
            Assert.AreEqual(arr.CoeffBitCount, 0);
        }
예제 #22
0
 public BigPolyArray MultiplyPlain(BigPolyArray encrypted1, BigPoly encoded2)
 {
     //encrypted1 = Relinearize(encrypted1);
     return(evaluator.MultiplyPlain(encrypted1, encoded2));
 }