コード例 #1
0
ファイル: GlobalContext.cs プロジェクト: microsoft/SEAL
        static GlobalContext()
        {
            EncryptionParameters encParams = new EncryptionParameters(SchemeType.BFV)
            {
                PolyModulusDegree = 8192,
                CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree: 8192)
            };

            encParams.SetPlainModulus(65537ul);
            BFVContext = new SEALContext(encParams);

            encParams = new EncryptionParameters(SchemeType.CKKS)
            {
                PolyModulusDegree = 8192,
                CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree: 8192)
            };
            CKKSContext = new SEALContext(encParams);

            encParams = new EncryptionParameters(SchemeType.BGV)
            {
                PolyModulusDegree = 8192,
                CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree: 8192)
            };
            encParams.SetPlainModulus(65537ul);
            BGVContext = new SEALContext(encParams);
        }
コード例 #2
0
        public void ExpandModChainTest()
        {
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
            {
                PolyModulusDegree = 4096,
                CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree: 4096),
                PlainModulus      = new Modulus(1 << 20)
            };

            SEALContext context1 = new SEALContext(parms,
                                                   expandModChain: true,
                                                   secLevel: SecLevelType.None);

            // By default there is a chain
            SEALContext.ContextData contextData = context1.KeyContextData;
            Assert.IsNotNull(contextData);
            Assert.IsNull(contextData.PrevContextData);
            Assert.IsNotNull(contextData.NextContextData);
            contextData = context1.FirstContextData;
            Assert.IsNotNull(contextData);
            Assert.IsNotNull(contextData.PrevContextData);
            Assert.IsNotNull(contextData.NextContextData);

            // This should not create a chain
            SEALContext context2 = new SEALContext(parms, expandModChain: false);

            contextData = context2.KeyContextData;
            Assert.IsNotNull(contextData);
            Assert.IsNull(contextData.PrevContextData);
            Assert.IsNotNull(contextData.NextContextData);
            contextData = context2.FirstContextData;
            Assert.IsNotNull(contextData);
            Assert.IsNotNull(contextData.PrevContextData);
            Assert.IsNull(contextData.NextContextData);
        }
コード例 #3
0
        private static void ExampleCKKSPerformanceDefault()
        {
            Utilities.PrintExampleBanner("CKKS Performance Test with Degrees: 4096, 8192, and 16384");

            // It is not recommended to use BFVDefault primes in CKKS. However, for performance
            // test, BFVDefault primes are good enough.
            EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
            ulong polyModulusDegree    = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            CKKSPerformanceTest(new SEALContext(parms));

            Console.WriteLine();
            polyModulusDegree       = 8192;
            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            CKKSPerformanceTest(new SEALContext(parms));

            Console.WriteLine();
            polyModulusDegree       = 16384;
            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            CKKSPerformanceTest(new SEALContext(parms));

            /*
             * Comment out the following to run the biggest example.
             */
            //Console.WriteLine();
            //polyModulusDegree = 32768;
            //parms.PolyModulusDegree = polyModulusDegree;
            //parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
            //CKKSPerformanceTest(new SEALContext(parms));
        }
コード例 #4
0
        private static void ExampleCKKSPerformanceCustom()
        {
            Console.Write("> Set PolyModulusDegree (1024, 2048, 4096, 8192, 16384, or 32768): ");
            string input = Console.ReadLine();

            if (!ulong.TryParse(input, out ulong polyModulusDegree))
            {
                Console.WriteLine("Invalid option.");
                return;
            }
            if (polyModulusDegree < 1024 || polyModulusDegree > 32768 ||
                (polyModulusDegree & (polyModulusDegree - 1)) != 0)
            {
                Console.WriteLine("Invalid option.");
                return;
            }

            string banner = $"CKKS Performance Test with Degree: {polyModulusDegree}";

            Utilities.PrintExampleBanner(banner);

            using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS)
                  {
                      PolyModulusDegree = polyModulusDegree,
                      CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree)
                  };

            using (SEALContext context = new SEALContext(parms))
            {
                CKKSPerformanceTest(context);
            }
        }
コード例 #5
0
        public ContextManager()
        {
            EncryptionParams = new EncryptionParameters(SchemeType.BFV);
            const ulong polyModulusDegree = 2048;

            EncryptionParams.PolyModulusDegree = polyModulusDegree;
            EncryptionParams.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            EncryptionParams.PlainModulus      = new Modulus(1024);
            Context = new SEALContext(EncryptionParams);
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: salrashid123/fhe
        public void generateKeys(int x, int y, string publicFile, string secretFile, string encryptedXFile, string encryptedYFile)
        {
            //Console.WriteLine("Rider at ({0},{1})",x,y);

            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(1024);


            using SEALContext context = new SEALContext(parms);
            //Console.WriteLine("Set encryption parameters and print");
            //Console.WriteLine(context);
            //Console.WriteLine("Parameter validation (success): {0}", context.ParameterErrorMessage());

            using KeyGenerator keygen = new KeyGenerator(context);

            using PublicKey riderPub = keygen.PublicKey;
            using SecretKey riderSec = keygen.SecretKey;


            using Evaluator evaluator    = new Evaluator(context);
            using IntegerEncoder encoder = new IntegerEncoder(context);

            using Encryptor riderEncryptor = new Encryptor(context, riderPub);
            using Decryptor riderDecryptor = new Decryptor(context, riderSec);

            using Plaintext riderxPlain      = encoder.Encode(x);
            using Plaintext rideryPlain      = encoder.Encode(y);
            using Ciphertext riderxEncrypted = new Ciphertext();
            using Ciphertext rideryEncrypted = new Ciphertext();
            riderEncryptor.Encrypt(riderxPlain, riderxEncrypted);
            riderEncryptor.Encrypt(rideryPlain, rideryEncrypted);

            var fileStream = File.Create(publicFile);

            riderPub.Save(fileStream);
            fileStream.Close();

            fileStream = File.Create(secretFile);
            riderSec.Save(fileStream);
            fileStream.Close();

            fileStream = File.Create(encryptedXFile);
            riderxEncrypted.Save(fileStream);
            fileStream.Close();

            fileStream = File.Create(encryptedYFile);
            rideryEncrypted.Save(fileStream);
            fileStream.Close();
        }
コード例 #7
0
        public void PropertiesTest()
        {
            SEALContext context = GlobalContext.BFVContext;

            Assert.IsTrue(context.FirstContextData.Qualifiers.ParametersSet);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingBatching);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingFastPlainLift);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingFFT);
            Assert.AreEqual(SecLevelType.TC128, context.FirstContextData.Qualifiers.SecLevel);
            Assert.IsFalse(context.FirstContextData.Qualifiers.UsingDescendingModulusChain);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingNTT);
            Assert.IsTrue(context.UsingKeyswitching);

            EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS)
            {
                PolyModulusDegree = 4096,
                CoeffModulus      = CoeffModulus.BFVDefault(4096)
            };

            SEALContext context2 = new SEALContext(parms);

            Assert.IsTrue(context2.FirstContextData.Qualifiers.ParametersSet);
            Assert.IsTrue(context2.FirstContextData.Qualifiers.UsingBatching);
            Assert.IsFalse(context2.FirstContextData.Qualifiers.UsingFastPlainLift);
            Assert.IsTrue(context2.FirstContextData.Qualifiers.UsingFFT);
            Assert.AreEqual(SecLevelType.TC128, context2.FirstContextData.Qualifiers.SecLevel);
            Assert.IsFalse(context.FirstContextData.Qualifiers.UsingDescendingModulusChain);
            Assert.IsTrue(context2.FirstContextData.Qualifiers.UsingNTT);
            Assert.IsTrue(context.UsingKeyswitching);

            EncryptionParameterQualifiers qualifiers = new EncryptionParameterQualifiers(context2.FirstContextData.Qualifiers);

            Assert.IsNotNull(qualifiers);
            Assert.IsTrue(qualifiers.ParametersSet);
            Assert.IsTrue(qualifiers.UsingBatching);
            Assert.IsFalse(qualifiers.UsingFastPlainLift);
            Assert.IsTrue(qualifiers.UsingFFT);
            Assert.AreEqual(SecLevelType.TC128, qualifiers.SecLevel);
            Assert.IsTrue(qualifiers.UsingDescendingModulusChain);
            Assert.IsTrue(qualifiers.UsingNTT);

            SEALContext context3 = GlobalContext.BGVContext;

            Assert.IsTrue(context.FirstContextData.Qualifiers.ParametersSet);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingBatching);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingFastPlainLift);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingFFT);
            Assert.AreEqual(SecLevelType.TC128, context.FirstContextData.Qualifiers.SecLevel);
            Assert.IsFalse(context.FirstContextData.Qualifiers.UsingDescendingModulusChain);
            Assert.IsTrue(context.FirstContextData.Qualifiers.UsingNTT);
            Assert.IsTrue(context.UsingKeyswitching);
        }
