зеркало из https://github.com/microsoft/SEAL.git
Using `using` local variable declarations in C# examples (yay for C# 8.0)
This commit is contained in:
Родитель
f26e5041f1
Коммит
0389ed6a51
|
@ -42,7 +42,7 @@ namespace SEALNetExamples
|
|||
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);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
|
||||
/*
|
||||
The first parameter we set is the degree of the `polynomial modulus'. This
|
||||
|
@ -124,8 +124,21 @@ namespace SEALNetExamples
|
|||
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.
|
||||
|
||||
C# 8.0 introduced the `using` declaration for local variables. This is a very
|
||||
convenient addition to the language: it causes the Dispose method for the
|
||||
object to be called at the end of the enclosing scope (in this case the end
|
||||
of this function), hence automatically releasing the native resources held by
|
||||
the object. This is helpful, because releasing the native resources returns
|
||||
the allocated memory to the memory pool, speeding up further allocations.
|
||||
Another way would be to call GC::Collect() at a convenient point in the code,
|
||||
but this may be less optimal as it may still cause unnecessary allocations
|
||||
of memory if native resources were not released early enough. In this program
|
||||
we call GC::Collect() after every example (see Examples.cs) to make sure
|
||||
everything is returned to the memory pool at latest before running the next
|
||||
example.
|
||||
*/
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
|
||||
/*
|
||||
Print the parameters that we have chosen.
|
||||
|
@ -150,29 +163,29 @@ namespace SEALNetExamples
|
|||
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;
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using 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);
|
||||
using 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);
|
||||
using 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);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
/*
|
||||
As an example, we evaluate the degree 4 polynomial
|
||||
|
@ -199,14 +212,14 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
int x = 6;
|
||||
Plaintext xPlain = new Plaintext(x.ToString());
|
||||
using 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();
|
||||
using Ciphertext xEncrypted = new Ciphertext();
|
||||
Console.WriteLine("Encrypt xPlain to xEncrypted.");
|
||||
encryptor.Encrypt(xPlain, xEncrypted);
|
||||
|
||||
|
@ -229,7 +242,7 @@ namespace SEALNetExamples
|
|||
We decrypt the ciphertext and print the resulting plaintext in order to
|
||||
demonstrate correctness of the encryption.
|
||||
*/
|
||||
Plaintext xDecrypted = new Plaintext();
|
||||
using Plaintext xDecrypted = new Plaintext();
|
||||
Console.Write(" + decryption of encrypted_x: ");
|
||||
decryptor.Decrypt(xEncrypted, xDecrypted);
|
||||
Console.WriteLine($"0x{xDecrypted} ...... Correct.");
|
||||
|
@ -254,9 +267,9 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute xSqPlusOne (x^2+1).");
|
||||
Ciphertext xSqPlusOne = new Ciphertext();
|
||||
using Ciphertext xSqPlusOne = new Ciphertext();
|
||||
evaluator.Square(xEncrypted, xSqPlusOne);
|
||||
Plaintext plainOne = new Plaintext("1");
|
||||
using Plaintext plainOne = new Plaintext("1");
|
||||
evaluator.AddPlainInplace(xSqPlusOne, plainOne);
|
||||
|
||||
/*
|
||||
|
@ -274,7 +287,7 @@ namespace SEALNetExamples
|
|||
Even though the size has grown, decryption works as usual as long as noise
|
||||
budget has not reached 0.
|
||||
*/
|
||||
Plaintext decryptedResult = new Plaintext();
|
||||
using Plaintext decryptedResult = new Plaintext();
|
||||
Console.Write(" + decryption of xSqPlusOne: ");
|
||||
decryptor.Decrypt(xSqPlusOne, decryptedResult);
|
||||
Console.WriteLine($"0x{decryptedResult} ...... Correct.");
|
||||
|
@ -284,7 +297,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute xPlusOneSq ((x+1)^2).");
|
||||
Ciphertext xPlusOneSq = new Ciphertext();
|
||||
using Ciphertext xPlusOneSq = new Ciphertext();
|
||||
evaluator.AddPlain(xEncrypted, plainOne, xPlusOneSq);
|
||||
evaluator.SquareInplace(xPlusOneSq);
|
||||
Console.WriteLine($" + size of xPlusOneSq: {xPlusOneSq.Size}");
|
||||
|
@ -299,8 +312,8 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute encryptedResult (4(x^2+1)(x+1)^2).");
|
||||
Ciphertext encryptedResult = new Ciphertext();
|
||||
Plaintext plainFour = new Plaintext("4");
|
||||
using Ciphertext encryptedResult = new Ciphertext();
|
||||
using Plaintext plainFour = new Plaintext("4");
|
||||
evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour);
|
||||
evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult);
|
||||
Console.WriteLine($" + size of encrypted_result: {encryptedResult.Size}");
|
||||
|
@ -341,7 +354,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Generate locally usable relinearization keys.");
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
|
||||
/*
|
||||
We now repeat the computation relinearizing after each multiplication.
|
||||
|
@ -349,7 +362,7 @@ namespace SEALNetExamples
|
|||
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();
|
||||
using Ciphertext xSquared = new Ciphertext();
|
||||
evaluator.Square(xEncrypted, xSquared);
|
||||
Console.WriteLine($" + size of xSquared: {xSquared.Size}");
|
||||
evaluator.RelinearizeInplace(xSquared, relinKeys);
|
||||
|
@ -363,7 +376,7 @@ namespace SEALNetExamples
|
|||
Console.WriteLine($"0x{decryptedResult} ...... Correct.");
|
||||
|
||||
Utilities.PrintLine();
|
||||
Ciphertext xPlusOne = new Ciphertext();
|
||||
using Ciphertext xPlusOne = new Ciphertext();
|
||||
Console.WriteLine("Compute xPlusOne (x+1),");
|
||||
Console.WriteLine(new string(' ', 13) +
|
||||
"then compute and relinearize xPlusOneSq ((x+1)^2).");
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace SEALNetExamples
|
|||
However, advanced users will probably prefer more efficient approaches,
|
||||
such as the BatchEncoder or the CKKSEncoder.
|
||||
*/
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
ulong polyModulusDegree = 4096;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
|
@ -84,41 +84,41 @@ namespace SEALNetExamples
|
|||
will be incorrect.
|
||||
*/
|
||||
parms.PlainModulus = new SmallModulus(512);
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using 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);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
/*
|
||||
We create an IntegerEncoder.
|
||||
*/
|
||||
IntegerEncoder encoder = new IntegerEncoder(context);
|
||||
using 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);
|
||||
using Plaintext plain1 = encoder.Encode(value1);
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine($"Encode {value1} as polynomial {plain1} (plain1),");
|
||||
|
||||
int value2 = -7;
|
||||
Plaintext plain2 = encoder.Encode(value2);
|
||||
using 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();
|
||||
using Ciphertext encrypted1 = new Ciphertext();
|
||||
using Ciphertext encrypted2 = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encrypt plain1 to encrypted1 and plain2 to encrypted2.");
|
||||
encryptor.Encrypt(plain1, encrypted1);
|
||||
|
@ -132,7 +132,7 @@ namespace SEALNetExamples
|
|||
As a simple example, we compute (-encrypted1 + encrypted2) * encrypted2.
|
||||
*/
|
||||
encryptor.Encrypt(plain2, encrypted2);
|
||||
Ciphertext encryptedResult = new Ciphertext();
|
||||
using Ciphertext encryptedResult = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute encrypted_result = (-encrypted1 + encrypted2) * encrypted2.");
|
||||
evaluator.Negate(encrypted1, encryptedResult);
|
||||
|
@ -141,7 +141,7 @@ namespace SEALNetExamples
|
|||
Console.WriteLine(" + Noise budget in encryptedResult: {0} bits",
|
||||
decryptor.InvariantNoiseBudget(encryptedResult));
|
||||
|
||||
Plaintext plainResult = new Plaintext();
|
||||
using Plaintext plainResult = new Plaintext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Decrypt encrypted_result to plain_result.");
|
||||
decryptor.Decrypt(encryptedResult, plainResult);
|
||||
|
@ -177,7 +177,7 @@ namespace SEALNetExamples
|
|||
with BFV, and when used properly will result in implementations outperforming
|
||||
anything done with the IntegerEncoder.
|
||||
*/
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
ulong polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
|
@ -190,7 +190,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
|
@ -198,21 +198,21 @@ namespace SEALNetExamples
|
|||
We can verify that batching is indeed enabled by looking at the encryption
|
||||
parameter qualifiers created by SEALContext.
|
||||
*/
|
||||
var qualifiers = context.FirstContextData.Qualifiers;
|
||||
using var qualifiers = context.FirstContextData.Qualifiers;
|
||||
Console.WriteLine($"Batching enabled: {qualifiers.UsingBatching}");
|
||||
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
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.
|
||||
*/
|
||||
BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
using BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
|
||||
/*
|
||||
The total number of batching `slots' equals the PolyModulusDegree, N, and
|
||||
|
@ -247,7 +247,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
First we use BatchEncoder to encode the matrix into a plaintext polynomial.
|
||||
*/
|
||||
Plaintext plainMatrix = new Plaintext();
|
||||
using Plaintext plainMatrix = new Plaintext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encode plaintext matrix:");
|
||||
batchEncoder.Encode(podMatrix, plainMatrix);
|
||||
|
@ -264,7 +264,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
Next we encrypt the encoded plaintext.
|
||||
*/
|
||||
Ciphertext encryptedMatrix = new Ciphertext();
|
||||
using Ciphertext encryptedMatrix = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encrypt plainMatrix to encryptedMatrix.");
|
||||
encryptor.Encrypt(plainMatrix, encryptedMatrix);
|
||||
|
@ -286,7 +286,7 @@ namespace SEALNetExamples
|
|||
{
|
||||
podMatrix2[i] = (i % 2) + 1;
|
||||
}
|
||||
Plaintext plainMatrix2 = new Plaintext();
|
||||
using Plaintext plainMatrix2 = new Plaintext();
|
||||
batchEncoder.Encode(podMatrix2, plainMatrix2);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Second input plaintext matrix:");
|
||||
|
@ -311,7 +311,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
We decrypt and decompose the plaintext to recover the result as a matrix.
|
||||
*/
|
||||
Plaintext plainResult = new Plaintext();
|
||||
using Plaintext plainResult = new Plaintext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Decrypt and decode result.");
|
||||
decryptor.Decrypt(encryptedMatrix, plainResult);
|
||||
|
@ -349,7 +349,7 @@ namespace SEALNetExamples
|
|||
`CKKS_Basics.cs'. In this example we use CoeffModulus.Create to
|
||||
generate 5 40-bit prime numbers.
|
||||
*/
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
|
||||
ulong polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
|
@ -359,24 +359,24 @@ namespace SEALNetExamples
|
|||
/*
|
||||
We create the SEALContext as usual and print the parameters.
|
||||
*/
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
/*
|
||||
Keys are created the same way as for the BFV scheme.
|
||||
*/
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
|
||||
/*
|
||||
We also set up an Encryptor, Evaluator, and Decryptor as usual.
|
||||
*/
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
/*
|
||||
To create CKKS plaintexts we need a special encoder: there is no other way
|
||||
|
@ -386,7 +386,7 @@ namespace SEALNetExamples
|
|||
looks a lot like what BatchEncoder does for the BFV scheme, but the theory
|
||||
behind it is completely different.
|
||||
*/
|
||||
CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
using CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
|
||||
/*
|
||||
In CKKS the number of slots is PolyModulusDegree / 2 and each slot encodes
|
||||
|
@ -419,7 +419,7 @@ namespace SEALNetExamples
|
|||
we have little to worry about in this regard. For this simple example a 30-bit
|
||||
scale is more than enough.
|
||||
*/
|
||||
Plaintext plain = new Plaintext();
|
||||
using Plaintext plain = new Plaintext();
|
||||
double scale = Math.Pow(2.0, 30);
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encode input vector.");
|
||||
|
@ -436,7 +436,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
The vector is encrypted the same was as in BFV.
|
||||
*/
|
||||
Ciphertext encrypted = new Ciphertext();
|
||||
using Ciphertext encrypted = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encrypt input vector, square, and relinearize.");
|
||||
encryptor.Encrypt(plain, encrypted);
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace SEALNetExamples
|
|||
node can be identified by the ParmsId of its specific encryption parameters
|
||||
(PolyModulusDegree remains the same but CoeffModulus varies).
|
||||
*/
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
ulong polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
|
||||
/*
|
||||
|
@ -164,10 +164,10 @@ namespace SEALNetExamples
|
|||
/*
|
||||
We create some keys and check that indeed they appear at the highest level.
|
||||
*/
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
|
||||
/*
|
||||
In this example we create a local version of the GaloisKeys object using
|
||||
|
@ -176,7 +176,7 @@ namespace SEALNetExamples
|
|||
use KeyGenerator.GaloisKeys(), which outputs a Serializable<GaloisKeys>
|
||||
object for compressed serialization.
|
||||
*/
|
||||
GaloisKeys galoisKeys = keygen.GaloisKeysLocal();
|
||||
using GaloisKeys galoisKeys = keygen.GaloisKeysLocal();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Print the parameter IDs of generated elements.");
|
||||
Console.WriteLine($" + publicKey: {publicKey.ParmsId}");
|
||||
|
@ -184,16 +184,16 @@ namespace SEALNetExamples
|
|||
Console.WriteLine($" + relinKeys: {relinKeys.ParmsId}");
|
||||
Console.WriteLine($" + galoisKeys: {galoisKeys.ParmsId}");
|
||||
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
/*
|
||||
In the BFV scheme plaintexts do not carry a ParmsId, but ciphertexts do. Note
|
||||
how the freshly encrypted ciphertext is at the highest data level.
|
||||
*/
|
||||
Plaintext plain = new Plaintext("1x^3 + 2x^2 + 3x^1 + 4");
|
||||
Ciphertext encrypted = new Ciphertext();
|
||||
using Plaintext plain = new Plaintext("1x^3 + 2x^2 + 3x^1 + 4");
|
||||
using Ciphertext encrypted = new Ciphertext();
|
||||
encryptor.Encrypt(plain, encrypted);
|
||||
Console.WriteLine($" + plain: {plain.ParmsId} (not set in BFV)");
|
||||
Console.WriteLine($" + encrypted: {encrypted.ParmsId}");
|
||||
|
@ -309,7 +309,7 @@ namespace SEALNetExamples
|
|||
not want to create the modulus switching chain, except for the highest two
|
||||
levels. This can be done by passing a bool `false' to SEALContext constructor.
|
||||
*/
|
||||
context = new SEALContext(parms, expandModChain: false);
|
||||
using SEALContext context2 = new SEALContext(parms, expandModChain: false);
|
||||
|
||||
/*
|
||||
We can check that indeed the modulus switching chain has been created only
|
||||
|
@ -320,7 +320,7 @@ namespace SEALNetExamples
|
|||
Utilities.PrintLine();
|
||||
Console.WriteLine("Print the modulus switching chain.");
|
||||
Console.Write("----> ");
|
||||
for (contextData = context.KeyContextData; null != contextData;
|
||||
for (contextData = context2.KeyContextData; null != contextData;
|
||||
contextData = contextData.NextContextData)
|
||||
{
|
||||
Console.WriteLine($"Level (chain index): {contextData.ChainIndex}");
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace SEALNetExamples
|
|||
|
||||
We start by setting up the CKKS scheme.
|
||||
*/
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
|
||||
/*
|
||||
We saw in `2_Encoders.cs' that multiplication in CKKS causes scales in
|
||||
|
@ -86,19 +86,19 @@ namespace SEALNetExamples
|
|||
*/
|
||||
double scale = Math.Pow(2.0, 40);
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
using CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
ulong slotCount = encoder.SlotCount;
|
||||
Console.WriteLine($"Number of slots: {slotCount}");
|
||||
|
||||
|
@ -117,25 +117,25 @@ namespace SEALNetExamples
|
|||
We create plaintexts for PI, 0.4, and 1 using an overload of CKKSEncoder.Encode
|
||||
that encodes the given floating-point value to every slot in the vector.
|
||||
*/
|
||||
Plaintext plainCoeff3 = new Plaintext(),
|
||||
plainCoeff1 = new Plaintext(),
|
||||
plainCoeff0 = new Plaintext();
|
||||
using Plaintext plainCoeff3 = new Plaintext(),
|
||||
plainCoeff1 = new Plaintext(),
|
||||
plainCoeff0 = new Plaintext();
|
||||
encoder.Encode(3.14159265, scale, plainCoeff3);
|
||||
encoder.Encode(0.4, scale, plainCoeff1);
|
||||
encoder.Encode(1.0, scale, plainCoeff0);
|
||||
|
||||
Plaintext xPlain = new Plaintext();
|
||||
using Plaintext xPlain = new Plaintext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encode input vectors.");
|
||||
encoder.Encode(input, scale, xPlain);
|
||||
Ciphertext x1Encrypted = new Ciphertext();
|
||||
using Ciphertext x1Encrypted = new Ciphertext();
|
||||
encryptor.Encrypt(xPlain, x1Encrypted);
|
||||
|
||||
/*
|
||||
To compute x^3 we first compute x^2 and relinearize. However, the scale has
|
||||
now grown to 2^80.
|
||||
*/
|
||||
Ciphertext x3Encrypted = new Ciphertext();
|
||||
using Ciphertext x3Encrypted = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute x^2 and relinearize:");
|
||||
evaluator.Square(x1Encrypted, x3Encrypted);
|
||||
|
@ -165,7 +165,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute and rescale PI*x.");
|
||||
Ciphertext x1EncryptedCoeff3 = new Ciphertext();
|
||||
using Ciphertext x1EncryptedCoeff3 = new Ciphertext();
|
||||
evaluator.MultiplyPlain(x1Encrypted, plainCoeff3, x1EncryptedCoeff3);
|
||||
Console.WriteLine(" + Scale of PI*x before rescale: {0} bits",
|
||||
Math.Log(x1EncryptedCoeff3.Scale, newBase: 2));
|
||||
|
@ -284,14 +284,14 @@ namespace SEALNetExamples
|
|||
*/
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Compute PI*x^3 + 0.4*x + 1.");
|
||||
Ciphertext encryptedResult = new Ciphertext();
|
||||
using Ciphertext encryptedResult = new Ciphertext();
|
||||
evaluator.Add(x3Encrypted, x1Encrypted, encryptedResult);
|
||||
evaluator.AddPlainInplace(encryptedResult, plainCoeff0);
|
||||
|
||||
/*
|
||||
First print the true result.
|
||||
*/
|
||||
Plaintext plainResult = new Plaintext();
|
||||
using Plaintext plainResult = new Plaintext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Decrypt and decode PI * x ^ 3 + 0.4x + 1.");
|
||||
Console.WriteLine(" + Expected result:");
|
||||
|
|
|
@ -18,26 +18,26 @@ namespace SEALNetExamples
|
|||
{
|
||||
Utilities.PrintExampleBanner("Example: Rotation / Rotation in BFV");
|
||||
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.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);
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
using BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
ulong slotCount = batchEncoder.SlotCount;
|
||||
ulong rowSize = slotCount / 2;
|
||||
Console.WriteLine($"Plaintext matrix row size: {rowSize}");
|
||||
|
@ -61,10 +61,10 @@ namespace SEALNetExamples
|
|||
the plaintext as usual.
|
||||
*/
|
||||
Utilities.PrintLine();
|
||||
Plaintext plainMatrix = new Plaintext();
|
||||
using Plaintext plainMatrix = new Plaintext();
|
||||
Console.WriteLine("Encode and encrypt.");
|
||||
batchEncoder.Encode(podMatrix, plainMatrix);
|
||||
Ciphertext encryptedMatrix = new Ciphertext();
|
||||
using Ciphertext encryptedMatrix = new Ciphertext();
|
||||
encryptor.Encrypt(plainMatrix, encryptedMatrix);
|
||||
Console.WriteLine(" + Noise budget in fresh encryption: {0} bits",
|
||||
decryptor.InvariantNoiseBudget(encryptedMatrix));
|
||||
|
@ -74,7 +74,7 @@ namespace SEALNetExamples
|
|||
Rotations require yet another type of special key called `Galois keys'. These
|
||||
are easily obtained from the KeyGenerator.
|
||||
*/
|
||||
GaloisKeys galKeys = keygen.GaloisKeysLocal();
|
||||
using GaloisKeys galKeys = keygen.GaloisKeysLocal();
|
||||
|
||||
/*
|
||||
Now rotate both matrix rows 3 steps to the left, decrypt, decode, and print.
|
||||
|
@ -82,7 +82,7 @@ namespace SEALNetExamples
|
|||
Utilities.PrintLine();
|
||||
Console.WriteLine("Rotate rows 3 steps left.");
|
||||
evaluator.RotateRowsInplace(encryptedMatrix, 3, galKeys);
|
||||
Plaintext plainResult = new Plaintext();
|
||||
using Plaintext plainResult = new Plaintext();
|
||||
Console.WriteLine(" + Noise budget after rotation: {0} bits",
|
||||
decryptor.InvariantNoiseBudget(encryptedMatrix));
|
||||
Console.WriteLine(" + Decrypt and decode ...... Correct.");
|
||||
|
@ -130,27 +130,27 @@ namespace SEALNetExamples
|
|||
{
|
||||
Utilities.PrintExampleBanner("Example: Rotation / Rotation in CKKS");
|
||||
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
|
||||
ulong polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.Create(
|
||||
polyModulusDegree, new int[] { 40, 40, 40, 40, 40 });
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
GaloisKeys galKeys = keygen.GaloisKeysLocal();
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using RelinKeys relinKeys = keygen.RelinKeysLocal();
|
||||
using GaloisKeys galKeys = keygen.GaloisKeysLocal();
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
|
||||
CKKSEncoder ckksEncoder = new CKKSEncoder(context);
|
||||
using CKKSEncoder ckksEncoder = new CKKSEncoder(context);
|
||||
|
||||
ulong slotCount = ckksEncoder.SlotCount;
|
||||
Console.WriteLine($"Number of slots: {slotCount}");
|
||||
|
@ -168,12 +168,12 @@ namespace SEALNetExamples
|
|||
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Encode and encrypt.");
|
||||
Plaintext plain = new Plaintext();
|
||||
using Plaintext plain = new Plaintext();
|
||||
ckksEncoder.Encode(input, scale, plain);
|
||||
Ciphertext encrypted = new Ciphertext();
|
||||
using Ciphertext encrypted = new Ciphertext();
|
||||
encryptor.Encrypt(plain, encrypted);
|
||||
|
||||
Ciphertext rotated = new Ciphertext();
|
||||
using Ciphertext rotated = new Ciphertext();
|
||||
Utilities.PrintLine();
|
||||
Console.WriteLine("Rotate 2 steps left.");
|
||||
evaluator.RotateVector(encrypted, 2, galKeys, rotated);
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace SEALNetExamples
|
|||
if (!Serialization.IsSupportedComprMode(ComprModeType.Deflate))
|
||||
{
|
||||
Console.WriteLine("ZLIB support is not enabled; this example is not available.");
|
||||
Console.WriteLine();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,7 +54,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
{
|
||||
ulong polyModulusDegree = 8192;
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.Create(
|
||||
polyModulusDegree, new int[]{ 50, 20, 50 });
|
||||
|
@ -134,7 +135,7 @@ namespace SEALNetExamples
|
|||
we need to seek our stream back to the beginning.
|
||||
*/
|
||||
buffer.Seek(0, SeekOrigin.Begin);
|
||||
EncryptionParameters parms2 = new EncryptionParameters();
|
||||
using EncryptionParameters parms2 = new EncryptionParameters();
|
||||
parms2.Load(buffer);
|
||||
|
||||
/*
|
||||
|
@ -149,7 +150,7 @@ namespace SEALNetExamples
|
|||
and creates the required keys.
|
||||
*/
|
||||
{
|
||||
EncryptionParameters parms = new EncryptionParameters();
|
||||
using EncryptionParameters parms = new EncryptionParameters();
|
||||
parms.Load(parmsStream);
|
||||
|
||||
/*
|
||||
|
@ -158,11 +159,11 @@ namespace SEALNetExamples
|
|||
*/
|
||||
parmsStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
SecretKey sk = keygen.SecretKey;
|
||||
PublicKey pk = keygen.PublicKey;
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
using SecretKey sk = keygen.SecretKey;
|
||||
using PublicKey pk = keygen.PublicKey;
|
||||
|
||||
/*
|
||||
We need to save the secret key so we can decrypt later.
|
||||
|
@ -184,7 +185,7 @@ namespace SEALNetExamples
|
|||
must be expanded before being used in computations; this is automatically
|
||||
done by deserialization.
|
||||
*/
|
||||
Serializable<RelinKeys> rlk = keygen.RelinKeys();
|
||||
using Serializable<RelinKeys> rlk = keygen.RelinKeys();
|
||||
|
||||
/*
|
||||
Before continuing, we demonstrate the significant space saving from this
|
||||
|
@ -192,7 +193,7 @@ namespace SEALNetExamples
|
|||
*/
|
||||
long sizeRlk = rlk.Save(dataStream);
|
||||
|
||||
RelinKeys rlkLocal = keygen.RelinKeysLocal();
|
||||
using RelinKeys rlkLocal = keygen.RelinKeysLocal();
|
||||
long sizeRlkLocal = rlkLocal.Save(dataStream);
|
||||
|
||||
/*
|
||||
|
@ -214,14 +215,14 @@ namespace SEALNetExamples
|
|||
*/
|
||||
double scale = Math.Pow(2.0, 20);
|
||||
CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
Plaintext plain1 = new Plaintext(),
|
||||
plain2 = new Plaintext();
|
||||
using Plaintext plain1 = new Plaintext(),
|
||||
plain2 = new Plaintext();
|
||||
encoder.Encode(2.3, scale, plain1);
|
||||
encoder.Encode(4.5, scale, plain2);
|
||||
|
||||
Encryptor encryptor = new Encryptor(context, pk);
|
||||
Ciphertext encrypted1 = new Ciphertext(),
|
||||
encrypted2 = new Ciphertext();
|
||||
using Encryptor encryptor = new Encryptor(context, pk);
|
||||
using Ciphertext encrypted1 = new Ciphertext(),
|
||||
encrypted2 = new Ciphertext();
|
||||
encryptor.Encrypt(plain1, encrypted1);
|
||||
encryptor.Encrypt(plain2, encrypted2);
|
||||
|
||||
|
@ -242,9 +243,9 @@ namespace SEALNetExamples
|
|||
To use symmetric-key encryption, we need to set up the Encryptor with the
|
||||
secret key instead.
|
||||
*/
|
||||
Encryptor symEncryptor = new Encryptor(context, sk);
|
||||
Serializable<Ciphertext> symEncrypted1 = symEncryptor.EncryptSymmetric(plain1);
|
||||
Serializable<Ciphertext> symEncrypted2 = symEncryptor.EncryptSymmetric(plain2);
|
||||
using Encryptor symEncryptor = new Encryptor(context, sk);
|
||||
using Serializable<Ciphertext> symEncrypted1 = symEncryptor.EncryptSymmetric(plain1);
|
||||
using Serializable<Ciphertext> symEncrypted2 = symEncryptor.EncryptSymmetric(plain2);
|
||||
|
||||
/*
|
||||
Before continuing, we demonstrate the significant space saving from this
|
||||
|
@ -294,20 +295,20 @@ namespace SEALNetExamples
|
|||
SEALContext and set up an Evaluator here.
|
||||
*/
|
||||
{
|
||||
EncryptionParameters parms = new EncryptionParameters();
|
||||
using EncryptionParameters parms = new EncryptionParameters();
|
||||
parms.Load(parmsStream);
|
||||
parmsStream.Seek(0, SeekOrigin.Begin);
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
|
||||
/*
|
||||
Next we need to load relinearization keys and the ciphertexts from our
|
||||
dataStream.
|
||||
*/
|
||||
RelinKeys rlk = new RelinKeys();
|
||||
Ciphertext encrypted1 = new Ciphertext(),
|
||||
encrypted2 = new Ciphertext();
|
||||
using RelinKeys rlk = new RelinKeys();
|
||||
using Ciphertext encrypted1 = new Ciphertext(),
|
||||
encrypted2 = new Ciphertext();
|
||||
|
||||
/*
|
||||
Deserialization is as easy as serialization.
|
||||
|
@ -319,7 +320,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
Compute the product, rescale, and relinearize.
|
||||
*/
|
||||
Ciphertext encryptedProd = new Ciphertext();
|
||||
using Ciphertext encryptedProd = new Ciphertext();
|
||||
evaluator.Multiply(encrypted1, encrypted2, encryptedProd);
|
||||
evaluator.RelinearizeInplace(encryptedProd, rlk);
|
||||
evaluator.RescaleToNextInplace(encryptedProd);
|
||||
|
@ -345,23 +346,23 @@ namespace SEALNetExamples
|
|||
In the final step the client decrypts the result.
|
||||
*/
|
||||
{
|
||||
EncryptionParameters parms = new EncryptionParameters();
|
||||
using EncryptionParameters parms = new EncryptionParameters();
|
||||
parms.Load(parmsStream);
|
||||
parmsStream.Seek(0, SeekOrigin.Begin);
|
||||
SEALContext context = new SEALContext(parms);
|
||||
using SEALContext context = new SEALContext(parms);
|
||||
|
||||
/*
|
||||
Load back the secret key from skStream.
|
||||
*/
|
||||
SecretKey sk = new SecretKey();
|
||||
using SecretKey sk = new SecretKey();
|
||||
sk.Load(context, skStream);
|
||||
Decryptor decryptor = new Decryptor(context, sk);
|
||||
CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
using Decryptor decryptor = new Decryptor(context, sk);
|
||||
using CKKSEncoder encoder = new CKKSEncoder(context);
|
||||
|
||||
Ciphertext encryptedResult = new Ciphertext();
|
||||
using Ciphertext encryptedResult = new Ciphertext();
|
||||
encryptedResult.Load(context, dataStream);
|
||||
|
||||
Plaintext plainResult = new Plaintext();
|
||||
using Plaintext plainResult = new Plaintext();
|
||||
decryptor.Decrypt(encryptedResult, plainResult);
|
||||
List<double> result = new List<double>();
|
||||
encoder.Decode(plainResult, result);
|
||||
|
@ -372,4 +373,4 @@ namespace SEALNetExamples
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,55 +17,73 @@ namespace SEALNetExamples
|
|||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
EncryptionParameters parms = context.FirstContextData.Parms;
|
||||
SmallModulus plainModulus = parms.PlainModulus;
|
||||
using EncryptionParameters parms = context.FirstContextData.Parms;
|
||||
using SmallModulus plainModulus = parms.PlainModulus;
|
||||
ulong polyModulusDegree = parms.PolyModulusDegree;
|
||||
|
||||
Console.Write("Generating secret/public keys: ");
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
Console.WriteLine("Done");
|
||||
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
|
||||
RelinKeys relinKeys = null;
|
||||
GaloisKeys galKeys = null;
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
/*
|
||||
Generate relinearization keys.
|
||||
*/
|
||||
Console.Write("Generating relinearization keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
relinKeys = keygen.RelinKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
|
||||
if (!context.KeyContextData.Qualifiers.UsingBatching)
|
||||
Func<RelinKeys> GetRelinKeys = () => {
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
Console.WriteLine("Given encryption parameters do not support batching.");
|
||||
return;
|
||||
/*
|
||||
Generate relinearization keys.
|
||||
*/
|
||||
Console.Write("Generating relinearization keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
RelinKeys result = keygen.RelinKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Generate Galois keys. In larger examples the Galois keys can use a lot of
|
||||
memory, which can be a problem in constrained systems. The user should
|
||||
try some of the larger runs of the test and observe their effect on the
|
||||
memory pool allocation size. The key generation can also take a long time,
|
||||
as can be observed from the print-out.
|
||||
*/
|
||||
Console.Write($"Generating Galois keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
galKeys = keygen.GaloisKeysLocal();
|
||||
micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
}
|
||||
Func<GaloisKeys> GetGaloisKeys = () => {
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
if (!context.KeyContextData.Qualifiers.UsingBatching)
|
||||
{
|
||||
Console.WriteLine("Given encryption parameters do not support batching.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
IntegerEncoder encoder = new IntegerEncoder(context);
|
||||
/*
|
||||
Generate Galois keys. In larger examples the Galois keys can use a lot of
|
||||
memory, which can be a problem in constrained systems. The user should
|
||||
try some of the larger runs of the test and observe their effect on the
|
||||
memory pool allocation size. The key generation can also take a long time,
|
||||
as can be observed from the print-out.
|
||||
*/
|
||||
Console.Write($"Generating Galois keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
GaloisKeys result = keygen.GaloisKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
using RelinKeys relinKeys = GetRelinKeys();
|
||||
using GaloisKeys galKeys = GetGaloisKeys();
|
||||
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using BatchEncoder batchEncoder = new BatchEncoder(context);
|
||||
using IntegerEncoder encoder = new IntegerEncoder(context);
|
||||
|
||||
/*
|
||||
These will hold the total times used by each operation.
|
||||
|
@ -108,7 +126,7 @@ namespace SEALNetExamples
|
|||
into the polynomial. Note how the plaintext we create is of the exactly
|
||||
right size so unnecessary reallocations are avoided.
|
||||
*/
|
||||
Plaintext plain = new Plaintext(parms.PolyModulusDegree, 0);
|
||||
using Plaintext plain = new Plaintext(parms.PolyModulusDegree, 0);
|
||||
timeBatchSum.Start();
|
||||
batchEncoder.Encode(podValues, plain);
|
||||
timeBatchSum.Stop();
|
||||
|
@ -132,7 +150,7 @@ namespace SEALNetExamples
|
|||
to hold the encryption with these encryption parameters. We encrypt
|
||||
our random batched matrix here.
|
||||
*/
|
||||
Ciphertext encrypted = new Ciphertext(context);
|
||||
using Ciphertext encrypted = new Ciphertext(context);
|
||||
timeEncryptSum.Start();
|
||||
encryptor.Encrypt(plain, encrypted);
|
||||
timeEncryptSum.Stop();
|
||||
|
@ -141,7 +159,7 @@ namespace SEALNetExamples
|
|||
[Decryption]
|
||||
We decrypt what we just encrypted.
|
||||
*/
|
||||
Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
|
||||
using Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
|
||||
timeDecryptSum.Start();
|
||||
decryptor.Decrypt(encrypted, plain2);
|
||||
timeDecryptSum.Stop();
|
||||
|
@ -154,9 +172,9 @@ namespace SEALNetExamples
|
|||
[Add]
|
||||
We create two ciphertexts and perform a few additions with them.
|
||||
*/
|
||||
Ciphertext encrypted1 = new Ciphertext(context);
|
||||
using Ciphertext encrypted1 = new Ciphertext(context);
|
||||
encryptor.Encrypt(encoder.Encode(i), encrypted1);
|
||||
Ciphertext encrypted2 = new Ciphertext(context);
|
||||
using Ciphertext encrypted2 = new Ciphertext(context);
|
||||
encryptor.Encrypt(encoder.Encode(i + 1), encrypted2);
|
||||
|
||||
timeAddSum.Start();
|
||||
|
@ -286,53 +304,71 @@ namespace SEALNetExamples
|
|||
Utilities.PrintParameters(context);
|
||||
Console.WriteLine();
|
||||
|
||||
EncryptionParameters parms = context.FirstContextData.Parms;
|
||||
using EncryptionParameters parms = context.FirstContextData.Parms;
|
||||
ulong polyModulusDegree = parms.PolyModulusDegree;
|
||||
|
||||
Console.Write("Generating secret/public keys: ");
|
||||
KeyGenerator keygen = new KeyGenerator(context);
|
||||
using KeyGenerator keygen = new KeyGenerator(context);
|
||||
Console.WriteLine("Done");
|
||||
|
||||
SecretKey secretKey = keygen.SecretKey;
|
||||
PublicKey publicKey = keygen.PublicKey;
|
||||
using SecretKey secretKey = keygen.SecretKey;
|
||||
using PublicKey publicKey = keygen.PublicKey;
|
||||
|
||||
RelinKeys relinKeys = null;
|
||||
GaloisKeys galKeys = null;
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
/*
|
||||
Generate relinearization keys.
|
||||
*/
|
||||
Console.Write("Generating relinearization keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
relinKeys = keygen.RelinKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
|
||||
if (!context.KeyContextData.Qualifiers.UsingBatching)
|
||||
Func<RelinKeys> GetRelinKeys = () => {
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
Console.WriteLine("Given encryption parameters do not support batching.");
|
||||
return;
|
||||
/*
|
||||
Generate relinearization keys.
|
||||
*/
|
||||
Console.Write("Generating relinearization keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
RelinKeys result = keygen.RelinKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Generate Galois keys. In larger examples the Galois keys can use a lot of
|
||||
memory, which can be a problem in constrained systems. The user should
|
||||
try some of the larger runs of the test and observe their effect on the
|
||||
memory pool allocation size. The key generation can also take a long time,
|
||||
as can be observed from the print-out.
|
||||
*/
|
||||
Console.Write($"Generating Galois keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
galKeys = keygen.GaloisKeysLocal();
|
||||
micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
}
|
||||
Func<GaloisKeys> GetGaloisKeys = () => {
|
||||
if (context.UsingKeyswitching)
|
||||
{
|
||||
if (!context.KeyContextData.Qualifiers.UsingBatching)
|
||||
{
|
||||
Console.WriteLine("Given encryption parameters do not support batching.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
Evaluator evaluator = new Evaluator(context);
|
||||
CKKSEncoder ckksEncoder = new CKKSEncoder(context);
|
||||
/*
|
||||
Generate Galois keys. In larger examples the Galois keys can use a lot of
|
||||
memory, which can be a problem in constrained systems. The user should
|
||||
try some of the larger runs of the test and observe their effect on the
|
||||
memory pool allocation size. The key generation can also take a long time,
|
||||
as can be observed from the print-out.
|
||||
*/
|
||||
Console.Write($"Generating Galois keys: ");
|
||||
timer = Stopwatch.StartNew();
|
||||
GaloisKeys result = keygen.GaloisKeysLocal();
|
||||
int micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
|
||||
Console.WriteLine($"Done [{micros} microseconds]");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
using RelinKeys relinKeys = GetRelinKeys();
|
||||
using GaloisKeys galKeys = GetGaloisKeys();
|
||||
|
||||
using Encryptor encryptor = new Encryptor(context, publicKey);
|
||||
using Decryptor decryptor = new Decryptor(context, secretKey);
|
||||
using Evaluator evaluator = new Evaluator(context);
|
||||
using CKKSEncoder ckksEncoder = new CKKSEncoder(context);
|
||||
|
||||
Stopwatch timeEncodeSum = new Stopwatch();
|
||||
Stopwatch timeDecodeSum = new Stopwatch();
|
||||
|
@ -374,7 +410,7 @@ namespace SEALNetExamples
|
|||
from parms.
|
||||
*/
|
||||
double scale = Math.Sqrt(parms.CoeffModulus.Last().Value);
|
||||
Plaintext plain = new Plaintext(parms.PolyModulusDegree *
|
||||
using Plaintext plain = new Plaintext(parms.PolyModulusDegree *
|
||||
(ulong)parms.CoeffModulus.Count(), 0);
|
||||
timeEncodeSum.Start();
|
||||
ckksEncoder.Encode(podValues, scale, plain);
|
||||
|
@ -391,7 +427,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
[Encryption]
|
||||
*/
|
||||
Ciphertext encrypted = new Ciphertext(context);
|
||||
using Ciphertext encrypted = new Ciphertext(context);
|
||||
timeEncryptSum.Start();
|
||||
encryptor.Encrypt(plain, encrypted);
|
||||
timeEncryptSum.Stop();
|
||||
|
@ -399,7 +435,7 @@ namespace SEALNetExamples
|
|||
/*
|
||||
[Decryption]
|
||||
*/
|
||||
Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
|
||||
using Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
|
||||
timeDecryptSum.Start();
|
||||
decryptor.Decrypt(encrypted, plain2);
|
||||
timeDecryptSum.Stop();
|
||||
|
@ -407,10 +443,10 @@ namespace SEALNetExamples
|
|||
/*
|
||||
[Add]
|
||||
*/
|
||||
Ciphertext encrypted1 = new Ciphertext(context);
|
||||
using Ciphertext encrypted1 = new Ciphertext(context);
|
||||
ckksEncoder.Encode(i + 1, plain);
|
||||
encryptor.Encrypt(plain, encrypted1);
|
||||
Ciphertext encrypted2 = new Ciphertext(context);
|
||||
using Ciphertext encrypted2 = new Ciphertext(context);
|
||||
ckksEncoder.Encode(i + 1, plain2);
|
||||
encryptor.Encrypt(plain2, encrypted2);
|
||||
timeAddSum.Start();
|
||||
|
@ -529,26 +565,35 @@ namespace SEALNetExamples
|
|||
{
|
||||
Utilities.PrintExampleBanner("BFV Performance Test with Degrees: 4096, 8192, and 16384");
|
||||
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
|
||||
ulong polyModulusDegree = 4096;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
parms.PlainModulus = new SmallModulus(786433);
|
||||
BFVPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
BFVPerformanceTest(context);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
parms.PlainModulus = new SmallModulus(786433);
|
||||
BFVPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
BFVPerformanceTest(context);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
polyModulusDegree = 16384;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
parms.PlainModulus = new SmallModulus(786433);
|
||||
BFVPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
BFVPerformanceTest(context);
|
||||
}
|
||||
|
||||
/*
|
||||
Comment out the following to run the biggest example.
|
||||
|
@ -558,7 +603,10 @@ namespace SEALNetExamples
|
|||
//parms.PolyModulusDegree = polyModulusDegree;
|
||||
//parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
//parms.PlainModulus = new SmallModulus(786433);
|
||||
//BFVPerformanceTest(new SEALContext(parms));
|
||||
//using (SEALContext context = new SEALContext(parms))
|
||||
//{
|
||||
// BFVPerformanceTest(context);
|
||||
//}
|
||||
}
|
||||
|
||||
private static void ExampleBFVPerformanceCustom()
|
||||
|
@ -580,7 +628,7 @@ namespace SEALNetExamples
|
|||
string banner = $"BFV Performance Test with Degree: {polyModulusDegree}";
|
||||
Utilities.PrintExampleBanner(banner);
|
||||
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
|
||||
{
|
||||
PolyModulusDegree = polyModulusDegree,
|
||||
CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree)
|
||||
|
@ -593,7 +641,11 @@ namespace SEALNetExamples
|
|||
{
|
||||
parms.PlainModulus = new SmallModulus(786433);
|
||||
}
|
||||
BFVPerformanceTest(new SEALContext(parms));
|
||||
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
BFVPerformanceTest(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExampleCKKSPerformanceDefault()
|
||||
|
@ -602,23 +654,32 @@ namespace SEALNetExamples
|
|||
|
||||
// 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);
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
|
||||
ulong polyModulusDegree = 4096;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
CKKSPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
CKKSPerformanceTest(context);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
polyModulusDegree = 8192;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
CKKSPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
CKKSPerformanceTest(context);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
polyModulusDegree = 16384;
|
||||
parms.PolyModulusDegree = polyModulusDegree;
|
||||
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
CKKSPerformanceTest(new SEALContext(parms));
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
CKKSPerformanceTest(context);
|
||||
}
|
||||
|
||||
/*
|
||||
Comment out the following to run the biggest example.
|
||||
|
@ -627,7 +688,10 @@ namespace SEALNetExamples
|
|||
//polyModulusDegree = 32768;
|
||||
//parms.PolyModulusDegree = polyModulusDegree;
|
||||
//parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
|
||||
//CKKSPerformanceTest(new SEALContext(parms));
|
||||
//using (SEALContext context = new SEALContext(parms))
|
||||
//{
|
||||
// CKKSPerformanceTest(context);
|
||||
//}
|
||||
}
|
||||
|
||||
private static void ExampleCKKSPerformanceCustom()
|
||||
|
@ -649,12 +713,16 @@ namespace SEALNetExamples
|
|||
string banner = $"CKKS Performance Test with Degree: {polyModulusDegree}";
|
||||
Utilities.PrintExampleBanner(banner);
|
||||
|
||||
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS)
|
||||
using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS)
|
||||
{
|
||||
PolyModulusDegree = polyModulusDegree,
|
||||
CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree)
|
||||
};
|
||||
CKKSPerformanceTest(new SEALContext(parms));
|
||||
|
||||
using (SEALContext context = new SEALContext(parms))
|
||||
{
|
||||
CKKSPerformanceTest(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExamplePerformanceTest()
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace SEALNetExamples
|
|||
}
|
||||
|
||||
/*
|
||||
Force a garbage collection after each example to accurately show memory pool use.
|
||||
We may want to force a garbage collection after each example to accurately show memory pool use.
|
||||
*/
|
||||
GC.Collect();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче