Example #1
0
        public void EncodeLongTest()
        {
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            parms.PolyModulusDegree = 64;
            parms.CoeffModulus      = CoeffModulus.Create(64, new int[] { 60 });
            parms.PlainModulus      = new SmallModulus(257);

            SEALContext context = new SEALContext(parms,
                                                  expandModChain: false,
                                                  secLevel: SecLevelType.None);

            BatchEncoder encoder = new BatchEncoder(context);

            Assert.AreEqual(64ul, encoder.SlotCount);

            List <long> plainList = new List <long>();

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                plainList.Add((long)i);
            }

            Plaintext plain = new Plaintext();

            encoder.Encode(plainList, plain);

            List <long> plainList2 = new List <long>();

            encoder.Decode(plain, plainList2);

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(plainList[checked ((int)i)], plainList2[checked ((int)i)]);
            }

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                plainList[checked ((int)i)] = 5;
            }

            encoder.Encode(plainList, plain);
            Assert.AreEqual("5", plain.ToString());

            encoder.Decode(plain, plainList2);

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(plainList[checked ((int)i)], plainList2[checked ((int)i)]);
            }

            List <long> shortList = new List <long>();

            for (int i = 0; i < 20; i++)
            {
                shortList.Add((long)i);
            }

            encoder.Encode(shortList, plain);

            List <long> shortList2 = new List <long>();

            encoder.Decode(plain, shortList2);

            Assert.AreEqual(20, shortList.Count);
            Assert.AreEqual(64, shortList2.Count);

            for (int i = 0; i < 20; i++)
            {
                Assert.AreEqual(shortList[i], shortList2[i]);
            }

            for (ulong i = 20; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(0L, shortList2[checked ((int)i)]);
            }
        }