コード例 #8
0
 public EncounterContext()
 {
     @params = new EncryptionParameters(SchemeType.BFV)
     {
         PolyModulusDegree = polyModDeg,           // Must be a positive power of 2
         CoeffModulus      = CoeffModulus.BFVDefault(polyModDeg),
         PlainModulus      = new SmallModulus(256) // Try to keep this as small as possible
     };
     SealContext = new SEALContext(@params);
     KeyGen      = new KeyGenerator(SealContext);
     Decryptor   = new Decryptor(SealContext, KeyGen.SecretKey);
     Encryptor   = new Encryptor(SealContext, KeyGen.PublicKey);
 }
コード例 #9
0
        private static void ExampleBFVPerformanceDefault()
        {
            Utilities.PrintExampleBanner("BFV Performance Test with Degrees: 4096, 8192, and 16384");

            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(786433);
            using (SEALContext context = new SEALContext(parms))
            {
                BFVPerformanceTest(context);
            }

            Console.WriteLine();
            polyModulusDegree       = 8192;
            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(786433);
            using (SEALContext context = new SEALContext(parms))
            {
                BFVPerformanceTest(context);
            }

            Console.WriteLine();
            polyModulusDegree       = 16384;
            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(786433);
            using (SEALContext context = new SEALContext(parms))
            {
                BFVPerformanceTest(context);
            }

            /*
             * Comment out the following to run the biggest example.
             */
            //Console.WriteLine();
            //polyModulusDegree = 32768;
            //parms.PolyModulusDegree = polyModulusDegree;
            //parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
            //parms.PlainModulus = new Modulus(786433);
            //using (SEALContext context = new SEALContext(parms))
            //{
            //    BFVPerformanceTest(context);
            //}
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: salrashid123/fhe
        public void encryptDriverLocation(int x, int y, string publicFile, string encryptedXFile, string encryptedYFile)
        {
            //Console.WriteLine("Driver at ({0},{1})",x,y);

            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(1024);

            using SEALContext context = new SEALContext(parms);

            using KeyGenerator keygen = new KeyGenerator(context);

            using PublicKey riderPub = new PublicKey();


            using Ciphertext xEncrypted = new Ciphertext();
            using (var sr = new StreamReader(publicFile))
            {
                riderPub.Load(context, sr.BaseStream);
            }

            using Evaluator evaluator    = new Evaluator(context);
            using IntegerEncoder encoder = new IntegerEncoder(context);

            using Encryptor riderEncryptor = new Encryptor(context, riderPub);

            using Plaintext driverxPlain      = encoder.Encode(x);
            using Plaintext driveryPlain      = encoder.Encode(y);
            using Ciphertext driverxEncrypted = new Ciphertext();
            using Ciphertext driveryEncrypted = new Ciphertext();
            riderEncryptor.Encrypt(driverxPlain, driverxEncrypted);
            riderEncryptor.Encrypt(driveryPlain, driveryEncrypted);

            var fileStream = File.Create(encryptedXFile);

            driverxEncrypted.Save(fileStream);
            fileStream.Close();

            fileStream = File.Create(encryptedYFile);
            driveryEncrypted.Save(fileStream);
            fileStream.Close();
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: salrashid123/fhe
        public ulong decryptDistance(string publicFile, string secretFile, string distanceFile)
        {
            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(1024);

            using SEALContext context = new SEALContext(parms);

            using KeyGenerator keygen = new KeyGenerator(context);

            using PublicKey riderPub = new PublicKey();
            using (var sr = new StreamReader(publicFile))
            {
                riderPub.Load(context, sr.BaseStream);
            }

            using SecretKey riderSec = new SecretKey();
            using (var sr = new StreamReader(secretFile))
            {
                riderSec.Load(context, sr.BaseStream);
            }

            using Ciphertext X2MinusX1SquaredPlusY2MinusY1Squared = new Ciphertext();
            using (var sr = new StreamReader(distanceFile))
            {
                X2MinusX1SquaredPlusY2MinusY1Squared.Load(context, sr.BaseStream);
            }

            using Encryptor riderEncryptor = new Encryptor(context, riderPub);
            using Decryptor riderDecryptor = new Decryptor(context, riderSec);


            using Plaintext distance = new Plaintext();
            riderDecryptor.Decrypt(X2MinusX1SquaredPlusY2MinusY1Squared, distance);

            using IntegerEncoder encoder = new IntegerEncoder(context);

            //Console.WriteLine("Decrypted polynomial f(x) = {0}.", distance );
            //Console.WriteLine("     distance from rider {0}", encoder.DecodeUInt64(distance));
            return(encoder.DecodeUInt64(distance));
        }
コード例 #12
0
        public void CoeffModulusTest()
        {
            EncryptionParameters encParams = new EncryptionParameters(SchemeType.BFV);

            Assert.IsNotNull(encParams);

            List <SmallModulus> coeffs = new List <SmallModulus>(encParams.CoeffModulus);

            Assert.IsNotNull(coeffs);
            Assert.AreEqual(0, coeffs.Count);

            encParams.CoeffModulus = CoeffModulus.BFVDefault(4096);

            List <SmallModulus> newCoeffs = new List <SmallModulus>(encParams.CoeffModulus);

            Assert.IsNotNull(newCoeffs);
            Assert.AreEqual(3, newCoeffs.Count);
            Assert.AreEqual(0xffffee001ul, newCoeffs[0].Value);
            Assert.AreEqual(0xffffc4001ul, newCoeffs[1].Value);
            Assert.AreEqual(0x1ffffe0001ul, newCoeffs[2].Value);
        }
コード例 #13
0
ファイル: SealUtils.cs プロジェクト: relusion/HeVotingSystem
        public static SEALContext GetContext()
        {
            var encryptionParameters = new EncryptionParameters(SchemeType.BFV)
            {
                PolyModulusDegree = 32768,
                CoeffModulus      = CoeffModulus.BFVDefault(32768)
            };

            //encryptionParameters.PlainModulus = new Modulus(1024);

            /*
             * 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.
             */
            encryptionParameters.PlainModulus = PlainModulus.Batching(32768, 20);


            SEALContext new_context = new SEALContext(encryptionParameters);

            return(new_context);
        }
コード例 #14
0
        private static void ExampleBFVPerformanceCustom()
        {
            Console.Write("> Set PolyModulusDegree (1024, 2048, 4096, 8192, 16384, or 32768): ");
            string input = Console.ReadLine();

            if (!ulong.TryParse(input, out ulong polyModulusDegree))
            {
                Console.WriteLine("Invalid option.");
                return;
            }
            if (polyModulusDegree < 1024 || polyModulusDegree > 32768 ||
                (polyModulusDegree & (polyModulusDegree - 1)) != 0)
            {
                Console.WriteLine("Invalid option.");
                return;
            }

            string banner = $"BFV Performance Test with Degree: {polyModulusDegree}";

            Utilities.PrintExampleBanner(banner);

            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
            {
                PolyModulusDegree = polyModulusDegree,
                CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree)
            };

            if (polyModulusDegree == 1024)
            {
                parms.PlainModulus = new SmallModulus(12289);
            }
            else
            {
                parms.PlainModulus = new SmallModulus(786433);
            }
            BFVPerformanceTest(new SEALContext(parms));
        }
コード例 #15
0
ファイル: 2_Encoders.cs プロジェクト: philippejohns/SEAL
        /*
         * 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 scheme only)
             *
             * 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.
             */
            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.
             */
        }
