public void BatchUnbatchPlaintextNET() { var parms = new EncryptionParameters(); parms.PolyModulus = "1x^64 + 1"; parms.CoeffModulus = new List <SmallModulus> { DefaultParams.SmallMods60Bit(0) }; parms.PlainModulus = 257; var context = new SEALContext(parms); Assert.IsTrue(context.Qualifiers.EnableBatching); var crtbuilder = new PolyCRTBuilder(context); Assert.AreEqual(64, crtbuilder.SlotCount); var plain = new Plaintext(crtbuilder.SlotCount); for (int i = 0; i < crtbuilder.SlotCount; i++) { plain[i] = (UInt64)i; } crtbuilder.Compose(plain); crtbuilder.Decompose(plain); for (int i = 0; i < crtbuilder.SlotCount; i++) { Assert.IsTrue(plain[i] == (UInt64)i); } for (int i = 0; i < crtbuilder.SlotCount; i++) { plain[i] = (UInt64)5; } crtbuilder.Compose(plain); Assert.IsTrue(plain.ToString().Equals("5")); crtbuilder.Decompose(plain); for (int i = 0; i < crtbuilder.SlotCount; i++) { Assert.IsTrue(plain[i] == (UInt64)5); } var short_plain = new Plaintext(20); for (int i = 0; i < 20; i++) { short_plain[i] = (UInt64)i; } crtbuilder.Compose(short_plain); crtbuilder.Decompose(short_plain); for (int i = 0; i < 20; i++) { Assert.IsTrue(short_plain[i] == (UInt64)i); } for (int i = 20; i < crtbuilder.SlotCount; i++) { Assert.IsTrue(short_plain[i] == 0UL); } }
public static void ExampleBatching() { PrintExampleBanner("Example: Batching using CRT"); // Create encryption parameters var parms = new EncryptionParameters(); /* * For PolyCRTBuilder it is necessary to have PlainModulus be a prime number congruent to 1 modulo * 2*degree(PolyModulus). We can use for example the following parameters: */ parms.SetPolyModulus("1x^4096 + 1"); parms.SetCoeffModulus(ChooserEvaluator.DefaultParameterOptions[4096]); parms.SetPlainModulus(40961); parms.Validate(); // Create the PolyCRTBuilder var crtbuilder = new PolyCRTBuilder(parms); int slotCount = crtbuilder.SlotCount; Console.WriteLine($"Encryption parameters allow {slotCount} slots."); // Create a list of values that are to be stored in the slots. We initialize all values to 0 at this point. var values = new List <BigUInt>(slotCount); for (int i = 0; i < slotCount; ++i) { values.Add(new BigUInt(parms.PlainModulus.BitCount, 0)); } // Set the first few entries of the values list to be non-zero values[0].Set(2); values[1].Set(3); values[2].Set(5); values[3].Set(7); values[4].Set(11); values[5].Set(13); // Now compose these into one polynomial using PolyCRTBuilder Console.Write("Plaintext slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + values[i].ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } var plainComposedPoly = crtbuilder.Compose(values); // Let's do some homomorphic operations now. First we need all the encryption tools. // Generate keys. Console.WriteLine("Generating keys ..."); var generator = new KeyGenerator(parms); generator.Generate(); Console.WriteLine("... key generation completed"); var publicKey = generator.PublicKey; var secretKey = generator.SecretKey; // Create the encryption tools var encryptor = new Encryptor(parms, publicKey); var evaluator = new Evaluator(parms); var decryptor = new Decryptor(parms, secretKey); // Encrypt plainComposed_poly Console.Write("Encrypting ... "); var encryptedComposedPoly = encryptor.Encrypt(plainComposedPoly); Console.WriteLine("done."); // Let's square and then decrypt the encryptedComposedPoly Console.Write("Squaring the encrypted polynomial ... "); var encryptedSquare = evaluator.Square(encryptedComposedPoly); Console.WriteLine("done."); Console.Write("Decrypting the squared polynomial ... "); var plainSquare = decryptor.Decrypt(encryptedSquare); Console.WriteLine("done."); // Print the squared slots crtbuilder.Decompose(plainSquare, values); Console.Write("Squared slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + values[i].ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // Now let's try to multiply the squares with the plaintext coefficients (3, 1, 4, 1, 5, 9, 0, 0, ..., 0). // First create the coefficient list var plainCoeffList = new List <BigUInt>(slotCount); for (int i = 0; i < slotCount; ++i) { plainCoeffList.Add(new BigUInt(parms.PlainModulus.BitCount, 0)); } plainCoeffList[0].Set(3); plainCoeffList[1].Set(1); plainCoeffList[2].Set(4); plainCoeffList[3].Set(1); plainCoeffList[4].Set(5); plainCoeffList[5].Set(9); // Use PolyCRTBuilder to compose plainCoeffList into a polynomial var plainCoeffPoly = crtbuilder.Compose(plainCoeffList); // Print the coefficient list Console.Write("Coefficient slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + plainCoeffList[i].ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // Now use MultiplyPlain to multiply each encrypted slot with the corresponding coefficient Console.Write("Multiplying squared slots with the coefficients ... "); var encryptedScaledSquare = evaluator.MultiplyPlain(encryptedSquare, plainCoeffPoly); Console.WriteLine(" done."); // Decrypt it Console.Write("Decrypting the scaled squared polynomial ... "); var plainScaledSquare = decryptor.Decrypt(encryptedScaledSquare); Console.WriteLine("done."); // Print the scaled squared slots crtbuilder.Decompose(plainScaledSquare, values); Console.Write("Scaled squared slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + values[i].ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // How much noise budget are we left with? Console.WriteLine("Noise budget in result: {0} bits", decryptor.InvariantNoiseBudget(encryptedScaledSquare)); }
public static void ExampleBatching() { PrintExampleBanner("Example: Batching using CRT"); // Create encryption parameters var parms = new EncryptionParameters(); /* * For PolyCRTBuilder we need to use a plain modulus congruent to 1 modulo 2*degree(PolyModulus), and * preferably a prime number. We could for example use the following parameters: * * parms.PolyModulus.Set("1x^2048 + 1"); * parms.CoeffModulus.Set(ChooserEvaluator.DefaultParameterOptions[2048]); * parms.PlainModulus.Set(12289); * * However, the primes suggested by ChooserEvaluator.DefaultParameterOptions are highly non-optimal in this * case. The reason is that the noise growth in many homomorphic operations depends on the remainder * CoeffModulus % PlainModulus, which is typically close to PlainModulus unless the parameters are carefully * chosen. The primes in ChooserEvaluator.DefaultParameterOptions are chosen so that this remainder is 1 * when PlainModulus is a (not too large) power of 2, so in the earlier examples this was not an issue. * However, here we are forced to take PlainModulus to be odd, and as a result the default parameters are no * longer optimal at all in this sense. * * Thus, for improved performance when using PolyCRTBuilder, we recommend the user to use their own * custom CoeffModulus. It should be a prime of the form 2^A - D, where D is as small as possible. * The PlainModulus should be simultaneously chosen to be a prime congruent to 1 modulo 2*degree(PolyModulus), * so that in addition CoeffModulus % PlainModulus is 1. Finally, CoeffModulus should be bounded by the * same strict upper bounds that were mentioned in ExampleBasics(): * /------------------------------------\ | PolyModulus | CoeffModulus bound | | -------------|---------------------| | 1x^1024 + 1 | 48 bits | | 1x^2048 + 1 | 96 bits | | 1x^4096 + 1 | 192 bits | | 1x^8192 + 1 | 384 bits | | 1x^16384 + 1 | 768 bits | \------------------------------------/ | | One issue with using such custom primes, however, is that they are never NTT primes, i.e. not congruent | to 1 modulo 2*degree(PolyModulus), and hence might not allow for certain optimizations to be used in | polynomial arithmetic. Another issue is that the search-to-decision reduction of RLWE does not apply to | non-NTT primes, but this is not known to result in any concrete reduction in the security level. | | In this example we use the prime 2^95 - 613077 as our coefficient modulus. The user should try switching | between this and ChooserEvaluator.DefaultParameterOptions[2048] to observe the difference in the noise | level at the end of the computation. This difference becomes significantly greater when using larger | values for PlainModulus. */ parms.PolyModulus.Set("1x^2048 + 1"); parms.CoeffModulus.Set("7FFFFFFFFFFFFFFFFFF6A52B"); //parms.CoeffModulus.Set(ChooserEvaluator.DefaultParameterOptions[2048]); parms.PlainModulus.Set(12289); Console.WriteLine("Encryption parameters specify {0} coefficients with {1} bits per coefficient", parms.PolyModulus.GetSignificantCoeffCount(), parms.CoeffModulus.GetSignificantBitCount()); // Create the PolyCRTBuilder var crtbuilder = new PolyCRTBuilder(parms.PlainModulus, parms.PolyModulus); int slotCount = crtbuilder.SlotCount; // Create a list of values that are to be stored in the slots. We initialize all values to 0 at this point. var values = new List <BigUInt>(slotCount); for (int i = 0; i < slotCount; ++i) { values.Add(new BigUInt(parms.PlainModulus.BitCount, 0)); } // Set the first few entries of the values list to be non-zero values[0].Set(2); values[1].Set(3); values[2].Set(5); values[3].Set(7); values[4].Set(11); values[5].Set(13); // Now compose these into one polynomial using PolyCRTBuilder Console.Write("Plaintext slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + values[i].ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } var plainComposedPoly = crtbuilder.Compose(values); // Let's do some homomorphic operations now. First we need all the encryption tools. // Generate keys. Console.WriteLine("Generating keys..."); var generator = new KeyGenerator(parms); generator.Generate(); Console.WriteLine("... key generation completed"); var publicKey = generator.PublicKey; var secretKey = generator.SecretKey; // Create the encryption tools var encryptor = new Encryptor(parms, publicKey); var evaluator = new Evaluator(parms); var decryptor = new Decryptor(parms, secretKey); // Encrypt plainComposed_poly Console.Write("Encrypting ... "); var encryptedComposedPoly = encryptor.Encrypt(plainComposedPoly); Console.WriteLine("done."); // Let's square and then decrypt the encryptedComposedPoly Console.Write("Squaring the encrypted polynomial ... "); var encryptedSquare = evaluator.Exponentiate(encryptedComposedPoly, 2); Console.WriteLine("done."); Console.Write("Decrypting the squared polynomial ... "); var plainSquare = decryptor.Decrypt(encryptedSquare); Console.WriteLine("done."); // Print the squared slots Console.Write("Squared slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + crtbuilder.GetSlot(plainSquare, i).ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // Now let's try to multiply the squares with the plaintext coefficients (3, 1, 4, 1, 5, 9, 0, 0, ..., 0). // First create the coefficient list var plainCoeffList = new List <BigUInt>(slotCount); for (int i = 0; i < slotCount; ++i) { plainCoeffList.Add(new BigUInt(parms.PlainModulus.BitCount, 0)); } plainCoeffList[0].Set(3); plainCoeffList[1].Set(1); plainCoeffList[2].Set(4); plainCoeffList[3].Set(1); plainCoeffList[4].Set(5); plainCoeffList[5].Set(9); // Use PolyCRTBuilder to compose plainCoeffList into a polynomial var plainCoeffPoly = crtbuilder.Compose(plainCoeffList); // Print the coefficient list Console.Write("Coefficient slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + crtbuilder.GetSlot(plainCoeffPoly, i).ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // Now use MultiplyPlain to multiply each encrypted slot with the corresponding coefficient Console.Write("Multiplying squared slots with the coefficients ... "); var encryptedScaledSquare = evaluator.MultiplyPlain(encryptedSquare, plainCoeffPoly); Console.WriteLine(" done."); // Decrypt it Console.Write("Decrypting the scaled squared polynomial ... "); var plainScaledSquare = decryptor.Decrypt(encryptedScaledSquare); Console.WriteLine("done."); // Print the scaled squared slots Console.Write("Scaled squared slot contents (slot, value): "); for (int i = 0; i < 6; ++i) { string toWrite = "(" + i.ToString() + ", " + crtbuilder.GetSlot(plainScaledSquare, i).ToDecimalString() + ")"; toWrite += (i != 5) ? ", " : "\n"; Console.Write(toWrite); } // How much noise did we end up with? Console.WriteLine("Noise in the result: {0}/{1} bits", Utilities.InherentNoise(encryptedScaledSquare, parms, secretKey).GetSignificantBitCount(), Utilities.InherentNoiseMax(parms).GetSignificantBitCount()); }
public void BatchUnbatchIntVectorNET() { var parms = new EncryptionParameters(); parms.PolyModulus = "1x^64 + 1"; parms.CoeffModulus = new List <SmallModulus> { DefaultParams.SmallMods60Bit(0) }; parms.PlainModulus = 257; var context = new SEALContext(parms); Assert.IsTrue(context.Qualifiers.EnableBatching); var crtbuilder = new PolyCRTBuilder(context); Assert.AreEqual(64, crtbuilder.SlotCount); var plain_vec = new List <Int64>(); for (int i = 0; i < crtbuilder.SlotCount; i++) { plain_vec.Add((Int64)i * (1 - 2 * (i % 2))); } var plain = new Plaintext(); crtbuilder.Compose(plain_vec, plain); var plain_vec2 = new List <Int64>(); crtbuilder.Decompose(plain, plain_vec2); Assert.IsTrue(plain_vec.SequenceEqual(plain_vec2)); for (int i = 0; i < crtbuilder.SlotCount; i++) { plain_vec[i] = -5; } crtbuilder.Compose(plain_vec, plain); Assert.IsTrue(plain.ToString().Equals("FC")); crtbuilder.Decompose(plain, plain_vec2); Assert.IsTrue(plain_vec.SequenceEqual(plain_vec2)); var short_plain_vec = new List <Int64>(); for (int i = 0; i < 20; i++) { short_plain_vec.Add((Int64)i * (1 - 2 * (i % 2))); } crtbuilder.Compose(short_plain_vec, plain); var short_plain_vec2 = new List <Int64>(); crtbuilder.Decompose(plain, short_plain_vec2); Assert.AreEqual(20, short_plain_vec.Count); Assert.AreEqual(64, short_plain_vec2.Count); for (int i = 0; i < 20; i++) { Assert.AreEqual(short_plain_vec[i], short_plain_vec2[i]); } for (int i = 20; i < crtbuilder.SlotCount; i++) { Assert.AreEqual(0L, short_plain_vec2[i]); } }