Example #2
0
        /*
         * Both the BFV scheme (with BatchEncoder) as well as the CKKS scheme support native
         * vectorized computations on encrypted numbers. In addition to computing slot-wise,
         * it is possible to rotate the encrypted vectors cyclically.
         */
        private static void ExampleRotationBFV()
        {
            Utilities.PrintExampleBanner("Example: Rotation / Rotation in BFV");

            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            ulong polyModulusDegree = 8192;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = PlainModulus.Batching(polyModulusDegree, 20);

            using SEALContext context = new SEALContext(parms);
            Utilities.PrintParameters(context);
            Console.WriteLine();

            using KeyGenerator keygen = new KeyGenerator(context);
            using SecretKey secretKey = keygen.SecretKey;
            keygen.CreatePublicKey(out PublicKey publicKey);
            keygen.CreateRelinKeys(out RelinKeys relinKeys);
            using Encryptor encryptor = new Encryptor(context, publicKey);
            using Evaluator evaluator = new Evaluator(context);
            using Decryptor decryptor = new Decryptor(context, secretKey);

            using BatchEncoder batchEncoder = new BatchEncoder(context);
            ulong slotCount = batchEncoder.SlotCount;
            ulong rowSize   = slotCount / 2;

            Console.WriteLine($"Plaintext matrix row size: {rowSize}");

            ulong[] podMatrix = new ulong[slotCount];
            podMatrix[0]           = 0;
            podMatrix[1]           = 1;
            podMatrix[2]           = 2;
            podMatrix[3]           = 3;
            podMatrix[rowSize]     = 4;
            podMatrix[rowSize + 1] = 5;
            podMatrix[rowSize + 2] = 6;
            podMatrix[rowSize + 3] = 7;

            Console.WriteLine("Input plaintext matrix:");
            Utilities.PrintMatrix(podMatrix, (int)rowSize);
            Console.WriteLine();

            /*
             * First we use BatchEncoder to encode the matrix into a plaintext. We encrypt
             * the plaintext as usual.
             */
            Utilities.PrintLine();
            using Plaintext plainMatrix = new Plaintext();
            Console.WriteLine("Encode and encrypt.");
            batchEncoder.Encode(podMatrix, plainMatrix);
            using Ciphertext encryptedMatrix = new Ciphertext();
            encryptor.Encrypt(plainMatrix, encryptedMatrix);
            Console.WriteLine("    + Noise budget in fresh encryption: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));
            Console.WriteLine();

            /*
             * Rotations require yet another type of special key called `Galois keys'. These
             * are easily obtained from the KeyGenerator.
             */
            keygen.CreateGaloisKeys(out GaloisKeys galoisKeys);

            /*
             * Now rotate both matrix rows 3 steps to the left, decrypt, decode, and print.
             */
            Utilities.PrintLine();
            Console.WriteLine("Rotate rows 3 steps left.");
            evaluator.RotateRowsInplace(encryptedMatrix, 3, galoisKeys);
            using Plaintext plainResult = new Plaintext();
            Console.WriteLine("    + Noise budget after rotation: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));
            Console.WriteLine("    + Decrypt and decode ...... Correct.");
            decryptor.Decrypt(encryptedMatrix, plainResult);
            List <ulong> podResult = new List <ulong>();

            batchEncoder.Decode(plainResult, podResult);
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * We can also rotate the columns, i.e., swap the rows.
             */
            Utilities.PrintLine();
            Console.WriteLine("Rotate columns.");
            evaluator.RotateColumnsInplace(encryptedMatrix, galoisKeys);
            Console.WriteLine("    + Noise budget after rotation: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));
            Console.WriteLine("    + Decrypt and decode ...... Correct.");
            decryptor.Decrypt(encryptedMatrix, plainResult);
            batchEncoder.Decode(plainResult, podResult);
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Finally, we rotate the rows 4 steps to the right, decrypt, decode, and print.
             */
            Utilities.PrintLine();
            Console.WriteLine("Rotate rows 4 steps right.");
            evaluator.RotateRowsInplace(encryptedMatrix, -4, galoisKeys);
            Console.WriteLine("    + Noise budget after rotation: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));
            Console.WriteLine("    + Decrypt and decode ...... Correct.");
            decryptor.Decrypt(encryptedMatrix, plainResult);
            batchEncoder.Decode(plainResult, podResult);
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Note that rotations do not consume any noise budget. However, this is only
             * the case when the special prime is at least as large as the other primes. The
             * same holds for relinearization. Microsoft SEAL does not require that the
             * special prime is of any particular size, so ensuring this is the case is left
             * for the user to do.
             */
        }
Example #3
0
        /*
         * In `1_BFV_Basics.cs' we showed how to perform a very simple computation using the
         * BFV scheme. The computation was performed modulo the PlainModulus parameter, and
         * utilized only one coefficient from a BFV plaintext polynomial. This approach has
         * two notable problems:
         *
         *  (1) Practical applications typically use integer or real number arithmetic,
         *      not modular arithmetic;
         *  (2) We used only one coefficient of the plaintext polynomial. This is really
         *      wasteful, as the plaintext polynomial is large and will in any case be
         *      encrypted in its entirety.
         *
         * For (1), one may ask why not just increase the PlainModulus parameter until no
         * overflow occurs, and the computations behave as in integer arithmetic. The problem
         * is that increasing PlainModulus increases noise budget consumption, and decreases
         * the initial noise budget too.
         *
         * In these examples we will discuss other ways of laying out data into plaintext
         * elements (encoding) that allow more computations without data type overflow, and
         * can allow the full plaintext polynomial to be utilized.
         */
        private static void ExampleBatchEncoder()
        {
            Utilities.PrintExampleBanner("Example: Encoders / Batch Encoder");

            /*
             * [BatchEncoder] (For BFV or BGV scheme)
             *
             * Let N denote the PolyModulusDegree and T denote the PlainModulus. Batching
             * allows the BFV plaintext polynomials to be viewed as 2-by-(N/2) matrices, with
             * each element an integer modulo T. In the matrix view, encrypted operations act
             * element-wise on encrypted matrices, allowing the user to obtain speeds-ups of
             * several orders of magnitude in fully vectorizable computations. Thus, in all
             * but the simplest computations, batching should be the preferred method to use
             * with BFV, and when used properly will result in implementations outperforming
             * anything done without batching.
             *
             * In a later example, we will demonstrate how to use the BGV scheme. Batching
             * works similarly for the BGV scheme to this example for the BFV scheme. For
             * example, simply changing `SchemeType.BFV` into `SchemeType.BGV` can make
             * this example work for the BGV scheme.
             */
            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 8192;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);

            /*
             * To enable batching, we need to set the plain_modulus to be a prime number
             * congruent to 1 modulo 2*PolyModulusDegree. Microsoft SEAL provides a helper
             * method for finding such a prime. In this example we create a 20-bit prime
             * that supports batching.
             */
            parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);

            using SEALContext context = new SEALContext(parms);
            Utilities.PrintParameters(context);
            Console.WriteLine();

            /*
             * We can verify that batching is indeed enabled by looking at the encryption
             * parameter qualifiers created by SEALContext.
             */
            using var qualifiers = context.FirstContextData.Qualifiers;
            Console.WriteLine($"Batching enabled: {qualifiers.UsingBatching}");

            using KeyGenerator keygen = new KeyGenerator(context);
            using SecretKey secretKey = keygen.SecretKey;
            keygen.CreatePublicKey(out PublicKey publicKey);
            keygen.CreateRelinKeys(out RelinKeys relinKeys);
            using Encryptor encryptor = new Encryptor(context, publicKey);
            using Evaluator evaluator = new Evaluator(context);
            using Decryptor decryptor = new Decryptor(context, secretKey);

            /*
             * Batching is done through an instance of the BatchEncoder class.
             */
            using BatchEncoder batchEncoder = new BatchEncoder(context);

            /*
             * The total number of batching `slots' equals the PolyModulusDegree, N, and
             * these slots are organized into 2-by-(N/2) matrices that can be encrypted and
             * computed on. Each slot contains an integer modulo PlainModulus.
             */
            ulong slotCount = batchEncoder.SlotCount;
            ulong rowSize   = slotCount / 2;

            Console.WriteLine($"Plaintext matrix row size: {rowSize}");

            /*
             * The matrix plaintext is simply given to BatchEncoder as a flattened vector
             * of numbers. The first `rowSize' many numbers form the first row, and the
             * rest form the second row. Here we create the following matrix:
             *
             *  [ 0,  1,  2,  3,  0,  0, ...,  0 ]
             *  [ 4,  5,  6,  7,  0,  0, ...,  0 ]
             */
            ulong[] podMatrix = new ulong[slotCount];
            podMatrix[0]           = 0;
            podMatrix[1]           = 1;
            podMatrix[2]           = 2;
            podMatrix[3]           = 3;
            podMatrix[rowSize]     = 4;
            podMatrix[rowSize + 1] = 5;
            podMatrix[rowSize + 2] = 6;
            podMatrix[rowSize + 3] = 7;

            Console.WriteLine("Input plaintext matrix:");
            Utilities.PrintMatrix(podMatrix, (int)rowSize);

            /*
             * First we use BatchEncoder to encode the matrix into a plaintext polynomial.
             */
            using Plaintext plainMatrix = new Plaintext();
            Utilities.PrintLine();
            Console.WriteLine("Encode plaintext matrix:");
            batchEncoder.Encode(podMatrix, plainMatrix);

            /*
             * We can instantly decode to verify correctness of the encoding. Note that no
             * encryption or decryption has yet taken place.
             */
            List <ulong> podResult = new List <ulong>();

            Console.WriteLine("    + Decode plaintext matrix ...... Correct.");
            batchEncoder.Decode(plainMatrix, podResult);
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Next we encrypt the encoded plaintext.
             */
            using Ciphertext encryptedMatrix = new Ciphertext();
            Utilities.PrintLine();
            Console.WriteLine("Encrypt plainMatrix to encryptedMatrix.");
            encryptor.Encrypt(plainMatrix, encryptedMatrix);
            Console.WriteLine("    + Noise budget in encryptedMatrix: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));

            /*
             * Operating on the ciphertext results in homomorphic operations being performed
             * simultaneously in all 8192 slots (matrix elements). To illustrate this, we
             * form another plaintext matrix
             *
             *  [ 1,  2,  1,  2,  1,  2, ..., 2 ]
             *  [ 1,  2,  1,  2,  1,  2, ..., 2 ]
             *
             * and encode it into a plaintext.
             */
            ulong[] podMatrix2 = new ulong[slotCount];
            for (ulong i = 0; i < slotCount; i++)
            {
                podMatrix2[i] = (i & 1) + 1;
            }
            using Plaintext plainMatrix2 = new Plaintext();
            batchEncoder.Encode(podMatrix2, plainMatrix2);
            Console.WriteLine();
            Console.WriteLine("Second input plaintext matrix:");
            Utilities.PrintMatrix(podMatrix2, (int)rowSize);

            /*
             * We now add the second (plaintext) matrix to the encrypted matrix, and square
             * the sum.
             */
            Utilities.PrintLine();
            Console.WriteLine("Sum, square, and relinearize.");
            evaluator.AddPlainInplace(encryptedMatrix, plainMatrix2);
            evaluator.SquareInplace(encryptedMatrix);
            evaluator.RelinearizeInplace(encryptedMatrix, relinKeys);

            /*
             * How much noise budget do we have left?
             */
            Console.WriteLine("    + Noise budget in result: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedMatrix));

            /*
             * We decrypt and decompose the plaintext to recover the result as a matrix.
             */
            using Plaintext plainResult = new Plaintext();
            Utilities.PrintLine();
            Console.WriteLine("Decrypt and decode result.");
            decryptor.Decrypt(encryptedMatrix, plainResult);
            batchEncoder.Decode(plainResult, podResult);
            Console.WriteLine("    + Result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Batching allows us to efficiently use the full plaintext polynomial when the
             * desired encrypted computation is highly parallelizable. However, it has not
             * solved the other problem mentioned in the beginning of this file: each slot
             * holds only an integer modulo plain_modulus, and unless plain_modulus is very
             * large, we can quickly encounter data type overflow and get unexpected results
             * when integer computations are desired. Note that overflow cannot be detected
             * in encrypted form. The CKKS scheme (and the CKKSEncoder) addresses the data
             * type overflow issue, but at the cost of yielding only approximate results.
             */
        }
Example #4
0
        public void SeededKeyTest()
        {
            {
                EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
                {
                    PolyModulusDegree = 8,
                    PlainModulus      = new Modulus(257),
                    CoeffModulus      = CoeffModulus.Create(8, new int[] { 40, 40 })
                };
                SEALContext context = new SEALContext(parms,
                                                      expandModChain: false,
                                                      secLevel: SecLevelType.None);
                KeyGenerator keygen = new KeyGenerator(context);
                keygen.CreatePublicKey(out PublicKey publicKey);

                Encryptor    encryptor = new Encryptor(context, publicKey);
                Decryptor    decryptor = new Decryptor(context, keygen.SecretKey);
                Evaluator    evaluator = new Evaluator(context);
                BatchEncoder encoder   = new BatchEncoder(context);

                GaloisKeys galoisKeys = new GaloisKeys();
                using (MemoryStream stream = new MemoryStream())
                {
                    keygen.CreateGaloisKeys().Save(stream);
                    stream.Seek(0, SeekOrigin.Begin);
                    galoisKeys.Load(context, stream);
                }

                Plaintext    plain = new Plaintext();
                List <ulong> vec   = new List <ulong>
                {
                    1, 2, 3, 4,
                    5, 6, 7, 8
                };

                encoder.Encode(vec, plain);

                Ciphertext encrypted = new Ciphertext();
                Ciphertext encdest   = new Ciphertext();
                Plaintext  plaindest = new Plaintext();

                encryptor.Encrypt(plain, encrypted);
                evaluator.RotateColumns(encrypted, galoisKeys, encdest);
                decryptor.Decrypt(encdest, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    5, 6, 7, 8,
                    1, 2, 3, 4
                }));

                evaluator.RotateRows(encdest, -1, galoisKeys, encrypted);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    8, 5, 6, 7,
                    4, 1, 2, 3
                }));

                evaluator.RotateRowsInplace(encrypted, 2, galoisKeys);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    6, 7, 8, 5,
                    2, 3, 4, 1
                }));

                evaluator.RotateColumnsInplace(encrypted, galoisKeys);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    2, 3, 4, 1,
                    6, 7, 8, 5
                }));
            }
            {
                EncryptionParameters parms = new EncryptionParameters(SchemeType.BGV)
                {
                    PolyModulusDegree = 8,
                    PlainModulus      = new Modulus(257),
                    CoeffModulus      = CoeffModulus.Create(8, new int[] { 40, 40 })
                };
                SEALContext context = new SEALContext(parms,
                                                      expandModChain: false,
                                                      secLevel: SecLevelType.None);
                KeyGenerator keygen = new KeyGenerator(context);
                keygen.CreatePublicKey(out PublicKey publicKey);

                Encryptor    encryptor = new Encryptor(context, publicKey);
                Decryptor    decryptor = new Decryptor(context, keygen.SecretKey);
                Evaluator    evaluator = new Evaluator(context);
                BatchEncoder encoder   = new BatchEncoder(context);

                GaloisKeys galoisKeys = new GaloisKeys();
                using (MemoryStream stream = new MemoryStream())
                {
                    keygen.CreateGaloisKeys().Save(stream);
                    stream.Seek(0, SeekOrigin.Begin);
                    galoisKeys.Load(context, stream);
                }

                Plaintext    plain = new Plaintext();
                List <ulong> vec   = new List <ulong>
                {
                    1, 2, 3, 4,
                    5, 6, 7, 8
                };

                encoder.Encode(vec, plain);

                Ciphertext encrypted = new Ciphertext();
                Ciphertext encdest   = new Ciphertext();
                Plaintext  plaindest = new Plaintext();

                encryptor.Encrypt(plain, encrypted);
                evaluator.RotateColumns(encrypted, galoisKeys, encdest);
                decryptor.Decrypt(encdest, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    5, 6, 7, 8,
                    1, 2, 3, 4
                }));

                evaluator.RotateRows(encdest, -1, galoisKeys, encrypted);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    8, 5, 6, 7,
                    4, 1, 2, 3
                }));

                evaluator.RotateRowsInplace(encrypted, 2, galoisKeys);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    6, 7, 8, 5,
                    2, 3, 4, 1
                }));

                evaluator.RotateColumnsInplace(encrypted, galoisKeys);
                decryptor.Decrypt(encrypted, plaindest);
                encoder.Decode(plaindest, vec);

                Assert.IsTrue(AreCollectionsEqual(vec, new List <ulong>
                {
                    2, 3, 4, 1,
                    6, 7, 8, 5
                }));
            }
        }