コード例 #16
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 ExampleIntegerEncoder()
        {
            Utilities.PrintExampleBanner("Example: Encoders / Integer Encoder");

            /*
             * [IntegerEncoder] (For BFV scheme only)
             *
             * The IntegerEncoder encodes integers to BFV plaintext polynomials as follows.
             * First, a binary expansion of the integer is computed. Next, a polynomial is
             * created with the bits as coefficients. For example, the integer
             *
             *  26 = 2^4 + 2^3 + 2^1
             *
             * is encoded as the polynomial 1x^4 + 1x^3 + 1x^1. Conversely, plaintext
             * polynomials are decoded by evaluating them at x=2. For negative numbers the
             * IntegerEncoder simply stores all coefficients as either 0 or -1, where -1 is
             * represented by the unsigned integer PlainModulus - 1 in memory.
             *
             * Since encrypted computations operate on the polynomials rather than on the
             * encoded integers themselves, the polynomial coefficients will grow in the
             * course of such computations. For example, computing the sum of the encrypted
             * encoded integer 26 with itself will result in an encrypted polynomial with
             * larger coefficients: 2x^4 + 2x^3 + 2x^1. Squaring the encrypted encoded
             * integer 26 results also in increased coefficients due to cross-terms, namely,
             *
             *  (1x^4 + 1x^3 + 1x^1)^2 = 1x^8 + 2x^7 + 1x^6 + 2x^5 + 2x^4 + 1x^2;
             *
             * further computations will quickly increase the coefficients much more.
             * Decoding will still work correctly in this case (evaluating the polynomial
             * at x=2), but since the coefficients of plaintext polynomials are really
             * integers modulo plain_modulus, implicit reduction modulo plain_modulus may
             * yield unexpected results. For example, adding 1x^4 + 1x^3 + 1x^1 to itself
             * plain_modulus many times will result in the constant polynomial 0, which is
             * clearly not equal to 26 * plain_modulus. It can be difficult to predict when
             * such overflow will take place especially when computing several sequential
             * multiplications.
             *
             * The IntegerEncoder is easy to understand and use for simple computations,
             * and can be a good tool to experiment with for users new to Microsoft SEAL.
             * However, advanced users will probably prefer more efficient approaches,
             * such as the BatchEncoder or the CKKSEncoder.
             */
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree    = 4096;

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

            /*
             * There is no hidden logic behind our choice of the plain_modulus. The only
             * thing that matters is that the plaintext polynomial coefficients will not
             * exceed this value at any point during our computation; otherwise the result
             * will be incorrect.
             */
            parms.PlainModulus = new SmallModulus(512);
            SEALContext context = new SEALContext(parms);

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

            KeyGenerator keygen    = new KeyGenerator(context);
            PublicKey    publicKey = keygen.PublicKey;
            SecretKey    secretKey = keygen.SecretKey;
            Encryptor    encryptor = new Encryptor(context, publicKey);
            Evaluator    evaluator = new Evaluator(context);
            Decryptor    decryptor = new Decryptor(context, secretKey);

            /*
             * We create an IntegerEncoder.
             */
            IntegerEncoder encoder = new IntegerEncoder(context);

            /*
             * First, we encode two integers as plaintext polynomials. Note that encoding
             * is not encryption: at this point nothing is encrypted.
             */
            int       value1 = 5;
            Plaintext plain1 = encoder.Encode(value1);

            Utilities.PrintLine();
            Console.WriteLine($"Encode {value1} as polynomial {plain1} (plain1),");

            int       value2 = -7;
            Plaintext plain2 = encoder.Encode(value2);

            Console.WriteLine(new string(' ', 13)
                              + $"Encode {value2} as polynomial {plain2} (plain2),");

            /*
             * Now we can encrypt the plaintext polynomials.
             */
            Ciphertext encrypted1 = new Ciphertext();
            Ciphertext encrypted2 = new Ciphertext();

            Utilities.PrintLine();
            Console.WriteLine("Encrypt plain1 to encrypted1 and plain2 to encrypted2.");
            encryptor.Encrypt(plain1, encrypted1);
            encryptor.Encrypt(plain2, encrypted2);
            Console.WriteLine("    + Noise budget in encrypted1: {0} bits",
                              decryptor.InvariantNoiseBudget(encrypted1));
            Console.WriteLine("    + Noise budget in encrypted2: {0} bits",
                              decryptor.InvariantNoiseBudget(encrypted2));

            /*
             * As a simple example, we compute (-encrypted1 + encrypted2) * encrypted2.
             */
            encryptor.Encrypt(plain2, encrypted2);
            Ciphertext encryptedResult = new Ciphertext();

            Utilities.PrintLine();
            Console.WriteLine("Compute encrypted_result = (-encrypted1 + encrypted2) * encrypted2.");
            evaluator.Negate(encrypted1, encryptedResult);
            evaluator.AddInplace(encryptedResult, encrypted2);
            evaluator.MultiplyInplace(encryptedResult, encrypted2);
            Console.WriteLine("    + Noise budget in encryptedResult: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedResult));

            Plaintext plainResult = new Plaintext();

            Utilities.PrintLine();
            Console.WriteLine("Decrypt encrypted_result to plain_result.");
            decryptor.Decrypt(encryptedResult, plainResult);

            /*
             * Print the result plaintext polynomial. The coefficients are not even close
             * to exceeding our plainModulus, 512.
             */
            Console.WriteLine($"    + Plaintext polynomial: {plainResult}");

            /*
             * Decode to obtain an integer result.
             */
            Utilities.PrintLine();
            Console.WriteLine("Decode plain_result.");
            Console.WriteLine("    + Decoded integer: {0} ...... Correct.",
                              encoder.DecodeInt32(plainResult));
        }
コード例 #17
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.
             */
        }
