public void BalancedEncodeDecodeInt64NET() { var modulus = new SmallModulus(0x10000); var encoder = new BalancedEncoder(modulus, 3, MemoryPoolHandle.New()); var poly = encoder.Encode(0L); Assert.AreEqual(0, poly.SignificantCoeffCount()); Assert.IsTrue(poly.IsZero); Assert.AreEqual(0L, encoder.DecodeInt64(poly)); var poly1 = encoder.Encode(1L); Assert.AreEqual(1, poly1.SignificantCoeffCount()); Assert.AreEqual("1", poly1.ToString()); Assert.AreEqual(1L, encoder.DecodeInt64(poly1)); var poly2 = encoder.Encode(2L); Assert.AreEqual(2, poly2.SignificantCoeffCount()); Assert.AreEqual("1x^1 + FFFF", poly2.ToString()); Assert.AreEqual(2L, encoder.DecodeInt64(poly2)); var poly3 = encoder.Encode(3L); Assert.AreEqual(2, poly3.SignificantCoeffCount()); Assert.AreEqual("1x^1", poly3.ToString()); Assert.AreEqual(3L, encoder.DecodeInt64(poly3)); var poly4 = encoder.Encode(-1L); Assert.AreEqual(1, poly4.SignificantCoeffCount()); Assert.AreEqual("FFFF", poly4.ToString()); Assert.AreEqual(-1L, encoder.DecodeInt64(poly4)); var poly5 = encoder.Encode(-2L); Assert.AreEqual(2, poly5.SignificantCoeffCount()); Assert.AreEqual("FFFFx^1 + 1", poly5.ToString()); Assert.AreEqual(-2L, encoder.DecodeInt64(poly5)); var poly6 = encoder.Encode(-3L); Assert.AreEqual(2, poly6.SignificantCoeffCount()); Assert.AreEqual("FFFFx^1", poly6.ToString()); Assert.AreEqual(-3L, encoder.DecodeInt64(poly6)); var poly7 = encoder.Encode(-0x2671L); Assert.AreEqual(9, poly7.SignificantCoeffCount()); for (int i = 0; i < 9; ++i) { Assert.AreEqual(0xFFFFUL, poly7[i]); } Assert.AreEqual(-0x2671L, encoder.DecodeInt64(poly7)); var poly8 = encoder.Encode(-4374L); Assert.AreEqual(9, poly8.SignificantCoeffCount()); Assert.AreEqual(0xFFFFUL, poly8[8]); Assert.AreEqual(1UL, poly8[7]); for (int i = 0; i < 7; ++i) { Assert.IsTrue(poly8[i] == 0); } Assert.AreEqual(-4374L, encoder.DecodeInt64(poly8)); var poly9 = encoder.Encode(-0xD4EBL); Assert.AreEqual(11, poly9.SignificantCoeffCount()); for (int i = 0; i < 11; ++i) { if (i % 3 == 1) { Assert.AreEqual(0xFFFFUL, poly9[i]); } else if (i % 3 == 0) { Assert.IsTrue(poly9[i] == 0); } else { Assert.AreEqual(1UL, poly9[i]); } } Assert.AreEqual(-0xD4EBL, encoder.DecodeInt64(poly9)); var poly10 = encoder.Encode(-30724L); Assert.AreEqual(11, poly10.SignificantCoeffCount()); Assert.AreEqual(0xFFFFUL, poly10[10]); Assert.AreEqual(1UL, poly10[9]); Assert.AreEqual(1UL, poly10[8]); Assert.AreEqual(1UL, poly10[7]); Assert.IsTrue(poly10[6] == 0); Assert.IsTrue(poly10[5] == 0); Assert.AreEqual(0xFFFFUL, poly10[4]); Assert.AreEqual(0xFFFFUL, poly10[3]); Assert.IsTrue(poly10[2] == 0); Assert.AreEqual(1UL, poly10[1]); Assert.AreEqual(0xFFFFUL, poly10[0]); Assert.AreEqual(-30724L, encoder.DecodeInt64(poly10)); var encoder2 = new BalancedEncoder(modulus, 13, MemoryPoolHandle.New()); var poly11 = encoder2.Encode(-126375543984L); Assert.AreEqual(11, poly11.SignificantCoeffCount()); Assert.AreEqual(0xFFFFUL, poly11[10]); Assert.AreEqual(1UL, poly11[9]); Assert.AreEqual(1UL, poly11[8]); Assert.AreEqual(1UL, poly11[7]); Assert.IsTrue(poly11[6] == 0); Assert.IsTrue(poly11[5] == 0); Assert.AreEqual(0xFFFFUL, poly11[4]); Assert.AreEqual(0xFFFFUL, poly11[3]); Assert.IsTrue(poly11[2] == 0); Assert.AreEqual(1UL, poly11[1]); Assert.AreEqual(0xFFFFUL, poly11[0]); Assert.AreEqual(-126375543984L, encoder2.DecodeInt64(poly11)); modulus.Set(0xFFFF); var encoder3 = new BalancedEncoder(modulus, 7, MemoryPoolHandle.New()); var poly12 = new Plaintext(6); poly12[0] = 1; poly12[1] = 0xFFFE; // -1 poly12[2] = 0xFFFD; // -2 poly12[3] = 0x8000; // -32767 poly12[4] = 0x7FFF; // 32767 poly12[5] = 0x7FFE; // 32766 Assert.AreEqual(1L + -1 * 7 + -2 * 49 + -32767 * 343 + 32767 * 2401 + 32766 * 16807, encoder3.DecodeInt64(poly12)); var encoder4 = new BalancedEncoder(modulus, 6, MemoryPoolHandle.New()); poly8 = new Plaintext(4); poly8[0] = 5; poly8[1] = 4; poly8[2] = 3; poly8[3] = (modulus.Value - 2); Int64 value = 5 + 4 * 6 + 3 * 36 - 2 * 216; Assert.AreEqual(value, encoder4.DecodeInt64(poly8)); var encoder5 = new BalancedEncoder(modulus, 10, MemoryPoolHandle.New()); poly9 = new Plaintext(4); poly9[0] = 1; poly9[1] = 2; poly9[2] = 3; poly9[3] = 4; value = 4321; Assert.AreEqual(value, encoder5.DecodeInt64(poly9)); value = -1234; poly10.Set(encoder3.Encode(value)); Assert.AreEqual(5, poly10.SignificantCoeffCount()); Assert.IsTrue(value.Equals(encoder3.DecodeInt64(poly10))); value = -1234; poly11.Set(encoder4.Encode(value)); Assert.AreEqual(5, poly11.SignificantCoeffCount()); Assert.IsTrue(value.Equals(encoder4.DecodeInt64(poly11))); value = -1234; poly12.Set(encoder5.Encode(value)); Assert.AreEqual(4, poly12.SignificantCoeffCount()); Assert.IsTrue(value.Equals(encoder5.DecodeInt64(poly12))); }
public void BalancedEncodeDecodeInt64NET() { var modulus = new BigUInt("10000"); var encoder = new BalancedEncoder(modulus, 3); var poly = encoder.Encode(0L); Assert.AreEqual(0, poly.GetSignificantCoeffCount()); Assert.IsTrue(poly.IsZero); Assert.AreEqual(0L, encoder.DecodeInt64(poly)); var poly1 = encoder.Encode(1L); Assert.AreEqual(1, poly1.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly1.CoeffBitCount); Assert.AreEqual("1", poly1.ToString()); Assert.AreEqual(1L, encoder.DecodeInt64(poly1)); var poly2 = encoder.Encode(2L); Assert.AreEqual(2, poly2.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly2.CoeffBitCount); Assert.AreEqual("1x^1 + FFFF", poly2.ToString()); Assert.AreEqual(2L, encoder.DecodeInt64(poly2)); var poly3 = encoder.Encode(3L); Assert.AreEqual(2, poly3.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly3.CoeffBitCount); Assert.AreEqual("1x^1", poly3.ToString()); Assert.AreEqual(3L, encoder.DecodeInt64(poly3)); var poly4 = encoder.Encode(-1L); Assert.AreEqual(1, poly4.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly4.CoeffBitCount); Assert.AreEqual("FFFF", poly4.ToString()); Assert.AreEqual(-1L, encoder.DecodeInt64(poly4)); var poly5 = encoder.Encode(-2L); Assert.AreEqual(2, poly5.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly5.CoeffBitCount); Assert.AreEqual("FFFFx^1 + 1", poly5.ToString()); Assert.AreEqual(-2L, encoder.DecodeInt64(poly5)); var poly6 = encoder.Encode(-3L); Assert.AreEqual(2, poly6.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly6.CoeffBitCount); Assert.AreEqual("FFFFx^1", poly6.ToString()); Assert.AreEqual(-3L, encoder.DecodeInt64(poly6)); var poly7 = encoder.Encode(-0x2671L); Assert.AreEqual(9, poly7.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly7.CoeffBitCount); for (int i = 0; i < 9; ++i) { Assert.AreEqual("FFFF", poly7[i].ToString()); } Assert.AreEqual(-0x2671L, encoder.DecodeInt64(poly7)); var poly8 = encoder.Encode(-4374L); Assert.AreEqual(9, poly8.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly8.CoeffBitCount); Assert.AreEqual("FFFF", poly8[8].ToString()); Assert.AreEqual("1", poly8[7].ToString()); for (int i = 0; i < 7; ++i) { Assert.IsTrue(poly8[i].IsZero); } Assert.AreEqual(-4374L, encoder.DecodeInt64(poly8)); var poly9 = encoder.Encode(-0xD4EBL); Assert.AreEqual(11, poly9.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly9.CoeffBitCount); for (int i = 0; i < 11; ++i) { if (i % 3 == 1) { Assert.AreEqual("FFFF", poly9[i].ToString()); } else if (i % 3 == 0) { Assert.IsTrue(poly9[i].IsZero); } else { Assert.AreEqual("1", poly9[i].ToString()); } } Assert.AreEqual(-0xD4EBL, encoder.DecodeInt64(poly9)); var poly10 = encoder.Encode(-30724L); Assert.AreEqual(11, poly10.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly10.CoeffBitCount); Assert.AreEqual("FFFF", poly10[10].ToString()); Assert.AreEqual("1", poly10[9].ToString()); Assert.AreEqual("1", poly10[8].ToString()); Assert.AreEqual("1", poly10[7].ToString()); Assert.IsTrue(poly10[6].IsZero); Assert.IsTrue(poly10[5].IsZero); Assert.AreEqual("FFFF", poly10[4].ToString()); Assert.AreEqual("FFFF", poly10[3].ToString()); Assert.IsTrue(poly10[2].IsZero); Assert.AreEqual("1", poly10[1].ToString()); Assert.AreEqual("FFFF", poly10[0].ToString()); Assert.AreEqual(-30724L, encoder.DecodeInt64(poly10)); var encoder2 = new BalancedEncoder(modulus, 13); var poly11 = encoder2.Encode(-126375543984L); Assert.AreEqual(11, poly11.GetSignificantCoeffCount()); Assert.AreEqual(modulus.BitCount, poly11.CoeffBitCount); Assert.AreEqual("FFFF", poly11[10].ToString()); Assert.AreEqual("1", poly11[9].ToString()); Assert.AreEqual("1", poly11[8].ToString()); Assert.AreEqual("1", poly11[7].ToString()); Assert.IsTrue(poly11[6].IsZero); Assert.IsTrue(poly11[5].IsZero); Assert.AreEqual("FFFF", poly11[4].ToString()); Assert.AreEqual("FFFF", poly11[3].ToString()); Assert.IsTrue(poly11[2].IsZero); Assert.AreEqual("1", poly11[1].ToString()); Assert.AreEqual("FFFF", poly11[0].ToString()); Assert.AreEqual(-126375543984L, encoder2.DecodeInt64(poly11)); modulus.Set("FFFF"); var encoder3 = new BalancedEncoder(modulus, 7); var poly12 = new BigPoly(6, 16); poly12[0].Set(1); poly12[1].Set("FFFE"); // -1 poly12[2].Set("FFFD"); // -2 poly12[3].Set("8000"); // -32767 poly12[4].Set("7FFF"); // 32767 poly12[5].Set("7FFE"); // 32766 Assert.AreEqual(1L + -1 * 7 + -2 * 49 + -32767 * 343 + 32767 * 2401 + 32766 * 16807, encoder3.DecodeInt64(poly12)); }
public static void ExampleParameterSelection() { PrintExampleBanner("Example: Automatic Parameter Selection"); /* * Here we demonstrate the automatic parameter selection tool. Suppose we want to find parameters * that are optimized in a way that allows us to evaluate the polynomial 42x^3-27x+1. We need to know * the size of the input data, so let's assume that x is an integer with base-3 representation of length * at most 10. */ Console.Write("Finding optimized parameters for computing 42x^3-27x+1 ... "); var chooserEncoder = new ChooserEncoder(); var chooserEvaluator = new ChooserEvaluator(); /* * First create a ChooserPoly representing the input data. You can think of this modeling a freshly * encrypted cipheretext of a plaintext polynomial with length at most 10 coefficients, where the * coefficients have absolute value at most 1. */ var cinput = new ChooserPoly(10, 1); // Compute the first term var ccubedInput = chooserEvaluator.Exponentiate(cinput, 3); var cterm1 = chooserEvaluator.MultiplyPlain(ccubedInput, chooserEncoder.Encode(42)); // Compute the second term var cterm2 = chooserEvaluator.MultiplyPlain(cinput, chooserEncoder.Encode(27)); // Subtract the first two terms var csum12 = chooserEvaluator.Sub(cterm1, cterm2); // Add the constant term 1 var cresult = chooserEvaluator.AddPlain(csum12, chooserEncoder.Encode(1)); // To find an optimized set of parameters, we use ChooserEvaluator::select_parameters(...). var optimalParms = new EncryptionParameters(); chooserEvaluator.SelectParameters(cresult, optimalParms); Console.WriteLine("done."); // Let's print these to see what was recommended Console.WriteLine("Selected parameters:"); Console.WriteLine("{{ poly_modulus: {0}", optimalParms.PolyModulus); Console.WriteLine("{{ coeff_modulus: {0}", optimalParms.CoeffModulus); Console.WriteLine("{{ plain_modulus: {0}", optimalParms.PlainModulus.ToDecimalString()); Console.WriteLine("{{ decomposition_bit_count: {0}", optimalParms.DecompositionBitCount); Console.WriteLine("{{ noise_standard_deviation: {0}", optimalParms.NoiseStandardDeviation); Console.WriteLine("{{ noise_max_deviation: {0}", optimalParms.NoiseMaxDeviation); // Let's try to actually perform the homomorphic computation using the recommended parameters. // Generate keys. Console.WriteLine("Generating keys..."); var generator = new KeyGenerator(optimalParms); generator.Generate(); Console.WriteLine("... key generation completed"); var publicKey = generator.PublicKey; var secretKey = generator.SecretKey; // Create the encoding/encryption tools var encoder = new BalancedEncoder(optimalParms.PlainModulus); var encryptor = new Encryptor(optimalParms, publicKey); var evaluator = new Evaluator(optimalParms); var decryptor = new Decryptor(optimalParms, secretKey); // Now perform the computations on real encrypted data. const int inputValue = 12345; var plainInput = encoder.Encode(inputValue); Console.WriteLine("Encoded {0} as polynomial {1}", inputValue, plainInput); Console.Write("Encrypting ... "); var input = encryptor.Encrypt(plainInput); Console.WriteLine("done."); // Compute the first term Console.Write("Computing first term ... "); var cubedInput = evaluator.Exponentiate(input, 3); var term1 = evaluator.MultiplyPlain(cubedInput, encoder.Encode(42)); Console.WriteLine("done."); // Compute the second term Console.Write("Computing second term ... "); var term2 = evaluator.MultiplyPlain(input, encoder.Encode(27)); Console.WriteLine("done."); // Subtract the first two terms Console.Write("Subtracting first two terms ... "); var sum12 = evaluator.Sub(term1, term2); Console.WriteLine("done."); // Add the constant term 1 Console.Write("Adding one ... "); var result = evaluator.AddPlain(sum12, encoder.Encode(1)); Console.WriteLine("done."); // Decrypt and decode Console.Write("Decrypting ... "); var plainResult = decryptor.Decrypt(result); Console.WriteLine("done."); // Finally print the result Console.WriteLine("Polynomial 42x^3-27x+1 evaluated at x=12345: {0}", encoder.DecodeInt64(plainResult)); // How much noise did we end up with? Console.WriteLine("Noise in the result: {0}/{1} bits", Utilities.InherentNoise(result, optimalParms, secretKey).GetSignificantBitCount(), Utilities.InherentNoiseMax(optimalParms).GetSignificantBitCount()); }