Example #5
0
        private static void BFVPerformanceTest(SEALContext context)
        {
            Stopwatch timer;

            Utilities.PrintParameters(context);
            Console.WriteLine();

            using EncryptionParameters parms = context.FirstContextData.Parms;
            using Modulus plainModulus       = parms.PlainModulus;
            ulong polyModulusDegree = parms.PolyModulusDegree;

            Console.Write("Generating secret/public keys: ");
            using KeyGenerator keygen = new KeyGenerator(context);
            Console.WriteLine("Done");

            using SecretKey secretKey = keygen.SecretKey;
            using PublicKey publicKey = keygen.PublicKey;

            Func <RelinKeys> GetRelinKeys = () => {
                if (context.UsingKeyswitching)
                {
                    /*
                     * Generate relinearization keys.
                     */
                    Console.Write("Generating relinearization keys: ");
                    timer = Stopwatch.StartNew();
                    RelinKeys result = keygen.RelinKeysLocal();
                    int       micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
                    Console.WriteLine($"Done [{micros} microseconds]");
                    return(result);
                }
                else
                {
                    return(null);
                }
            };

            Func <GaloisKeys> GetGaloisKeys = () => {
                if (context.UsingKeyswitching)
                {
                    if (!context.KeyContextData.Qualifiers.UsingBatching)
                    {
                        Console.WriteLine("Given encryption parameters do not support batching.");
                        return(null);
                    }

                    /*
                     * Generate Galois keys. In larger examples the Galois keys can use a lot of
                     * memory, which can be a problem in constrained systems. The user should
                     * try some of the larger runs of the test and observe their effect on the
                     * memory pool allocation size. The key generation can also take a long time,
                     * as can be observed from the print-out.
                     */
                    Console.Write($"Generating Galois keys: ");
                    timer = Stopwatch.StartNew();
                    GaloisKeys result = keygen.GaloisKeysLocal();
                    int        micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
                    Console.WriteLine($"Done [{micros} microseconds]");
                    return(result);
                }
                else
                {
                    return(null);
                }
            };

            using RelinKeys relinKeys = GetRelinKeys();
            using GaloisKeys galKeys  = GetGaloisKeys();

            using Encryptor encryptor       = new Encryptor(context, publicKey);
            using Decryptor decryptor       = new Decryptor(context, secretKey);
            using Evaluator evaluator       = new Evaluator(context);
            using BatchEncoder batchEncoder = new BatchEncoder(context);
            using IntegerEncoder encoder    = new IntegerEncoder(context);

            /*
             * These will hold the total times used by each operation.
             */
            Stopwatch timeBatchSum             = new Stopwatch();
            Stopwatch timeUnbatchSum           = new Stopwatch();
            Stopwatch timeEncryptSum           = new Stopwatch();
            Stopwatch timeDecryptSum           = new Stopwatch();
            Stopwatch timeAddSum               = new Stopwatch();
            Stopwatch timeMultiplySum          = new Stopwatch();
            Stopwatch timeMultiplyPlainSum     = new Stopwatch();
            Stopwatch timeSquareSum            = new Stopwatch();
            Stopwatch timeRelinearizeSum       = new Stopwatch();
            Stopwatch timeRotateRowsOneStepSum = new Stopwatch();
            Stopwatch timeRotateRowsRandomSum  = new Stopwatch();
            Stopwatch timeRotateColumnsSum     = new Stopwatch();

            /*
             * How many times to run the test?
             */
            int count = 10;

            /*
             * Populate a vector of values to batch.
             */
            ulong slotCount = batchEncoder.SlotCount;

            ulong[] podValues = new ulong[slotCount];
            Random  rnd       = new Random();

            for (ulong i = 0; i < batchEncoder.SlotCount; i++)
            {
                podValues[i] = (ulong)rnd.Next() % plainModulus.Value;
            }

            Console.Write("Running tests ");
            for (int i = 0; i < count; i++)
            {
                /*
                 * [Batching]
                 * There is nothing unusual here. We batch our random plaintext matrix
                 * into the polynomial. Note how the plaintext we create is of the exactly
                 * right size so unnecessary reallocations are avoided.
                 */
                using Plaintext plain = new Plaintext(parms.PolyModulusDegree, 0);
                timeBatchSum.Start();
                batchEncoder.Encode(podValues, plain);
                timeBatchSum.Stop();

                /*
                 * [Unbatching]
                 * We unbatch what we just batched.
                 */
                List <ulong> podList = new List <ulong>((int)slotCount);
                timeUnbatchSum.Start();
                batchEncoder.Decode(plain, podList);
                timeUnbatchSum.Stop();
                if (!podList.SequenceEqual(podValues))
                {
                    throw new InvalidOperationException("Batch/unbatch failed. Something is wrong.");
                }

                /*
                 * [Encryption]
                 * We make sure our ciphertext is already allocated and large enough
                 * to hold the encryption with these encryption parameters. We encrypt
                 * our random batched matrix here.
                 */
                using Ciphertext encrypted = new Ciphertext(context);
                timeEncryptSum.Start();
                encryptor.Encrypt(plain, encrypted);
                timeEncryptSum.Stop();

                /*
                 * [Decryption]
                 * We decrypt what we just encrypted.
                 */
                using Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
                timeDecryptSum.Start();
                decryptor.Decrypt(encrypted, plain2);
                timeDecryptSum.Stop();
                if (!plain2.Equals(plain))
                {
                    throw new InvalidOperationException("Encrypt/decrypt failed. Something is wrong.");
                }

                /*
                 * [Add]
                 * We create two ciphertexts and perform a few additions with them.
                 */
                using Ciphertext encrypted1 = new Ciphertext(context);
                encryptor.Encrypt(encoder.Encode(i), encrypted1);
                using Ciphertext encrypted2 = new Ciphertext(context);
                encryptor.Encrypt(encoder.Encode(i + 1), encrypted2);

                timeAddSum.Start();
                evaluator.AddInplace(encrypted1, encrypted1);
                evaluator.AddInplace(encrypted2, encrypted2);
                evaluator.AddInplace(encrypted1, encrypted2);
                timeAddSum.Stop();

                /*
                 * [Multiply]
                 * We multiply two ciphertexts. Since the size of the result will be 3,
                 * and will overwrite the first argument, we reserve first enough memory
                 * to avoid reallocating during multiplication.
                 */
                encrypted1.Reserve(3);
                timeMultiplySum.Start();
                evaluator.MultiplyInplace(encrypted1, encrypted2);
                timeMultiplySum.Stop();

                /*
                 * [Multiply Plain]
                 * We multiply a ciphertext with a random plaintext. Recall that
                 * MultiplyPlain does not change the size of the ciphertext so we use
                 * encrypted2 here.
                 */
                timeMultiplyPlainSum.Start();
                evaluator.MultiplyPlainInplace(encrypted2, plain);
                timeMultiplyPlainSum.Stop();

                /*
                 * [Square]
                 * We continue to use encrypted2. Now we square it; this should be
                 * faster than generic homomorphic multiplication.
                 */
                timeSquareSum.Start();
                evaluator.SquareInplace(encrypted2);
                timeSquareSum.Stop();

                if (context.UsingKeyswitching)
                {
                    /*
                     * [Relinearize]
                     * Time to get back to encrypted1. We now relinearize it back
                     * to size 2. Since the allocation is currently big enough to
                     * contain a ciphertext of size 3, no costly reallocations are
                     * needed in the process.
                     */
                    timeRelinearizeSum.Start();
                    evaluator.RelinearizeInplace(encrypted1, relinKeys);
                    timeRelinearizeSum.Stop();

                    /*
                     * [Rotate Rows One Step]
                     * We rotate matrix rows by one step left and measure the time.
                     */
                    timeRotateRowsOneStepSum.Start();
                    evaluator.RotateRowsInplace(encrypted, 1, galKeys);
                    evaluator.RotateRowsInplace(encrypted, -1, galKeys);
                    timeRotateRowsOneStepSum.Stop();

                    /*
                     * [Rotate Rows Random]
                     * We rotate matrix rows by a random number of steps. This is much more
                     * expensive than rotating by just one step.
                     */
                    int rowSize        = (int)batchEncoder.SlotCount / 2;
                    int randomRotation = rnd.Next() % rowSize;
                    timeRotateRowsRandomSum.Start();
                    evaluator.RotateRowsInplace(encrypted, randomRotation, galKeys);
                    timeRotateRowsRandomSum.Stop();

                    /*
                     * [Rotate Columns]
                     * Nothing surprising here.
                     */
                    timeRotateColumnsSum.Start();
                    evaluator.RotateColumnsInplace(encrypted, galKeys);
                    timeRotateColumnsSum.Stop();
                }


                /*
                 * Print a dot to indicate progress.
                 */
                Console.Write(".");
                Console.Out.Flush();
            }

            Console.WriteLine(" Done");
            Console.WriteLine();
            Console.Out.Flush();

            int avgBatch             = (int)(timeBatchSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgUnbatch           = (int)(timeUnbatchSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgEncrypt           = (int)(timeEncryptSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgDecrypt           = (int)(timeDecryptSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgAdd               = (int)(timeAddSum.Elapsed.TotalMilliseconds * 1000 / (3 * count));
            int avgMultiply          = (int)(timeMultiplySum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgMultiplyPlain     = (int)(timeMultiplyPlainSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgSquare            = (int)(timeSquareSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgRelinearize       = (int)(timeRelinearizeSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgRotateRowsOneStep = (int)(timeRotateRowsOneStepSum.Elapsed.TotalMilliseconds * 1000 / (2 * count));
            int avgRotateRowsRandom  = (int)(timeRotateRowsRandomSum.Elapsed.TotalMilliseconds * 1000 / count);
            int avgRotateColumns     = (int)(timeRotateColumnsSum.Elapsed.TotalMilliseconds * 1000 / count);

            Console.WriteLine($"Average batch: {avgBatch} microseconds");
            Console.WriteLine($"Average unbatch: {avgUnbatch} microseconds");
            Console.WriteLine($"Average encrypt: {avgEncrypt} microseconds");
            Console.WriteLine($"Average decrypt: {avgDecrypt} microseconds");
            Console.WriteLine($"Average add: {avgAdd} microseconds");
            Console.WriteLine($"Average multiply: {avgMultiply} microseconds");
            Console.WriteLine($"Average multiply plain: {avgMultiplyPlain} microseconds");
            Console.WriteLine($"Average square: {avgSquare} microseconds");
            if (context.UsingKeyswitching)
            {
                Console.WriteLine($"Average relinearize: {avgRelinearize} microseconds");
                Console.WriteLine($"Average rotate rows one step: {avgRotateRowsOneStep} microseconds");
                Console.WriteLine($"Average rotate rows random: {avgRotateRowsRandom} microseconds");
                Console.WriteLine($"Average rotate columns: {avgRotateColumns} microseconds");
            }
            Console.Out.Flush();
        }
Example #6
0
        public BatchEncoder CreateBatchEncoder()
        {
            var batchEncoder = new BatchEncoder(SealContext);

            return(batchEncoder);
        }
Example #7
0
        /// <summary>
        /// Convert a Matrix to a twisted Ciphertext.
        /// Rows in the matrix are laid next to each other in a Plaintext and then encrypted.
        /// The second batching row is duplicate of the first one but rotated by eltSeparation
        /// </summary>
        /// <param name="matrix">Matrix to convert to Ciphertext</param>
        /// <param name="encryptor">Encryptor used to encrypt Plaintext data</param>
        /// <param name="encoder">BatchEncoder used to encode the matrix data</param>
        /// <returns>Encrypted matrix</returns>
        public static Ciphertext MatrixToTwistedCiphertext(int[,] matrix, Encryptor encryptor, BatchEncoder encoder)
        {
            int batchRowSize    = (int)encoder.SlotCount / 2;
            int rows            = matrix.GetLength(dimension: 0);
            int cols            = matrix.GetLength(dimension: 1);
            int paddedColLength = FindNextPowerOfTwo((ulong)rows);
            int eltSeparation   = batchRowSize / paddedColLength;

            long[] batchArray = new long[encoder.SlotCount];

            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    batchArray[r * eltSeparation + c] = (long)matrix[r, c];
                    batchArray[batchRowSize + ((batchRowSize + (r - 1) * eltSeparation) % batchRowSize) + c] = (long)matrix[r, c];
                }
            }

            Plaintext plain = new Plaintext();

            encoder.Encode(batchArray, plain);

            Ciphertext result = new Ciphertext();

            encryptor.Encrypt(plain, result);
            return(result);
        }
Example #8
0
        public void EncodeLongTest()
        {
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            parms.PolyModulusDegree = 64;
            List <SmallModulus> coeffModulus = new List <SmallModulus>();

            coeffModulus.Add(DefaultParams.SmallMods60Bit(0));
            parms.CoeffModulus = coeffModulus;
            parms.PlainModulus = new SmallModulus(257);

            SEALContext context = SEALContext.Create(parms);

            BatchEncoder encoder = new BatchEncoder(context);

            Assert.AreEqual(64ul, encoder.SlotCount);

            List <long> plainList = new List <long>();

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                plainList.Add((long)i);
            }

            Plaintext plain = new Plaintext();

            encoder.Encode(plainList, plain);

            List <long> plainList2 = new List <long>();

            encoder.Decode(plain, plainList2);

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(plainList[(int)i], plainList2[(int)i]);
            }

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                plainList[(int)i] = 5;
            }

            encoder.Encode(plainList, plain);
            Assert.AreEqual("5", plain.ToString());

            encoder.Decode(plain, plainList2);

            for (ulong i = 0; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(plainList[(int)i], plainList2[(int)i]);
            }

            List <long> shortList = new List <long>();

            for (int i = 0; i < 20; i++)
            {
                shortList.Add((long)i);
            }

            encoder.Encode(shortList, plain);

            List <long> shortList2 = new List <long>();

            encoder.Decode(plain, shortList2);

            Assert.AreEqual(20, shortList.Count);
            Assert.AreEqual(64, shortList2.Count);

            for (int i = 0; i < 20; i++)
            {
                Assert.AreEqual(shortList[i], shortList2[i]);
            }

            for (ulong i = 20; i < encoder.SlotCount; i++)
            {
                Assert.AreEqual(0L, shortList2[(int)i]);
            }
        }
Example #9
0
        /// <summary>
        /// Set the indicated Matrix column as the coefficients of a Plaintext (in inverse order)
        /// and encrypt it.
        /// </summary>
        /// <param name="matrix">Matrix to get a column from</param>
        /// <param name="col">Column to encrypt</param>
        /// <param name="encryptor">Encryptor used to encrypt column data</param>
        /// <param name="encoder">BatchEncoder used to encode the matrix data</param>
        /// <returns>Encrypted inverted matrix column</returns>
        public static Ciphertext InvertedColumnToCiphertext(int[,] matrix, int col, Encryptor encryptor, BatchEncoder encoder)
        {
            int batchRowSize  = (int)encoder.SlotCount / 2;
            int rows          = matrix.GetLength(dimension: 0);
            int paddedLength  = FindNextPowerOfTwo((ulong)rows);
            int eltSeparation = batchRowSize / paddedLength;

            long[] colToEncrypt = new long[batchRowSize];
            for (int r = 0; r < rows; r++)
            {
                colToEncrypt[eltSeparation * r] = matrix[r, col];
            }

            Plaintext plain = new Plaintext();

            encoder.Encode(colToEncrypt, plain);

            Ciphertext result = new Ciphertext();

            encryptor.Encrypt(plain, result);
            return(result);
        }
Example #10
0
        /// <summary>
        /// Set the indicated Matrix rows as the coefficients of Plaintexts and encrypt them.
        /// Two rows will always be encrypted into a single ciphertext into the two batching "rows".
        /// </summary>
        /// <param name="matrix">Matrix to get a row from</param>
        /// <param name="repl">How many times to replicate the row values</param>
        /// <param name="encryptor">Encryptor used to encrypt row data</param>
        /// <param name="encoder">BatchEncoder used to encode the matrix data</param>
        /// <returns>Encrypted matrix rows</returns>
        public static List <Ciphertext> RowsToCiphertexts(int[,] matrix, int repl, Encryptor encryptor, BatchEncoder encoder)
        {
            int batchRowCount = 2;
            int batchRowSize  = (int)encoder.SlotCount / 2;
            int cols          = matrix.GetLength(dimension: 1);
            int rows          = matrix.GetLength(dimension: 0);
            int paddedLength  = FindNextPowerOfTwo((ulong)cols);
            int eltSeparation = batchRowSize / paddedLength;

            if (repl < 0 || repl > eltSeparation)
            {
                throw new ArgumentException("repl out of bounds");
            }

            List <Ciphertext> result = new List <Ciphertext>();
            int r = 0;

            while (r < rows)
            {
                long[] batchArray = new long[encoder.SlotCount];
                for (int batchRowIndex = 0; batchRowIndex < batchRowCount && r < rows; batchRowIndex++, r++)
                {
                    for (int c = 0; c < cols; c++)
                    {
                        for (int j = 0; j < repl; j++)
                        {
                            batchArray[batchRowIndex * batchRowSize + eltSeparation * c + j] = matrix[r, c];
                        }
                    }
                }

                Plaintext plain = new Plaintext();
                encoder.Encode(batchArray, plain);

                Ciphertext newCipher = new Ciphertext();
                encryptor.Encrypt(plain, newCipher);
                result.Add(newCipher);
            }

            return(result);
        }
Example #11
0
        /// <summary>
        /// Set the indicated Matrix row as the coefficients of a Plaintext and encrypt it.
        /// </summary>
        /// <param name="matrix">Matrix to get a row from</param>
        /// <param name="row">Row to encrypt</param>
        /// <param name="repl">How many times to replicate the row values</param>
        /// <param name="encryptor">Encryptor used to encrypt row data</param>
        /// <param name="encoder">BatchEncoder used to encode the matrix data</param>
        /// <returns>Encrypted matrix row</returns>
        public static Ciphertext RowToCiphertext(int[,] matrix, int row, int repl, Encryptor encryptor, BatchEncoder encoder)
        {
            int batchRowSize  = (int)encoder.SlotCount / 2;
            int cols          = matrix.GetLength(dimension: 1);
            int paddedLength  = FindNextPowerOfTwo((ulong)cols);
            int eltSeparation = batchRowSize / paddedLength;

            if (repl < 0 || repl > eltSeparation)
            {
                throw new ArgumentException("repl out of bounds");
            }

            long[] rowToEncrypt = new long[batchRowSize];
            for (int c = 0; c < cols; c++)
            {
                for (int j = 0; j < repl; j++)
                {
                    rowToEncrypt[eltSeparation * c + j] = matrix[row, c];
                }
            }

            Plaintext plain = new Plaintext();

            encoder.Encode(rowToEncrypt, plain);

            Ciphertext result = new Ciphertext();

            encryptor.Encrypt(plain, result);
            return(result);
        }
Example #12
0
        private static void ExampleBGVBasics()
        {
            Utilities.PrintExampleBanner("Example: BGV Basics");

            /*
             * As an example, we evaluate the degree 8 polynomial
             *
             *  x^8
             *
             * over an encrypted x over integers 1, 2, 3, 4. The coefficients of the
             * polynomial can be considered as plaintext inputs, as we will see below. The
             * computation is done modulo the plain_modulus 1032193.
             *
             * Computing over encrypted data in the BGV scheme is similar to that in BFV.
             * The purpose of this example is mainly to explain the differences between BFV
             * and BGV in terms of ciphertext coefficient modulus selection and noise control.
             *
             * Most of the following code are repeated from "BFV basics" and "encoders" examples.
             */

            /*
             * Note that scheme_type is now "bgv".
             */
            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BGV);
            ulong polyModulusDegree = 8192;

            parms.PolyModulusDegree = polyModulusDegree;

            /*
             * We can certainly use BFVDefault coeff_modulus. In later parts of this example,
             * we will demonstrate how to choose coeff_modulus that is more useful in BGV.
             */
            parms.CoeffModulus        = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus        = PlainModulus.Batching(polyModulusDegree, 20);
            using SEALContext context = new SEALContext(parms);

            /*
             * Print the parameters that we have chosen.
             */
            Utilities.PrintLine();
            Console.WriteLine("Set encryption parameters and print");
            Utilities.PrintParameters(context);

            using KeyGenerator keygen = new KeyGenerator(context);
            using SecretKey secretKey = keygen.SecretKey;
            keygen.CreatePublicKey(out PublicKey publicKey);
            keygen.CreateRelinKeys(out RelinKeys relinKeys);
            using Encryptor encryptor = new Encryptor(context, publicKey);
            using Evaluator evaluator = new Evaluator(context);
            using Decryptor decryptor = new Decryptor(context, secretKey);

            /*
             * Batching and slot operations are the same in BFV and BGV.
             */
            using BatchEncoder batchEncoder = new BatchEncoder(context);
            ulong slotCount = batchEncoder.SlotCount;
            ulong rowSize   = slotCount / 2;

            Console.WriteLine($"Plaintext matrix row size: {rowSize}");

            /*
             * Here we create the following matrix:
             *  [ 1,  2,  3,  4,  0,  0, ...,  0 ]
             *  [ 0,  0,  0,  0,  0,  0, ...,  0 ]
             */
            ulong[] podMatrix = new ulong[slotCount];
            podMatrix[0] = 1;
            podMatrix[1] = 2;
            podMatrix[2] = 3;
            podMatrix[3] = 4;

            Console.WriteLine("Input plaintext matrix:");
            Utilities.PrintMatrix(podMatrix, (int)rowSize);
            using Plaintext xPlain = new Plaintext();
            Console.WriteLine("Encode plaintext matrix to xPlain:");
            batchEncoder.Encode(podMatrix, xPlain);

            /*
             * Next we encrypt the encoded plaintext.
             */
            using Ciphertext xEncrypted = new Ciphertext();
            Utilities.PrintLine();
            Console.WriteLine("Encrypt xPlain to xEncrypted.");
            encryptor.Encrypt(xPlain, xEncrypted);
            Console.WriteLine("    + noise budget in freshly encrypted x: {0} bits",
                              decryptor.InvariantNoiseBudget(xEncrypted));
            Console.WriteLine();

            /*
             * Then we compute x^2.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize xSquared (x^2),");
            using Ciphertext xSquared = new Ciphertext();
            evaluator.Square(xEncrypted, xSquared);
            Console.WriteLine($"    + size of xSquared: {xSquared.Size}");
            evaluator.RelinearizeInplace(xSquared, relinKeys);
            Console.WriteLine("    + size of xSquared (after relinearization): {0}",
                              xSquared.Size);
            Console.WriteLine("    + noise budget in xSquared: {0} bits",
                              decryptor.InvariantNoiseBudget(xSquared));
            using Plaintext decryptedResult = new Plaintext();
            decryptor.Decrypt(xSquared, decryptedResult);
            List <ulong> podResult = new List <ulong>();

            batchEncoder.Decode(decryptedResult, podResult);
            Console.WriteLine("    + result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Next we compute x^4.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize x4th (x^4),");
            using Ciphertext x4th = new Ciphertext();
            evaluator.Square(xSquared, x4th);
            Console.WriteLine($"    + size of x4th: {x4th.Size}");
            evaluator.RelinearizeInplace(x4th, relinKeys);
            Console.WriteLine("    + size of x4th (after relinearization): {0}",
                              x4th.Size);
            Console.WriteLine("    + noise budget in x4th: {0} bits",
                              decryptor.InvariantNoiseBudget(x4th));
            decryptor.Decrypt(x4th, decryptedResult);
            batchEncoder.Decode(decryptedResult, podResult);
            Console.WriteLine("    + result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Last we compute x^8. We run out of noise budget.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize x8th (x^8),");
            using Ciphertext x8th = new Ciphertext();
            evaluator.Square(x4th, x8th);
            Console.WriteLine($"    + size of x8th: {x8th.Size}");
            evaluator.RelinearizeInplace(x8th, relinKeys);
            Console.WriteLine("    + size of x8th (after relinearization): {0}",
                              x8th.Size);
            Console.WriteLine("    + noise budget in x8th: {0} bits",
                              decryptor.InvariantNoiseBudget(x8th));
            Console.WriteLine("NOTE: Notice the increase in remaining noise budget.");

            Console.WriteLine();
            Console.WriteLine("~~~~~~ Use modulus switching to calculate x^8. ~~~~~~");

            /*
             * Noise budget has reached 0, which means that decryption cannot be expected
             * to give the correct result. BGV requires modulus switching to reduce noise
             * growth. In the following demonstration, we will insert a modulus switching
             * after each relinearization.
             */
            Utilities.PrintLine();
            Console.WriteLine("Encrypt xPlain to xEncrypted.");
            encryptor.Encrypt(xPlain, xEncrypted);
            Console.WriteLine("    + noise budget in freshly encrypted x: {0} bits",
                              decryptor.InvariantNoiseBudget(xEncrypted));
            Console.WriteLine();

            /*
             * Then we compute x^2.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize xSquared (x^2),");
            Console.WriteLine("    + noise budget in xSquared (previously): {0} bits",
                              decryptor.InvariantNoiseBudget(xSquared));
            evaluator.Square(xEncrypted, xSquared);
            evaluator.RelinearizeInplace(xSquared, relinKeys);
            evaluator.ModSwitchToNextInplace(xSquared);
            Console.WriteLine("    + noise budget in xSquared (with modulus switching): {0} bits",
                              decryptor.InvariantNoiseBudget(xSquared));
            decryptor.Decrypt(xSquared, decryptedResult);
            batchEncoder.Decode(decryptedResult, podResult);
            Console.WriteLine("    + result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Next we compute x^4.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize x4th (x^4),");
            Console.WriteLine("    + noise budget in x4th (previously): {0} bits",
                              decryptor.InvariantNoiseBudget(x4th));
            evaluator.Square(xSquared, x4th);
            evaluator.RelinearizeInplace(x4th, relinKeys);
            evaluator.ModSwitchToNextInplace(x4th);
            Console.WriteLine("    + noise budget in x4th (with modulus switching): {0} bits",
                              decryptor.InvariantNoiseBudget(x4th));
            decryptor.Decrypt(x4th, decryptedResult);
            batchEncoder.Decode(decryptedResult, podResult);
            Console.WriteLine("    + result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Last we compute x^8. We still have budget left.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize x8th (x^8),");
            Console.WriteLine("    + noise budget in x8th (previously): {0} bits",
                              decryptor.InvariantNoiseBudget(x8th));
            evaluator.Square(x4th, x8th);
            evaluator.RelinearizeInplace(x8th, relinKeys);
            evaluator.ModSwitchToNextInplace(x8th);
            Console.WriteLine("    + noise budget in x8th (with modulus switching): {0} bits",
                              decryptor.InvariantNoiseBudget(x8th));
            decryptor.Decrypt(x8th, decryptedResult);
            batchEncoder.Decode(decryptedResult, podResult);
            Console.WriteLine("    + result plaintext matrix ...... Correct.");
            Utilities.PrintMatrix(podResult, (int)rowSize);

            /*
             * Although with modulus switching x_squared has less noise budget than before,
             * noise budget is consumed at a slower rate. To achieve the optimal consumption
             * rate of noise budget in an application, one needs to carefully choose the
             * location to insert modulus switching and manually choose coeff_modulus.
             */
        }
Example #13
0
        private void btnCreate_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrWhiteSpace(txtFilePath.Text))
            {
                return;
            }
            lvBatchEncode.Items.Clear();
            Running = true;

            /*
             *          try
             *          {
             *              tabMain.AllowSelect = false;
             *              this.btnCreate.Enabled = false;
             *              AutoResetEvent finish = new AutoResetEvent(false);
             *              Thread waitTime = new Thread(() =>
             *              {
             *                  DateTime dtStart = DateTime.Now;
             *                  this.Invoke(new MethodInvoker(() =>
             *                  {
             *                      this.toolStripStatusLabel2.Text = "正在读取文件和生成二维码";
             *                  }));
             *                  finish.WaitOne();
             *                  DateTime dtFinish = DateTime.Now;
             *                  this.Invoke(new MethodInvoker(() =>
             *                  {
             *                      this.toolStripStatusLabel2.Text = "生成完成,所用时间:"
             + ((int)(dtFinish - dtStart).TotalSeconds).ToString("d") + "秒";
             +                      this.btnCreate.Enabled = true;
             +                      tabMain.AllowSelect = true;
             +                      Running = false;
             +                  }));
             +              });
             +              waitTime.IsBackground = true;
             +              waitTime.Name = "计时线程";
             +              waitTime.Start();
             +
             +              string filePath = txtFilePath.Text;
             +              listFileReaded.Items.Clear();
             +              BatchEncode be = new BatchEncode(filePath, this);
             +              Thread createThread = new Thread(() =>
             +              {
             +                  be.Start();
             +                  finish.Set();
             +              });
             +              createThread.IsBackground = true;
             +              createThread.Name = "生成主线程";
             +              createThread.Start();
             +          }
             +          catch (Exception ex)
             +          {
             +              MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
             +          }
             */

            /*
             *          string filePath = txtFilePath.Text;
             *          string outDir = Path.GetDirectoryName(filePath) + "\\CreatedQRcode";
             *          toolStripStatusLabel2.Text = "正在读取文件和生成二维码";
             *          tabMain.AllowSelect = false;
             *          btnCreate.Enabled = false;
             *
             *          Task.Factory.StartNew(() =>
             *          {
             *              TimeSpan timeSpan = BatchEncode(filePath, outDir);
             *              this.Invoke(new MethodInvoker(() =>
             *              {
             *                  this.toolStripStatusLabel2.Text = string.Format("生成完成,所用时间:{0}秒",
             *                      timeSpan.TotalSeconds.ToString("2f"));
             *                  this.btnCreate.Enabled = true;
             *                  tabMain.AllowSelect = true;
             *                  Running = false;
             *              }));
             *
             *          });
             */
            string       filePath = txtFilePath.Text;
            string       outDir   = Path.Combine(Path.GetDirectoryName(filePath), "CreatedQRcode");
            BatchEncoder encoder  = new BatchEncoder(filePath, outDir,
                                                     (EventInfo eventInfo) =>
            {
                BatchEncoder.ReadLineEventTarget target =
                    eventInfo.Target as BatchEncoder.ReadLineEventTarget;

                ListViewItem item = new ListViewItem(new[] { target.LineIndex.ToString(), target.Text, "" });
                AddItemForListView(lvBatchEncode, item);
            },
                                                     (EventInfo eventInfo) =>
            {
                if (eventInfo.Type == EventInfo.EventType.OK)
                {
                    BatchEncoder.EncodeLineToFileEventTarget target =
                        eventInfo.Target as BatchEncoder.EncodeLineToFileEventTarget;
                    SetCellForListView(lvBatchEncode, target.LineIndex, 2, "成功");
                }
                else if (eventInfo.Type == EventInfo.EventType.ERROR)
                {
                }
            });

            Task.Factory.StartNew(() =>
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                encoder.BatchEncode(false);
                watch.Stop();
                toolStripStatusLabel2.Text =
                    string.Format("生成完成,所用时间:{0}秒", watch.Elapsed.TotalSeconds.ToString("f3"));
                Running = false;
            });
        }