コード例 #18
0
        static async Task RunAsync()
        {
            // Update port # in the following line.
            client.BaseAddress = new Uri("http://localhost/");
            //client.BaseAddress = new Uri("https://sealserver20200623225403.azurewebsites.net/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/octet-stream"));
            UriBuilder builder = new UriBuilder();

            builder.Port = 50755;
            builder.Path = "sealoperation";
            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree   = polyModulusDegree;
            parms.CoeffModulus        = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus        = new Modulus(4096);
            using SEALContext context = new SEALContext(parms);
            using Evaluator evaluator = new Evaluator(context);
            using KeyGenerator keygen = new KeyGenerator(context);
            using PublicKey publicKey = keygen.PublicKey;
            using SecretKey secretKey = keygen.SecretKey;
            using Encryptor encryptor = new Encryptor(context, publicKey);
            using Decryptor decryptor = new Decryptor(context, secretKey);


            //BigInteger bint = BigInteger.Parse("97391909619002370737223511047161666878854921822310726371156754097341907215981");
            BigInteger bint = BigInteger.Parse("998745113");
            //int xVal = 625;
            //int degree = 10;
            //int coeff = 25;
            // These are good starting points for small numbers < 100mil

            /*
             * int tConst = 121;
             * int xVal = 10;
             * int degree = 2;
             * int coeff = 3;
             */
            int tConst = 1210;
            int xVal   = 25;
            int degree = 4;
            int coeff  = 3;


            // Candidate first result from initial polynomial
            List <int> terms;
            BigInteger res = createBigIntFromPoly(degree, coeff, xVal, tConst, out terms);

            // compare res to target BigInteger, if way smaller, then create a new
            // result after increasing any of the polynomial values
            while (BigInteger.Compare(res, bint) < 0) // res is less than bint
            {
                BigInteger halfVal    = BigInteger.Divide(bint, new BigInteger(2));
                BigInteger onePercent = BigInteger.Divide(bint, new BigInteger(100));
                BigInteger tenPercent = BigInteger.Multiply(onePercent, new BigInteger(10));
                //BigInteger quarterVal = BigInteger.Divide(bint, new BigInteger(4));
                if (BigInteger.Compare(halfVal, res) > 0)
                {
                    //coeff += 1;
                    int len  = halfVal.ToString().Length;
                    int len2 = res.ToString().Length;
                    if (len == len2)
                    {
                        coeff *= 2;
                    }
                    else
                    {
                        degree += 2;
                    }
                    res = createBigIntFromPoly(degree, coeff, xVal, tConst, out terms);
                }
                else
                {
                    BigInteger difference = BigInteger.Subtract(bint, res);
                    if (BigInteger.Compare(tenPercent, difference) > 0)
                    {
                        tConst += 1111;
                    }
                    else
                    {
                        coeff += 1;
                    }
                    res = createBigIntFromPoly(degree, coeff, xVal, tConst, out terms);
                }
                //Console.WriteLine(res.ToString());
                Console.WriteLine("...");
            }
            // Res is now equal or greater to bint
            tConst = tConst - (int)BigInteger.Subtract(res, bint);
            // Now check the polynomial
            BigInteger testPoly = createBigIntFromPoly(degree, coeff, xVal, tConst, out terms);

            Console.WriteLine("For Big Integer {0}", bint.ToString());
            foreach (int term in terms)
            {
                Console.WriteLine("Polynomial term is {0}x^{1}", coeff, term);
            }
            Console.WriteLine("Final term is constant {0} with x={1}", tConst, xVal);
            byte[] bytespan = bint.ToByteArray();
            byte[] newspan  = new byte[bytespan.Length];
            newspan[0] = bytespan[0];
            BigInteger binttemp = new BigInteger(bytespan);
            // Pick an 'x' value for the polynomial that is big enough to represent the upper 10 digits of the value
            BigInteger bint2   = BigInteger.Parse("7983012132846067729184195556448685457666384473549591845215215701504271855338012801306119587019479688581971723759499902125851173348207536911525267617909811");
            BigInteger bintres = bint * bint2;

            using Plaintext bPlainB = new Plaintext(bint.ToString());
            int x = 9;

            Console.WriteLine("Plain x value to set");
            Console.WriteLine(x.ToString());
            using Plaintext xPlainX = new Plaintext(Convert.ToString(x, 16));
            Console.WriteLine("Hex value being set");
            Console.WriteLine(xPlainX.ToString());
            using Ciphertext xEncrypted = new Ciphertext();
            Console.WriteLine("Encrypt xPlain to xEncrypted.");
            encryptor.Encrypt(xPlainX, xEncrypted);
            int y = 5;

            Console.WriteLine("Plain y value to set");
            Console.WriteLine(y.ToString());
            using Plaintext xPlainY = new Plaintext(Convert.ToString(y, 16));
            Console.WriteLine("Hex y value being set");
            Console.WriteLine(xPlainY.ToString());
            using Ciphertext yEncrypted = new Ciphertext();
            encryptor.Encrypt(xPlainY, yEncrypted);

            FHEParams fHEParams = new FHEParams();

            fHEParams.param1 = xEncrypted;
            fHEParams.param2 = yEncrypted;
            fHEParams.result = new Ciphertext();
            // DEBUG ONLY
            Ciphertext mAnswer = new Ciphertext();

            evaluator.Multiply(fHEParams.param1, fHEParams.param2, mAnswer);
            evaluator.Add(fHEParams.param1, fHEParams.param2, fHEParams.result);
            string expAnswer = SerializeSEAL(fHEParams.result);

            using Plaintext xDecrypted2 = new Plaintext();
            decryptor.Decrypt(mAnswer, xDecrypted2);
            Console.WriteLine(xDecrypted2.ToString());
            decryptor.Decrypt(fHEParams.result, xDecrypted2);
            string answer = xDecrypted2.ToString();
            int    num    = 0;

            Int32.TryParse(answer, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num);
            Console.WriteLine("Local answer");
            Console.WriteLine(answer);
            Console.WriteLine(num.ToString());

            // END DEBUG

            //fHEParams.param1.

            fHEParams.operation = "add";

            SEALTransport transport = new SEALTransport();

            transport.ContextParams = SerializeSEAL(parms);

            transport.FHEParam1 = SerializeSEAL(fHEParams.param1);
            // Console.WriteLine(transport.FHEParam1);
            transport.FHEParam2 = SerializeSEAL(fHEParams.param2);
            transport.FHEResult = SerializeSEAL(fHEParams.result);
            transport.Operation = fHEParams.operation;

            try
            {
                // Get the parameters,
                SEALTransport response = await PostFHEResultAsync(builder.Uri.AbsoluteUri, transport);

                Ciphertext result    = new Ciphertext();
                byte[]     fp1       = System.Convert.FromBase64String(response.FHEResult);
                string     recAnswer = response.FHEResult;
                if (expAnswer == recAnswer)
                {
                    Console.WriteLine("Expected answer matches received answer");
                }
                MemoryStream mst = new MemoryStream(fp1);
                result.Load(context, mst);
                Plaintext xDecrypted3 = new Plaintext();
                decryptor.Decrypt(result, xDecrypted3);
                answer = xDecrypted3.ToString();
                Console.WriteLine(answer);
                Console.WriteLine("Remote Decimal answer");
                Int32.TryParse(answer, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num);
                Console.WriteLine(num.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadLine();
        }
コード例 #19
0
ファイル: 1_BFV_Basics.cs プロジェクト: eshnil2000/bootcamp
        private static void ExampleBFVBasics()
        {
            Utilities.PrintExampleBanner("Example: BFV Basics");

            /*
             * In this example, we demonstrate performing simple computations (a polynomial
             * evaluation) on encrypted integers using the BFV encryption scheme.
             *
             * The first task is to set up an instance of the EncryptionParameters class.
             * It is critical to understand how the different parameters behave, how they
             * affect the encryption scheme, performance, and the security level. There are
             * three encryption parameters that are necessary to set:
             *
             *  - PolyModulusDegree (degree of polynomial modulus);
             *  - CoeffModulus ([ciphertext] coefficient modulus);
             *  - PlainModulus (plaintext modulus; only for the BFV scheme).
             *
             * The BFV scheme cannot perform arbitrary computations on encrypted data.
             * Instead, each ciphertext has a specific quantity called the `invariant noise
             * budget' -- or `noise budget' for short -- measured in bits. The noise budget
             * in a freshly encrypted ciphertext (initial noise budget) is determined by
             * the encryption parameters. Homomorphic operations consume the noise budget
             * at a rate also determined by the encryption parameters. In BFV the two basic
             * operations allowed on encrypted data are additions and multiplications, of
             * which additions can generally be thought of as being nearly free in terms of
             * noise budget consumption compared to multiplications. Since noise budget
             * consumption compounds in sequential multiplications, the most significant
             * factor in choosing appropriate encryption parameters is the multiplicative
             * depth of the arithmetic circuit that the user wants to evaluate on encrypted
             * data. Once the noise budget of a ciphertext reaches zero it becomes too
             * corrupted to be decrypted. Thus, it is essential to choose the parameters to
             * be large enough to support the desired computation; otherwise the result is
             * impossible to make sense of even with the secret key.
             */
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            /*
             * The first parameter we set is the degree of the `polynomial modulus'. This
             * must be a positive power of 2, representing the degree of a power-of-two
             * cyclotomic polynomial; it is not necessary to understand what this means.
             *
             * Larger PolyModulusDegree makes ciphertext sizes larger and all operations
             * slower, but enables more complicated encrypted computations. Recommended
             * values are 1024, 2048, 4096, 8192, 16384, 32768, but it is also possible
             * to go beyond this range.
             *
             * In this example we use a relatively small polynomial modulus. Anything
             * smaller than this will enable only very restricted encrypted computations.
             */
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;

            /*
             * Next we set the [ciphertext] `coefficient modulus' (CoeffModulus). This
             * parameter is a large integer, which is a product of distinct prime numbers,
             * numbers, each represented by an instance of the SmallModulus class. The
             * bit-length of CoeffModulus means the sum of the bit-lengths of its prime
             * factors.
             *
             * A larger CoeffModulus implies a larger noise budget, hence more encrypted
             * computation capabilities. However, an upper bound for the total bit-length
             * of the CoeffModulus is determined by the PolyModulusDegree, as follows:
             *
             +----------------------------------------------------+
             | PolyModulusDegree   | max CoeffModulus bit-length  |
             +---------------------+------------------------------+
             | 1024                | 27                           |
             | 2048                | 54                           |
             | 4096                | 109                          |
             | 8192                | 218                          |
             | 16384               | 438                          |
             | 32768               | 881                          |
             +---------------------+------------------------------+
             |
             | These numbers can also be found in native/src/seal/util/hestdparms.h encoded
             | in the function SEAL_HE_STD_PARMS_128_TC, and can also be obtained from the
             | function
             |
             |  CoeffModulus.MaxBitCount(polyModulusDegree).
             |
             | For example, if PolyModulusDegree is 4096, the coeff_modulus could consist
             | of three 36-bit primes (108 bits).
             |
             | Microsoft SEAL comes with helper functions for selecting the CoeffModulus.
             | For new users the easiest way is to simply use
             |
             |  CoeffModulus.BFVDefault(polyModulusDegree),
             |
             | which returns IEnumerable<SmallModulus> consisting of a generally good choice
             | for the given PolyModulusDegree.
             */
            parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);

            /*
             * The plaintext modulus can be any positive integer, even though here we take
             * it to be a power of two. In fact, in many cases one might instead want it
             * to be a prime number; we will see this in later examples. The plaintext
             * modulus determines the size of the plaintext data type and the consumption
             * of noise budget in multiplications. Thus, it is essential to try to keep the
             * plaintext data type as small as possible for best performance. The noise
             * budget in a freshly encrypted ciphertext is
             *
             *  ~ log2(CoeffModulus/PlainModulus) (bits)
             *
             * and the noise budget consumption in a homomorphic multiplication is of the
             * form log2(PlainModulus) + (other terms).
             *
             * The plaintext modulus is specific to the BFV scheme, and cannot be set when
             * using the CKKS scheme.
             */
            parms.PlainModulus = new SmallModulus(1024);

            /*
             * Now that all parameters are set, we are ready to construct a SEALContext
             * object. This is a heavy class that checks the validity and properties of the
             * parameters we just set.
             */
            SEALContext context = new SEALContext(parms);

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

            Console.WriteLine();
            Console.WriteLine("~~~~~~ A naive way to calculate 4(x^2+1)(x+1)^2. ~~~~~~");

            /*
             * The encryption schemes in Microsoft SEAL are public key encryption schemes.
             * For users unfamiliar with this terminology, a public key encryption scheme
             * has a separate public key for encrypting data, and a separate secret key for
             * decrypting data. This way multiple parties can encrypt data using the same
             * shared public key, but only the proper recipient of the data can decrypt it
             * with the secret key.
             *
             * We are now ready to generate the secret and public keys. For this purpose
             * we need an instance of the KeyGenerator class. Constructing a KeyGenerator
             * automatically generates the public and secret key, which can immediately be
             * read to local variables.
             */
            KeyGenerator keygen    = new KeyGenerator(context);
            PublicKey    publicKey = keygen.PublicKey;
            SecretKey    secretKey = keygen.SecretKey;

            /*
             * To be able to encrypt we need to construct an instance of Encryptor. Note
             * that the Encryptor only requires the public key, as expected.
             */
            Encryptor encryptor = new Encryptor(context, publicKey);

            /*
             * Computations on the ciphertexts are performed with the Evaluator class. In
             * a real use-case the Evaluator would not be constructed by the same party
             * that holds the secret key.
             */
            Evaluator evaluator = new Evaluator(context);

            /*
             * We will of course want to decrypt our results to verify that everything worked,
             * so we need to also construct an instance of Decryptor. Note that the Decryptor
             * requires the secret key.
             */
            Decryptor decryptor = new Decryptor(context, secretKey);

            /*
             * As an example, we evaluate the degree 4 polynomial
             *
             *  4x^4 + 8x^3 + 8x^2 + 8x + 4
             *
             * over an encrypted x = 6. The coefficients of the polynomial can be considered
             * as plaintext inputs, as we will see below. The computation is done modulo the
             * plain_modulus 1024.
             *
             * While this examples is simple and easy to understand, it does not have much
             * practical value. In later examples we will demonstrate how to compute more
             * efficiently on encrypted integers and real or complex numbers.
             *
             * Plaintexts in the BFV scheme are polynomials of degree less than the degree
             * of the polynomial modulus, and coefficients integers modulo the plaintext
             * modulus. For readers with background in ring theory, the plaintext space is
             * the polynomial quotient ring Z_T[X]/(X^N + 1), where N is PolyModulusDegree
             * and T is PlainModulus.
             *
             * To get started, we create a plaintext containing the constant 6. For the
             * plaintext element we use a constructor that takes the desired polynomial as
             * a string with coefficients represented as hexadecimal numbers.
             */
            Utilities.PrintLine();
            int       x      = 6;
            Plaintext xPlain = new Plaintext(x.ToString());

            Console.WriteLine($"Express x = {x} as a plaintext polynomial 0x{xPlain}.");

            /*
             * We then encrypt the plaintext, producing a ciphertext.
             */
            Utilities.PrintLine();
            Ciphertext xEncrypted = new Ciphertext();

            Console.WriteLine("Encrypt xPlain to xEncrypted.");
            encryptor.Encrypt(xPlain, xEncrypted);

            /*
             * In Microsoft SEAL, a valid ciphertext consists of two or more polynomials
             * whose coefficients are integers modulo the product of the primes in the
             * coeff_modulus. The number of polynomials in a ciphertext is called its `size'
             * and is given by Ciphertext.Size. A freshly encrypted ciphertext always has
             * size 2.
             */
            Console.WriteLine($"    + size of freshly encrypted x: {xEncrypted.Size}");

            /*
             * There is plenty of noise budget left in this freshly encrypted ciphertext.
             */
            Console.WriteLine("    + noise budget in freshly encrypted x: {0} bits",
                              decryptor.InvariantNoiseBudget(xEncrypted));

            /*
             * We decrypt the ciphertext and print the resulting plaintext in order to
             * demonstrate correctness of the encryption.
             */
            Plaintext xDecrypted = new Plaintext();

            Console.Write("    + decryption of encrypted_x: ");
            decryptor.Decrypt(xEncrypted, xDecrypted);
            Console.WriteLine($"0x{xDecrypted} ...... Correct.");

            /*
             * When using Microsoft SEAL, it is typically advantageous to compute in a way
             * that minimizes the longest chain of sequential multiplications. In other
             * words, encrypted computations are best evaluated in a way that minimizes
             * the multiplicative depth of the computation, because the total noise budget
             * consumption is proportional to the multiplicative depth. For example, for
             * our example computation it is advantageous to factorize the polynomial as
             *
             *  4x^4 + 8x^3 + 8x^2 + 8x + 4 = 4(x + 1)^2 * (x^2 + 1)
             *
             * to obtain a simple depth 2 representation. Thus, we compute (x + 1)^2 and
             * (x^2 + 1) separately, before multiplying them, and multiplying by 4.
             *
             * First, we compute x^2 and add a plaintext "1". We can clearly see from the
             * print-out that multiplication has consumed a lot of noise budget. The user
             * can vary the plain_modulus parameter to see its effect on the rate of noise
             * budget consumption.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute xSqPlusOne (x^2+1).");
            Ciphertext xSqPlusOne = new Ciphertext();

            evaluator.Square(xEncrypted, xSqPlusOne);
            Plaintext plainOne = new Plaintext("1");

            evaluator.AddPlainInplace(xSqPlusOne, plainOne);

            /*
             * Encrypted 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. In this
             * case we perform a squaring, and observe both size growth and noise budget
             * consumption.
             */
            Console.WriteLine($"    + size of xSqPlusOne: {xSqPlusOne.Size}");
            Console.WriteLine("    + noise budget in xSqPlusOne: {0} bits",
                              decryptor.InvariantNoiseBudget(xSqPlusOne));

            /*
             * Even though the size has grown, decryption works as usual as long as noise
             * budget has not reached 0.
             */
            Plaintext decryptedResult = new Plaintext();

            Console.Write("    + decryption of xSqPlusOne: ");
            decryptor.Decrypt(xSqPlusOne, decryptedResult);
            Console.WriteLine($"0x{decryptedResult} ...... Correct.");

            /*
             * Next, we compute (x + 1)^2.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute xPlusOneSq ((x+1)^2).");
            Ciphertext xPlusOneSq = new Ciphertext();

            evaluator.AddPlain(xEncrypted, plainOne, xPlusOneSq);
            evaluator.SquareInplace(xPlusOneSq);
            Console.WriteLine($"    + size of xPlusOneSq: {xPlusOneSq.Size}");
            Console.WriteLine("    + noise budget in xPlusOneSq: {0} bits",
                              decryptor.InvariantNoiseBudget(xPlusOneSq));
            Console.Write("    + decryption of xPlusOneSq: ");
            decryptor.Decrypt(xPlusOneSq, decryptedResult);
            Console.WriteLine($"0x{decryptedResult} ...... Correct.");

            /*
             * Finally, we multiply (x^2 + 1) * (x + 1)^2 * 4.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute encryptedResult (4(x^2+1)(x+1)^2).");
            Ciphertext encryptedResult = new Ciphertext();
            Plaintext  plainFour       = new Plaintext("4");

            evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour);
            evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult);
            Console.WriteLine($"    + size of encrypted_result: {encryptedResult.Size}");
            Console.WriteLine("    + noise budget in encrypted_result: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedResult));
            Console.WriteLine("NOTE: Decryption can be incorrect if noise budget is zero.");

            Console.WriteLine();
            Console.WriteLine("~~~~~~ A better way to calculate 4(x^2+1)(x+1)^2. ~~~~~~");

            /*
             * Noise budget has reached 0, which means that decryption cannot be expected
             * to give the correct result. This is because both ciphertexts xSqPlusOne and
             * xPlusOneSq consist of 3 polynomials due to the previous squaring operations,
             * and homomorphic operations on large ciphertexts consume much more noise budget
             * than computations on small ciphertexts. Computing on smaller ciphertexts is
             * also computationally significantly cheaper.
             *
             * `Relinearization' is an operation that reduces the size of a ciphertext after
             * multiplication back to the initial size, 2. Thus, relinearizing one or both
             * input ciphertexts before the next multiplication can have a huge positive
             * impact on both noise growth and performance, even though relinearization has
             * a significant computational cost itself. It is only possible to relinearize
             * size 3 ciphertexts down to size 2, so often the user would want to relinearize
             * after each multiplication to keep the ciphertext sizes at 2.
             *
             * Relinearization requires special `relinearization keys', which can be thought
             * of as a kind of public key. Relinearization keys can easily be created with
             * the KeyGenerator.
             *
             * Relinearization is used similarly in both the BFV and the CKKS schemes, but
             * in this example we continue using BFV. We repeat our computation from before,
             * but this time relinearize after every multiplication.
             *
             * We use KeyGenerator.RelinKeys() to create relinearization keys.
             */
            Utilities.PrintLine();
            Console.WriteLine("Generate relinearization keys.");
            RelinKeys relinKeys = keygen.RelinKeys();

            /*
             * We now repeat the computation relinearizing after each multiplication.
             */
            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize xSquared (x^2),");
            Console.WriteLine(new string(' ', 13) + "then compute xSqPlusOne (x^2+1)");
            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);
            evaluator.AddPlain(xSquared, plainOne, xSqPlusOne);
            Console.WriteLine("    + noise budget in xSqPlusOne: {0} bits",
                              decryptor.InvariantNoiseBudget(xSqPlusOne));
            Console.Write("    + decryption of xSqPlusOne: ");
            decryptor.Decrypt(xSqPlusOne, decryptedResult);
            Console.WriteLine($"0x{decryptedResult} ...... Correct.");

            Utilities.PrintLine();
            Ciphertext xPlusOne = new Ciphertext();

            Console.WriteLine("Compute xPlusOne (x+1),");
            Console.WriteLine(new string(' ', 13) +
                              "then compute and relinearize xPlusOneSq ((x+1)^2).");
            evaluator.AddPlain(xEncrypted, plainOne, xPlusOne);
            evaluator.Square(xPlusOne, xPlusOneSq);
            Console.WriteLine($"    + size of xPlusOneSq: {xPlusOneSq.Size}");
            evaluator.RelinearizeInplace(xPlusOneSq, relinKeys);
            Console.WriteLine("    + noise budget in xPlusOneSq: {0} bits",
                              decryptor.InvariantNoiseBudget(xPlusOneSq));
            Console.Write("    + decryption of xPlusOneSq: ");
            decryptor.Decrypt(xPlusOneSq, decryptedResult);
            Console.WriteLine($"0x{decryptedResult} ...... Correct.");

            Utilities.PrintLine();
            Console.WriteLine("Compute and relinearize encryptedResult (4(x^2+1)(x+1)^2).");
            evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour);
            evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult);
            Console.WriteLine($"    + size of encryptedResult: {encryptedResult.Size}");
            evaluator.RelinearizeInplace(encryptedResult, relinKeys);
            Console.WriteLine("    + size of encryptedResult (after relinearization): {0}",
                              encryptedResult.Size);
            Console.WriteLine("    + noise budget in encryptedResult: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedResult));

            Console.WriteLine();
            Console.WriteLine("NOTE: Notice the increase in remaining noise budget.");

            /*
             * Relinearization clearly improved our noise consumption. We have still plenty
             * of noise budget left, so we can expect the correct answer when decrypting.
             */
            Utilities.PrintLine();
            Console.WriteLine("Decrypt encrypted_result (4(x^2+1)(x+1)^2).");
            decryptor.Decrypt(encryptedResult, decryptedResult);
            Console.WriteLine("    + decryption of 4(x^2+1)(x+1)^2 = 0x{0} ...... Correct.",
                              decryptedResult);

            /*
             * For x=6, 4(x^2+1)(x+1)^2 = 7252. Since the plaintext modulus is set to 1024,
             * this result is computed in integers modulo 1024. Therefore the expected output
             * should be 7252 % 1024 == 84, or 0x54 in hexadecimal.
             */
        }
