public static void ExampleWeightedAverage() { PrintExampleBanner("Example: Weighted Average"); // In this example we demonstrate computing a weighted average of 10 rational numbers. // The 10 rational numbers we use are: var rationalNumbers = new List <double> { 3.1, 4.159, 2.65, 3.5897, 9.3, 2.3, 8.46, 2.64, 3.383, 2.795 }; // The 10 weights are: var coefficients = new List <double> { 0.1, 0.05, 0.05, 0.2, 0.05, 0.3, 0.1, 0.025, 0.075, 0.05 }; // Create encryption parameters. var parms = new EncryptionParameters(); parms.SetPolyModulus("1x^2048 + 1"); parms.SetCoeffModulus(ChooserEvaluator.DefaultParameterOptions[2048]); parms.SetPlainModulus(1 << 8); parms.Validate(); // 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; /* * We will need a fractional encoder for dealing with the rational numbers. Here we reserve * 64 coefficients of the polynomial for the integral part (low-degree terms) and expand the * fractional part to 32 terms of precision (base 3) (high-degree terms). */ var encoder = new FractionalEncoder(parms.PlainModulus, parms.PolyModulus, 64, 32, 3); // Create the rest of the tools var encryptor = new Encryptor(parms, publicKey); var evaluator = new Evaluator(parms); var decryptor = new Decryptor(parms, secretKey); // First we encrypt the rational numbers Console.Write("Encrypting ... "); var encryptedRationals = new List <Ciphertext>(); for (int i = 0; i < 10; ++i) { var encodedNumber = encoder.Encode(rationalNumbers[i]); encryptedRationals.Add(encryptor.Encrypt(encodedNumber)); Console.Write(rationalNumbers[i] + ((i < 9) ? ", " : ".\n")); } // Next we encode the coefficients. There is no reason to encrypt these since they are not private data. Console.Write("Encoding ... "); var encodedCoefficients = new List <Plaintext>(); for (int i = 0; i < 10; ++i) { encodedCoefficients.Add(encoder.Encode(coefficients[i])); Console.Write(coefficients[i] + ((i < 9) ? ", " : ".\n")); } // We also need to encode 0.1. We will multiply the result by this to perform division by 10. var divByTen = encoder.Encode(0.1); // Now compute all the products of the encrypted rational numbers with the plaintext coefficients Console.Write("Computing products ... "); var encryptedProducts = new List <Ciphertext>(); for (int i = 0; i < 10; ++i) { /* * We use Evaluator.MultiplyPlain(...) instead of Evaluator.Multiply(...) (which would * require also the coefficient to be encrypted). This has much better noise growth * behavior than multiplying two encrypted numbers does. */ var encPlainProduct = evaluator.MultiplyPlain(encryptedRationals[i], encodedCoefficients[i]); encryptedProducts.Add(encPlainProduct); } Console.WriteLine("done."); // Now we add together these products. The most convenient way to do that is // to use the function Evaluator.AddMany(...). Console.Write("Add up all 10 ciphertexts ... "); var encryptedDotProduct = evaluator.AddMany(encryptedProducts); Console.WriteLine("done"); // Finally we divide by 10 to obtain the result. Console.Write("Divide by 10 ... "); var encryptedResult = evaluator.MultiplyPlain(encryptedDotProduct, divByTen); Console.WriteLine("done"); // Decrypt Console.Write("Decrypting ... "); var plainResult = decryptor.Decrypt(encryptedResult); Console.WriteLine("done"); // Print the result double result = encoder.Decode(plainResult); Console.WriteLine("Weighted average: {0}", result); // How much noise budget are we left with? Console.WriteLine("Noise budget in result: {0} bits", decryptor.InvariantNoiseBudget(encryptedResult)); }
private FractionalEncoder GetEncoder(SEALContext context) { var encoder = new FractionalEncoder(context.PlainModulus, context.PolyModulus, 64, 32); return(encoder); }