コード例 #20
0
        public void Calculation(double step, int m, string func, TcpClient client)
        {
            Dispatcher.BeginInvoke(new ThreadStart(delegate {
                Canvas.Children.Clear();
                AxisInit(m);
            }));

            points = new List <List <Point> >();

            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            parms.PolyModulusDegree = 4096;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(4096);
            parms.PlainModulus      = new Modulus(4096);


            SEALContext  context   = new SEALContext(new EncryptionParameters(parms));
            KeyGenerator keygen    = new KeyGenerator(context);
            PublicKey    publicKey = keygen.PublicKey;
            SecretKey    secretKey = keygen.SecretKey;

            Encryptor encryptor = new Encryptor(context, publicKey);

            Decryptor decryptor = new Decryptor(context, secretKey);

            MemoryStream streamParms = new MemoryStream();
            MemoryStream streamSk    = new MemoryStream();

            secretKey.Save(streamSk);
            parms.Save(streamParms);

            byte[] spbuff = streamParms.GetBuffer();

            client.Client.Send(spbuff);

            byte[] count = Encoding.ASCII.GetBytes(Convert.ToInt32(Canvas.ActualWidth + step).ToString());
            client.Client.Send(count);

            byte[] func_buffer = Encoding.ASCII.GetBytes(func);
            client.Client.Send(func_buffer);

            byte[] offset_buffer = Encoding.ASCII.GetBytes((0).ToString());
            client.Client.Send(offset_buffer);

            int x = -(int)Canvas.ActualWidth / 2;

            for (int i = 0; i <= (int)(Canvas.ActualWidth / step); i += 1)
            {
                Plaintext data = new Plaintext();
                string    temp = (i).ToString();
                bool      sign;
                if (x >= 0)
                {
                    data = new Plaintext(x.ToString());
                    sign = false;
                }
                else
                {
                    data = new Plaintext(Math.Abs(x).ToString());
                    sign = true;
                }


                Ciphertext dataEncrypted = new Ciphertext();

                encryptor.Encrypt(data, dataEncrypted);


                byte[] sbuff;

                MemoryStream streamEncrypted = new MemoryStream();
                dataEncrypted.Save(streamEncrypted);
                sbuff = streamEncrypted.GetBuffer();

                client.Client.Send(sbuff);
                streamEncrypted.Close();


                byte[] bufferRecieved = new byte[9377792 * 2];
                dataEncrypted = new Ciphertext();

                client.Client.Receive(bufferRecieved);
                MemoryStream streamRecieved = new MemoryStream(bufferRecieved);
                Ciphertext   c = new Ciphertext();
                c.Load(context, streamRecieved);
                dataEncrypted = c;


                data = new Plaintext();
                decryptor.Decrypt(dataEncrypted, data);



                streamParms.Close();
                streamSk.Close();

                double f;
                string t = data.ToString();
                f = Convert.ToInt32(data.ToString(), 16);

                List <Point> p  = new List <Point>();
                int          ep = 0;
                Dispatcher.BeginInvoke(new ThreadStart(delegate { ep = (int)scale_bar.Maximum + 1; }));
                Thread.Sleep(10);

                if (sign)
                {
                    x = -Math.Abs(x);
                    //f = -Math.Abs(f);
                }

                for (int k = 1; k < ep; k++)
                {
                    //p.Add(new Point((i - (int)Canvas.ActualWidth / 2) * k, (f + Canvas.ActualHeight / 2) * k));
                    p.Add(new Point((x) * k + Canvas.ActualWidth / 2, f * k + Canvas.ActualHeight / 2));
                }

                points.Add(p);

                Dispatcher.BeginInvoke(new ThreadStart(delegate
                {
                    if (i > 1 && points.Count > 1 && i < points.Count)
                    {
                        Lines(points[i - 1][(int)(scale_bar.Value - 1)], points[i][(int)(scale_bar.Value - 1)]);
                    }
                }));

                if (x < Canvas.ActualWidth / 2)
                {
                    x += (int)step;
                }
            }

            client.Client.Disconnect(true);

            /////
            /////
            /////
            //for (int i = 0; i < points.Count - 1; i++)
            //{
            //    Lines(points[i][(int)(scale_bar.Value - 1)], points[i + 1][(int)(scale_bar.Value - 1)]);
            //}
            /////
            /////
            /////
        }
コード例 #21
0
        static void Main(string[] args)
        {
            EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);

            parms.PolyModulusDegree = 4096;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(4096);
            parms.PlainModulus      = new Modulus(4096 * 2);


            SEALContext context = new SEALContext(new EncryptionParameters(parms));

            Console.WriteLine(context.ParameterErrorMessage());
            KeyGenerator keygen    = new KeyGenerator(context);
            PublicKey    publicKey = new PublicKey(keygen.PublicKey);
            SecretKey    secretKey = new SecretKey(keygen.SecretKey);

            Encryptor encryptor = new Encryptor(context, publicKey);

            Evaluator evaluator = new Evaluator(context);

            Decryptor decryptor = new Decryptor(context, secretKey);


            Console.WriteLine("Generate locally usable relinearization keys.");
            using RelinKeys relinKeys = keygen.RelinKeysLocal();

            int x = 6;

            using Plaintext xPlain = new Plaintext(x.ToString());

            using Ciphertext xEncrypted = new Ciphertext();
            encryptor.Encrypt(xPlain, xEncrypted);
            using Ciphertext xSqPlusOne      = new Ciphertext();
            using Plaintext decryptedResult  = new Plaintext();
            using Ciphertext xPlusOneSq      = new Ciphertext();
            using Ciphertext encryptedResult = new Ciphertext();
            using Plaintext plainOne         = new Plaintext("1");
            using Plaintext plainFour        = new Plaintext("4");

            /*
             * We now repeat the computation relinearizing after each multiplication.
             */

            Console.WriteLine("Compute and relinearize xSquared (x^2),");
            Console.WriteLine(new string(' ', 13) + "then compute xSqPlusOne (x^2+1)");
            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);
            evaluator.AddPlain(xSquared, plainOne, xSqPlusOne);
            Console.WriteLine("    + noise budget in xSqPlusOne: {0} bits",
                              decryptor.InvariantNoiseBudget(xSqPlusOne));
            Console.Write("    + decryption of xSqPlusOne: ");
            decryptor.Decrypt(xSqPlusOne, decryptedResult);
            int q = Convert.ToInt32(decryptedResult.ToString(), 16);

            Console.WriteLine($"{q} ...... Correct.");
            //Console.WriteLine($"0x{decryptedResult} ...... Correct.");


            using Ciphertext xPlusOne = new Ciphertext();
            Console.WriteLine("Compute xPlusOne (x+1),");
            Console.WriteLine(new string(' ', 13) +
                              "then compute and relinearize xPlusOneSq ((x+1)^2).");
            evaluator.AddPlain(xEncrypted, plainOne, xPlusOne);
            evaluator.Square(xPlusOne, xPlusOneSq);
            Console.WriteLine($"    + size of xPlusOneSq: {xPlusOneSq.Size}");
            evaluator.RelinearizeInplace(xPlusOneSq, relinKeys);
            Console.WriteLine("    + noise budget in xPlusOneSq: {0} bits",
                              decryptor.InvariantNoiseBudget(xPlusOneSq));
            Console.Write("    + decryption of xPlusOneSq: ");
            decryptor.Decrypt(xPlusOneSq, decryptedResult);
            int r = Convert.ToInt32(decryptedResult.ToString(), 16);

            Console.WriteLine($"{r} ...... Correct.");


            Console.WriteLine("Compute and relinearize encryptedResult (4(x^2+1)(x+1)^2).");
            evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour);
            evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult);
            Console.WriteLine($"    + size of encryptedResult: {encryptedResult.Size}");
            evaluator.RelinearizeInplace(encryptedResult, relinKeys);
            Console.WriteLine("    + size of encryptedResult (after relinearization): {0}",
                              encryptedResult.Size);
            Console.WriteLine("    + noise budget in encryptedResult: {0} bits",
                              decryptor.InvariantNoiseBudget(encryptedResult));

            Console.WriteLine();
            Console.WriteLine("NOTE: Notice the increase in remaining noise budget.");

            /*
             * Relinearization clearly improved our noise consumption. We have still plenty
             * of noise budget left, so we can expect the correct answer when decrypting.
             */

            Console.WriteLine("Decrypt encrypted_result (4(x^2+1)(x+1)^2).");
            decryptor.Decrypt(encryptedResult, decryptedResult);
            int t = Convert.ToInt32(decryptedResult.ToString(), 16);

            Console.WriteLine("    + decryption of 4(x^2+1)(x+1)^2 = 0x{0} ...... Correct.", t);


            Plaintext  four           = new Plaintext("4");
            Plaintext  four1          = new Plaintext("5");
            Ciphertext fourEncrypted  = new Ciphertext();
            Ciphertext four1Encrypted = new Ciphertext();

            encryptor.Encrypt(four, fourEncrypted);
            encryptor.Encrypt(four1, four1Encrypted);

            Ciphertext d = new Ciphertext();

            evaluator.Sub(fourEncrypted, four1Encrypted, d);
            Plaintext temp = new Plaintext();

            decryptor.Decrypt(d, temp);

            Console.WriteLine($"{Convert.ToInt32(temp.ToString(), 16)}");
        }
コード例 #22
0
ファイル: Program.cs プロジェクト: salrashid123/fhe
        public void calculateDistance(string encryptedRiderXFile, string encryptedRiderYFile, string encryptedDriverXFile, string encryptedDriverYFile, string distanceFile)
        {
            using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
            ulong polyModulusDegree = 4096;

            parms.PolyModulusDegree = polyModulusDegree;
            parms.CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree);
            parms.PlainModulus      = new Modulus(1024);

            using SEALContext context = new SEALContext(parms);

            using KeyGenerator keygen = new KeyGenerator(context);

            using PublicKey riderPub = new PublicKey();


            using Ciphertext xRiderEncrypted = new Ciphertext();
            using (var sr = new StreamReader(encryptedRiderXFile))
            {
                xRiderEncrypted.Load(context, sr.BaseStream);
            }

            using Ciphertext yRiderEncrypted = new Ciphertext();
            using (var sr = new StreamReader(encryptedRiderYFile))
            {
                yRiderEncrypted.Load(context, sr.BaseStream);
            }

            using Ciphertext xDriverEncrypted = new Ciphertext();
            using (var sr = new StreamReader(encryptedDriverXFile))
            {
                xDriverEncrypted.Load(context, sr.BaseStream);
            }

            using Ciphertext yDriverEncrypted = new Ciphertext();
            using (var sr = new StreamReader(encryptedDriverYFile))
            {
                yDriverEncrypted.Load(context, sr.BaseStream);
            }

            //Console.WriteLine("Calculate ( (x2-x1)^2 + (y2-y1)^2 )");

            using Evaluator evaluator    = new Evaluator(context);
            using IntegerEncoder encoder = new IntegerEncoder(context);

            using RelinKeys relinKeys = keygen.RelinKeysLocal();

            using Ciphertext X2MinusX1 = new Ciphertext();
            evaluator.Sub(xDriverEncrypted, xRiderEncrypted, X2MinusX1);          // (x2-x1)

            using Ciphertext Y2MinusY1 = new Ciphertext();
            evaluator.Sub(yDriverEncrypted, yRiderEncrypted, Y2MinusY1);          // (y2-y1)

            using Ciphertext X2MinusX1Squared = new Ciphertext();
            evaluator.Square(X2MinusX1, X2MinusX1Squared);                        // (x2-x1)^2
            //evaluator.RelinearizeInplace(X2MinusX1Squared, relinKeys);

            using Ciphertext Y2MinusY1Squared = new Ciphertext();
            evaluator.Square(Y2MinusY1, Y2MinusY1Squared);                        // (x2-x1)^2
            //evaluator.RelinearizeInplace(Y2MinusY1Squared, relinKeys);

            using Ciphertext X2MinusX1SquaredPlusY2MinusY1Squared = new Ciphertext();
            evaluator.Add(X2MinusX1Squared, Y2MinusY1Squared, X2MinusX1SquaredPlusY2MinusY1Squared);   // (x2-x1)^2 + (y2-y1)^2

            // using Ciphertext SquareRootOfX2MinusX1SquaredPlusY2MinusY1Squared = new Ciphertext();
            // decimal vIn = 0.5M;
            // ulong vOut = Convert.ToUInt64(vIn);
            // evaluator.Exponentiate(X2MinusX1SquaredPlusY2MinusY1Squared, vOut,relinKeys,SquareRootOfX2MinusX1SquaredPlusY2MinusY1Squared);

            var fileStream = File.Create(distanceFile);

            X2MinusX1SquaredPlusY2MinusY1Squared.Save(fileStream);
            fileStream.Close();
        }
コード例 #23
0
        public static List <int> Run(ulong polyModulusDegree, ulong plainModulus, int[] xs, int[] ys)
        {
            // for communication between client and server
            var parmsStream     = new MemoryStream();
            var relinKeysStream = new MemoryStream();
            var dataStream      = new MemoryStream();
            var resultsStream   = new MemoryStream();

            // for client's internal use
            var secretKeyStream = new MemoryStream();

            {
                /*
                 * Client
                 */
                Console.WriteLine($"<Client> Client has {xs.Length} elements: [{string.Join(", ", xs)}].");
                using var parms = new EncryptionParameters(SchemeType.BFV)
                      {
                          PolyModulusDegree = polyModulusDegree,
                          CoeffModulus      = CoeffModulus.BFVDefault(polyModulusDegree),
                          PlainModulus      = new Modulus(plainModulus)
                      };

                using var context = new SEALContext(parms);

                using var keygen    = new KeyGenerator(context);
                using var secretKey = keygen.SecretKey;
                keygen.CreatePublicKey(out var publicKey);
                keygen.CreateRelinKeys(out var relinKeys);

                var writer = new BinaryWriter(dataStream);
                writer.Write((int)xs.Length);

                using var encryptor = new Encryptor(context, publicKey);

                for (int i = 0; i < xs.Length; i++)
                {
                    using var xPlain = new Plaintext(xs[i].ToString("X"));
                    encryptor.Encrypt(xPlain).Save(dataStream);
                }
                dataStream.Seek(0, SeekOrigin.Begin);

                parms.Save(parmsStream);
                parmsStream.Seek(0, SeekOrigin.Begin);

                relinKeys.Save(relinKeysStream);
                relinKeysStream.Seek(0, SeekOrigin.Begin);

                secretKey.Save(secretKeyStream);
                secretKeyStream.Seek(0, SeekOrigin.Begin);

                Console.WriteLine("----------------------");
            }
            {
                /*
                 * Server
                 */
                Console.WriteLine($"<Server> Server has {ys.Length} elements: [{string.Join(", ", ys)}].");

                using var parms = new EncryptionParameters();
                parms.Load(parmsStream);
                parmsStream.Seek(0, SeekOrigin.Begin);

                var plainModulusValue = (int)parms.PlainModulus.Value;

                using var context   = new SEALContext(parms);
                using var evaluator = new Evaluator(context);

                using var relinKeys = new RelinKeys();
                relinKeys.Load(context, relinKeysStream);

                var ysPlain = new Plaintext[ys.Length];
                for (int j = 0; j < ys.Length; j++)
                {
                    ysPlain[j] = new Plaintext(ys[j].ToString("X"));
                }

                var reader   = new BinaryReader(dataStream);
                int dataSize = reader.ReadInt32();

                var writer = new BinaryWriter(resultsStream);
                writer.Write((int)dataSize);

                var rnd = new Random();
                for (int i = 0; i < dataSize; i++)
                {
                    using var xEncrypted = new Ciphertext();
                    xEncrypted.Load(context, dataStream);

                    var tmpEncrypted = new Ciphertext[ys.Length];
                    for (int j = 0; j < ys.Length; j++)
                    {
                        tmpEncrypted[j] = new Ciphertext();
                        evaluator.SubPlain(xEncrypted, ysPlain[j], tmpEncrypted[j]);
                    }
                    using var plainRandomText = new Plaintext(rnd.Next(1, plainModulusValue).ToString("X"));

                    using var resultEncrypted = new Ciphertext();
                    evaluator.MultiplyMany(tmpEncrypted, relinKeys, resultEncrypted);
                    evaluator.MultiplyPlainInplace(resultEncrypted, plainRandomText);

                    resultEncrypted.Save(resultsStream);
                }
                resultsStream.Seek(0, SeekOrigin.Begin);

                Console.WriteLine("----------------------");
            }
            {
                /*
                 * Client
                 */
                using var parms = new EncryptionParameters();
                parms.Load(parmsStream);

                using var context = new SEALContext(parms);

                using var secretKey = new SecretKey();
                secretKey.Load(context, secretKeyStream);

                using var decryptor = new Decryptor(context, secretKey);

                var reader      = new BinaryReader(resultsStream);
                int resultsSize = reader.ReadInt32();


                List <int> intersection = new List <int>();
                for (int i = 0; i < resultsSize; i++)
                {
                    using var resultEncrypted = new Ciphertext();
                    resultEncrypted.Load(context, resultsStream);

                    var noiseBudget = decryptor.InvariantNoiseBudget(resultEncrypted);

                    if (noiseBudget > 0)
                    {
                        Console.WriteLine($"Noise: {noiseBudget} bits");
                        using var result = new Plaintext();
                        decryptor.Decrypt(resultEncrypted, result);
                        if (result.IsZero == true)
                        {
                            intersection.Add(xs[i]);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Ciphertext has too much noise.");
                    }
                }
                Console.WriteLine($"<Client> Intersection contains {intersection.Count} elements: [{string.Join(", ", intersection)}]");
                Console.WriteLine("----------------------");
                return(intersection);
            }
        }
コード例 #24
0
ファイル: 5_Rotation.cs プロジェクト: philippejohns/SEAL
        /*
         * 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.
             */
        }