Using `using` local variable declarations in C# examples (yay for C# 8.0)

This commit is contained in:
Kim Laine 2020-02-01 19:30:30 -08:00
Родитель f26e5041f1
Коммит 0389ed6a51
8 изменённых файлов: 338 добавлений и 256 удалений

Просмотреть файл

@ -42,7 +42,7 @@ namespace SEALNetExamples
be large enough to support the desired computation; otherwise the result is be large enough to support the desired computation; otherwise the result is
impossible to make sense of even with the secret key. 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 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 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 object. This is a heavy class that checks the validity and properties of the
parameters we just set. 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. Print the parameters that we have chosen.
@ -150,29 +163,29 @@ namespace SEALNetExamples
automatically generates the public and secret key, which can immediately be automatically generates the public and secret key, which can immediately be
read to local variables. read to local variables.
*/ */
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
/* /*
To be able to encrypt we need to construct an instance of Encryptor. Note To be able to encrypt we need to construct an instance of Encryptor. Note
that the Encryptor only requires the public key, as expected. 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 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 a real use-case the Evaluator would not be constructed by the same party
that holds the secret key. 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, 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 so we need to also construct an instance of Decryptor. Note that the Decryptor
requires the secret key. 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 As an example, we evaluate the degree 4 polynomial
@ -199,14 +212,14 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
int x = 6; 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}."); Console.WriteLine($"Express x = {x} as a plaintext polynomial 0x{xPlain}.");
/* /*
We then encrypt the plaintext, producing a ciphertext. We then encrypt the plaintext, producing a ciphertext.
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Ciphertext xEncrypted = new Ciphertext(); using Ciphertext xEncrypted = new Ciphertext();
Console.WriteLine("Encrypt xPlain to xEncrypted."); Console.WriteLine("Encrypt xPlain to xEncrypted.");
encryptor.Encrypt(xPlain, xEncrypted); encryptor.Encrypt(xPlain, xEncrypted);
@ -229,7 +242,7 @@ namespace SEALNetExamples
We decrypt the ciphertext and print the resulting plaintext in order to We decrypt the ciphertext and print the resulting plaintext in order to
demonstrate correctness of the encryption. demonstrate correctness of the encryption.
*/ */
Plaintext xDecrypted = new Plaintext(); using Plaintext xDecrypted = new Plaintext();
Console.Write(" + decryption of encrypted_x: "); Console.Write(" + decryption of encrypted_x: ");
decryptor.Decrypt(xEncrypted, xDecrypted); decryptor.Decrypt(xEncrypted, xDecrypted);
Console.WriteLine($"0x{xDecrypted} ...... Correct."); Console.WriteLine($"0x{xDecrypted} ...... Correct.");
@ -254,9 +267,9 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute xSqPlusOne (x^2+1)."); Console.WriteLine("Compute xSqPlusOne (x^2+1).");
Ciphertext xSqPlusOne = new Ciphertext(); using Ciphertext xSqPlusOne = new Ciphertext();
evaluator.Square(xEncrypted, xSqPlusOne); evaluator.Square(xEncrypted, xSqPlusOne);
Plaintext plainOne = new Plaintext("1"); using Plaintext plainOne = new Plaintext("1");
evaluator.AddPlainInplace(xSqPlusOne, plainOne); evaluator.AddPlainInplace(xSqPlusOne, plainOne);
/* /*
@ -274,7 +287,7 @@ namespace SEALNetExamples
Even though the size has grown, decryption works as usual as long as noise Even though the size has grown, decryption works as usual as long as noise
budget has not reached 0. budget has not reached 0.
*/ */
Plaintext decryptedResult = new Plaintext(); using Plaintext decryptedResult = new Plaintext();
Console.Write(" + decryption of xSqPlusOne: "); Console.Write(" + decryption of xSqPlusOne: ");
decryptor.Decrypt(xSqPlusOne, decryptedResult); decryptor.Decrypt(xSqPlusOne, decryptedResult);
Console.WriteLine($"0x{decryptedResult} ...... Correct."); Console.WriteLine($"0x{decryptedResult} ...... Correct.");
@ -284,7 +297,7 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute xPlusOneSq ((x+1)^2)."); Console.WriteLine("Compute xPlusOneSq ((x+1)^2).");
Ciphertext xPlusOneSq = new Ciphertext(); using Ciphertext xPlusOneSq = new Ciphertext();
evaluator.AddPlain(xEncrypted, plainOne, xPlusOneSq); evaluator.AddPlain(xEncrypted, plainOne, xPlusOneSq);
evaluator.SquareInplace(xPlusOneSq); evaluator.SquareInplace(xPlusOneSq);
Console.WriteLine($" + size of xPlusOneSq: {xPlusOneSq.Size}"); Console.WriteLine($" + size of xPlusOneSq: {xPlusOneSq.Size}");
@ -299,8 +312,8 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute encryptedResult (4(x^2+1)(x+1)^2)."); Console.WriteLine("Compute encryptedResult (4(x^2+1)(x+1)^2).");
Ciphertext encryptedResult = new Ciphertext(); using Ciphertext encryptedResult = new Ciphertext();
Plaintext plainFour = new Plaintext("4"); using Plaintext plainFour = new Plaintext("4");
evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour); evaluator.MultiplyPlainInplace(xSqPlusOne, plainFour);
evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult); evaluator.Multiply(xSqPlusOne, xPlusOneSq, encryptedResult);
Console.WriteLine($" + size of encrypted_result: {encryptedResult.Size}"); Console.WriteLine($" + size of encrypted_result: {encryptedResult.Size}");
@ -341,7 +354,7 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Generate locally usable relinearization keys."); 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. We now repeat the computation relinearizing after each multiplication.
@ -349,7 +362,7 @@ namespace SEALNetExamples
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute and relinearize xSquared (x^2),"); Console.WriteLine("Compute and relinearize xSquared (x^2),");
Console.WriteLine(new string(' ', 13) + "then compute xSqPlusOne (x^2+1)"); Console.WriteLine(new string(' ', 13) + "then compute xSqPlusOne (x^2+1)");
Ciphertext xSquared = new Ciphertext(); using Ciphertext xSquared = new Ciphertext();
evaluator.Square(xEncrypted, xSquared); evaluator.Square(xEncrypted, xSquared);
Console.WriteLine($" + size of xSquared: {xSquared.Size}"); Console.WriteLine($" + size of xSquared: {xSquared.Size}");
evaluator.RelinearizeInplace(xSquared, relinKeys); evaluator.RelinearizeInplace(xSquared, relinKeys);
@ -363,7 +376,7 @@ namespace SEALNetExamples
Console.WriteLine($"0x{decryptedResult} ...... Correct."); Console.WriteLine($"0x{decryptedResult} ...... Correct.");
Utilities.PrintLine(); Utilities.PrintLine();
Ciphertext xPlusOne = new Ciphertext(); using Ciphertext xPlusOne = new Ciphertext();
Console.WriteLine("Compute xPlusOne (x+1),"); Console.WriteLine("Compute xPlusOne (x+1),");
Console.WriteLine(new string(' ', 13) + Console.WriteLine(new string(' ', 13) +
"then compute and relinearize xPlusOneSq ((x+1)^2)."); "then compute and relinearize xPlusOneSq ((x+1)^2).");

Просмотреть файл

@ -72,7 +72,7 @@ namespace SEALNetExamples
However, advanced users will probably prefer more efficient approaches, However, advanced users will probably prefer more efficient approaches,
such as the BatchEncoder or the CKKSEncoder. such as the BatchEncoder or the CKKSEncoder.
*/ */
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV); using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
ulong polyModulusDegree = 4096; ulong polyModulusDegree = 4096;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
@ -84,41 +84,41 @@ namespace SEALNetExamples
will be incorrect. will be incorrect.
*/ */
parms.PlainModulus = new SmallModulus(512); parms.PlainModulus = new SmallModulus(512);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
/* /*
We create an IntegerEncoder. 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 First, we encode two integers as plaintext polynomials. Note that encoding
is not encryption: at this point nothing is encrypted. is not encryption: at this point nothing is encrypted.
*/ */
int value1 = 5; int value1 = 5;
Plaintext plain1 = encoder.Encode(value1); using Plaintext plain1 = encoder.Encode(value1);
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine($"Encode {value1} as polynomial {plain1} (plain1),"); Console.WriteLine($"Encode {value1} as polynomial {plain1} (plain1),");
int value2 = -7; int value2 = -7;
Plaintext plain2 = encoder.Encode(value2); using Plaintext plain2 = encoder.Encode(value2);
Console.WriteLine(new string(' ', 13) Console.WriteLine(new string(' ', 13)
+ $"Encode {value2} as polynomial {plain2} (plain2),"); + $"Encode {value2} as polynomial {plain2} (plain2),");
/* /*
Now we can encrypt the plaintext polynomials. Now we can encrypt the plaintext polynomials.
*/ */
Ciphertext encrypted1 = new Ciphertext(); using Ciphertext encrypted1 = new Ciphertext();
Ciphertext encrypted2 = new Ciphertext(); using Ciphertext encrypted2 = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encrypt plain1 to encrypted1 and plain2 to encrypted2."); Console.WriteLine("Encrypt plain1 to encrypted1 and plain2 to encrypted2.");
encryptor.Encrypt(plain1, encrypted1); encryptor.Encrypt(plain1, encrypted1);
@ -132,7 +132,7 @@ namespace SEALNetExamples
As a simple example, we compute (-encrypted1 + encrypted2) * encrypted2. As a simple example, we compute (-encrypted1 + encrypted2) * encrypted2.
*/ */
encryptor.Encrypt(plain2, encrypted2); encryptor.Encrypt(plain2, encrypted2);
Ciphertext encryptedResult = new Ciphertext(); using Ciphertext encryptedResult = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute encrypted_result = (-encrypted1 + encrypted2) * encrypted2."); Console.WriteLine("Compute encrypted_result = (-encrypted1 + encrypted2) * encrypted2.");
evaluator.Negate(encrypted1, encryptedResult); evaluator.Negate(encrypted1, encryptedResult);
@ -141,7 +141,7 @@ namespace SEALNetExamples
Console.WriteLine(" + Noise budget in encryptedResult: {0} bits", Console.WriteLine(" + Noise budget in encryptedResult: {0} bits",
decryptor.InvariantNoiseBudget(encryptedResult)); decryptor.InvariantNoiseBudget(encryptedResult));
Plaintext plainResult = new Plaintext(); using Plaintext plainResult = new Plaintext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Decrypt encrypted_result to plain_result."); Console.WriteLine("Decrypt encrypted_result to plain_result.");
decryptor.Decrypt(encryptedResult, plainResult); decryptor.Decrypt(encryptedResult, plainResult);
@ -177,7 +177,7 @@ namespace SEALNetExamples
with BFV, and when used properly will result in implementations outperforming with BFV, and when used properly will result in implementations outperforming
anything done with the IntegerEncoder. anything done with the IntegerEncoder.
*/ */
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV); using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
@ -190,7 +190,7 @@ namespace SEALNetExamples
*/ */
parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20); parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
@ -198,21 +198,21 @@ namespace SEALNetExamples
We can verify that batching is indeed enabled by looking at the encryption We can verify that batching is indeed enabled by looking at the encryption
parameter qualifiers created by SEALContext. parameter qualifiers created by SEALContext.
*/ */
var qualifiers = context.FirstContextData.Qualifiers; using var qualifiers = context.FirstContextData.Qualifiers;
Console.WriteLine($"Batching enabled: {qualifiers.UsingBatching}"); Console.WriteLine($"Batching enabled: {qualifiers.UsingBatching}");
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
/* /*
Batching is done through an instance of the BatchEncoder class. 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 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. First we use BatchEncoder to encode the matrix into a plaintext polynomial.
*/ */
Plaintext plainMatrix = new Plaintext(); using Plaintext plainMatrix = new Plaintext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encode plaintext matrix:"); Console.WriteLine("Encode plaintext matrix:");
batchEncoder.Encode(podMatrix, plainMatrix); batchEncoder.Encode(podMatrix, plainMatrix);
@ -264,7 +264,7 @@ namespace SEALNetExamples
/* /*
Next we encrypt the encoded plaintext. Next we encrypt the encoded plaintext.
*/ */
Ciphertext encryptedMatrix = new Ciphertext(); using Ciphertext encryptedMatrix = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encrypt plainMatrix to encryptedMatrix."); Console.WriteLine("Encrypt plainMatrix to encryptedMatrix.");
encryptor.Encrypt(plainMatrix, encryptedMatrix); encryptor.Encrypt(plainMatrix, encryptedMatrix);
@ -286,7 +286,7 @@ namespace SEALNetExamples
{ {
podMatrix2[i] = (i % 2) + 1; podMatrix2[i] = (i % 2) + 1;
} }
Plaintext plainMatrix2 = new Plaintext(); using Plaintext plainMatrix2 = new Plaintext();
batchEncoder.Encode(podMatrix2, plainMatrix2); batchEncoder.Encode(podMatrix2, plainMatrix2);
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("Second input plaintext matrix:"); 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. We decrypt and decompose the plaintext to recover the result as a matrix.
*/ */
Plaintext plainResult = new Plaintext(); using Plaintext plainResult = new Plaintext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Decrypt and decode result."); Console.WriteLine("Decrypt and decode result.");
decryptor.Decrypt(encryptedMatrix, plainResult); decryptor.Decrypt(encryptedMatrix, plainResult);
@ -349,7 +349,7 @@ namespace SEALNetExamples
`CKKS_Basics.cs'. In this example we use CoeffModulus.Create to `CKKS_Basics.cs'. In this example we use CoeffModulus.Create to
generate 5 40-bit prime numbers. generate 5 40-bit prime numbers.
*/ */
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
@ -359,24 +359,24 @@ namespace SEALNetExamples
/* /*
We create the SEALContext as usual and print the parameters. We create the SEALContext as usual and print the parameters.
*/ */
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
/* /*
Keys are created the same way as for the BFV scheme. Keys are created the same way as for the BFV scheme.
*/ */
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
/* /*
We also set up an Encryptor, Evaluator, and Decryptor as usual. We also set up an Encryptor, Evaluator, and Decryptor as usual.
*/ */
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
/* /*
To create CKKS plaintexts we need a special encoder: there is no other way 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 looks a lot like what BatchEncoder does for the BFV scheme, but the theory
behind it is completely different. 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 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 we have little to worry about in this regard. For this simple example a 30-bit
scale is more than enough. scale is more than enough.
*/ */
Plaintext plain = new Plaintext(); using Plaintext plain = new Plaintext();
double scale = Math.Pow(2.0, 30); double scale = Math.Pow(2.0, 30);
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encode input vector."); Console.WriteLine("Encode input vector.");
@ -436,7 +436,7 @@ namespace SEALNetExamples
/* /*
The vector is encrypted the same was as in BFV. The vector is encrypted the same was as in BFV.
*/ */
Ciphertext encrypted = new Ciphertext(); using Ciphertext encrypted = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encrypt input vector, square, and relinearize."); Console.WriteLine("Encrypt input vector, square, and relinearize.");
encryptor.Encrypt(plain, encrypted); encryptor.Encrypt(plain, encrypted);

Просмотреть файл

@ -44,7 +44,7 @@ namespace SEALNetExamples
node can be identified by the ParmsId of its specific encryption parameters node can be identified by the ParmsId of its specific encryption parameters
(PolyModulusDegree remains the same but CoeffModulus varies). (PolyModulusDegree remains the same but CoeffModulus varies).
*/ */
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV); using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
@ -91,7 +91,7 @@ namespace SEALNetExamples
*/ */
parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20); parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
/* /*
@ -164,10 +164,10 @@ namespace SEALNetExamples
/* /*
We create some keys and check that indeed they appear at the highest level. We create some keys and check that indeed they appear at the highest level.
*/ */
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
/* /*
In this example we create a local version of the GaloisKeys object using 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> use KeyGenerator.GaloisKeys(), which outputs a Serializable<GaloisKeys>
object for compressed serialization. object for compressed serialization.
*/ */
GaloisKeys galoisKeys = keygen.GaloisKeysLocal(); using GaloisKeys galoisKeys = keygen.GaloisKeysLocal();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Print the parameter IDs of generated elements."); Console.WriteLine("Print the parameter IDs of generated elements.");
Console.WriteLine($" + publicKey: {publicKey.ParmsId}"); Console.WriteLine($" + publicKey: {publicKey.ParmsId}");
@ -184,16 +184,16 @@ namespace SEALNetExamples
Console.WriteLine($" + relinKeys: {relinKeys.ParmsId}"); Console.WriteLine($" + relinKeys: {relinKeys.ParmsId}");
Console.WriteLine($" + galoisKeys: {galoisKeys.ParmsId}"); Console.WriteLine($" + galoisKeys: {galoisKeys.ParmsId}");
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
/* /*
In the BFV scheme plaintexts do not carry a ParmsId, but ciphertexts do. Note 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. how the freshly encrypted ciphertext is at the highest data level.
*/ */
Plaintext plain = new Plaintext("1x^3 + 2x^2 + 3x^1 + 4"); using Plaintext plain = new Plaintext("1x^3 + 2x^2 + 3x^1 + 4");
Ciphertext encrypted = new Ciphertext(); using Ciphertext encrypted = new Ciphertext();
encryptor.Encrypt(plain, encrypted); encryptor.Encrypt(plain, encrypted);
Console.WriteLine($" + plain: {plain.ParmsId} (not set in BFV)"); Console.WriteLine($" + plain: {plain.ParmsId} (not set in BFV)");
Console.WriteLine($" + encrypted: {encrypted.ParmsId}"); Console.WriteLine($" + encrypted: {encrypted.ParmsId}");
@ -309,7 +309,7 @@ namespace SEALNetExamples
not want to create the modulus switching chain, except for the highest two 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. 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 We can check that indeed the modulus switching chain has been created only
@ -320,7 +320,7 @@ namespace SEALNetExamples
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Print the modulus switching chain."); Console.WriteLine("Print the modulus switching chain.");
Console.Write("----> "); Console.Write("----> ");
for (contextData = context.KeyContextData; null != contextData; for (contextData = context2.KeyContextData; null != contextData;
contextData = contextData.NextContextData) contextData = contextData.NextContextData)
{ {
Console.WriteLine($"Level (chain index): {contextData.ChainIndex}"); Console.WriteLine($"Level (chain index): {contextData.ChainIndex}");

Просмотреть файл

@ -24,7 +24,7 @@ namespace SEALNetExamples
We start by setting up the CKKS scheme. 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 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); double scale = Math.Pow(2.0, 40);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
CKKSEncoder encoder = new CKKSEncoder(context); using CKKSEncoder encoder = new CKKSEncoder(context);
ulong slotCount = encoder.SlotCount; ulong slotCount = encoder.SlotCount;
Console.WriteLine($"Number of slots: {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 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. that encodes the given floating-point value to every slot in the vector.
*/ */
Plaintext plainCoeff3 = new Plaintext(), using Plaintext plainCoeff3 = new Plaintext(),
plainCoeff1 = new Plaintext(), plainCoeff1 = new Plaintext(),
plainCoeff0 = new Plaintext(); plainCoeff0 = new Plaintext();
encoder.Encode(3.14159265, scale, plainCoeff3); encoder.Encode(3.14159265, scale, plainCoeff3);
encoder.Encode(0.4, scale, plainCoeff1); encoder.Encode(0.4, scale, plainCoeff1);
encoder.Encode(1.0, scale, plainCoeff0); encoder.Encode(1.0, scale, plainCoeff0);
Plaintext xPlain = new Plaintext(); using Plaintext xPlain = new Plaintext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encode input vectors."); Console.WriteLine("Encode input vectors.");
encoder.Encode(input, scale, xPlain); encoder.Encode(input, scale, xPlain);
Ciphertext x1Encrypted = new Ciphertext(); using Ciphertext x1Encrypted = new Ciphertext();
encryptor.Encrypt(xPlain, x1Encrypted); encryptor.Encrypt(xPlain, x1Encrypted);
/* /*
To compute x^3 we first compute x^2 and relinearize. However, the scale has To compute x^3 we first compute x^2 and relinearize. However, the scale has
now grown to 2^80. now grown to 2^80.
*/ */
Ciphertext x3Encrypted = new Ciphertext(); using Ciphertext x3Encrypted = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute x^2 and relinearize:"); Console.WriteLine("Compute x^2 and relinearize:");
evaluator.Square(x1Encrypted, x3Encrypted); evaluator.Square(x1Encrypted, x3Encrypted);
@ -165,7 +165,7 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute and rescale PI*x."); Console.WriteLine("Compute and rescale PI*x.");
Ciphertext x1EncryptedCoeff3 = new Ciphertext(); using Ciphertext x1EncryptedCoeff3 = new Ciphertext();
evaluator.MultiplyPlain(x1Encrypted, plainCoeff3, x1EncryptedCoeff3); evaluator.MultiplyPlain(x1Encrypted, plainCoeff3, x1EncryptedCoeff3);
Console.WriteLine(" + Scale of PI*x before rescale: {0} bits", Console.WriteLine(" + Scale of PI*x before rescale: {0} bits",
Math.Log(x1EncryptedCoeff3.Scale, newBase: 2)); Math.Log(x1EncryptedCoeff3.Scale, newBase: 2));
@ -284,14 +284,14 @@ namespace SEALNetExamples
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Compute PI*x^3 + 0.4*x + 1."); 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.Add(x3Encrypted, x1Encrypted, encryptedResult);
evaluator.AddPlainInplace(encryptedResult, plainCoeff0); evaluator.AddPlainInplace(encryptedResult, plainCoeff0);
/* /*
First print the true result. First print the true result.
*/ */
Plaintext plainResult = new Plaintext(); using Plaintext plainResult = new Plaintext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Decrypt and decode PI * x ^ 3 + 0.4x + 1."); Console.WriteLine("Decrypt and decode PI * x ^ 3 + 0.4x + 1.");
Console.WriteLine(" + Expected result:"); Console.WriteLine(" + Expected result:");

Просмотреть файл

@ -18,26 +18,26 @@ namespace SEALNetExamples
{ {
Utilities.PrintExampleBanner("Example: Rotation / Rotation in BFV"); Utilities.PrintExampleBanner("Example: Rotation / Rotation in BFV");
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV); using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV);
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20); parms.PlainModulus = PlainModulus.Batching(polyModulusDegree, 20);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
BatchEncoder batchEncoder = new BatchEncoder(context); using BatchEncoder batchEncoder = new BatchEncoder(context);
ulong slotCount = batchEncoder.SlotCount; ulong slotCount = batchEncoder.SlotCount;
ulong rowSize = slotCount / 2; ulong rowSize = slotCount / 2;
Console.WriteLine($"Plaintext matrix row size: {rowSize}"); Console.WriteLine($"Plaintext matrix row size: {rowSize}");
@ -61,10 +61,10 @@ namespace SEALNetExamples
the plaintext as usual. the plaintext as usual.
*/ */
Utilities.PrintLine(); Utilities.PrintLine();
Plaintext plainMatrix = new Plaintext(); using Plaintext plainMatrix = new Plaintext();
Console.WriteLine("Encode and encrypt."); Console.WriteLine("Encode and encrypt.");
batchEncoder.Encode(podMatrix, plainMatrix); batchEncoder.Encode(podMatrix, plainMatrix);
Ciphertext encryptedMatrix = new Ciphertext(); using Ciphertext encryptedMatrix = new Ciphertext();
encryptor.Encrypt(plainMatrix, encryptedMatrix); encryptor.Encrypt(plainMatrix, encryptedMatrix);
Console.WriteLine(" + Noise budget in fresh encryption: {0} bits", Console.WriteLine(" + Noise budget in fresh encryption: {0} bits",
decryptor.InvariantNoiseBudget(encryptedMatrix)); decryptor.InvariantNoiseBudget(encryptedMatrix));
@ -74,7 +74,7 @@ namespace SEALNetExamples
Rotations require yet another type of special key called `Galois keys'. These Rotations require yet another type of special key called `Galois keys'. These
are easily obtained from the KeyGenerator. 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. Now rotate both matrix rows 3 steps to the left, decrypt, decode, and print.
@ -82,7 +82,7 @@ namespace SEALNetExamples
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Rotate rows 3 steps left."); Console.WriteLine("Rotate rows 3 steps left.");
evaluator.RotateRowsInplace(encryptedMatrix, 3, galKeys); evaluator.RotateRowsInplace(encryptedMatrix, 3, galKeys);
Plaintext plainResult = new Plaintext(); using Plaintext plainResult = new Plaintext();
Console.WriteLine(" + Noise budget after rotation: {0} bits", Console.WriteLine(" + Noise budget after rotation: {0} bits",
decryptor.InvariantNoiseBudget(encryptedMatrix)); decryptor.InvariantNoiseBudget(encryptedMatrix));
Console.WriteLine(" + Decrypt and decode ...... Correct."); Console.WriteLine(" + Decrypt and decode ...... Correct.");
@ -130,27 +130,27 @@ namespace SEALNetExamples
{ {
Utilities.PrintExampleBanner("Example: Rotation / Rotation in CKKS"); Utilities.PrintExampleBanner("Example: Rotation / Rotation in CKKS");
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.Create( parms.CoeffModulus = CoeffModulus.Create(
polyModulusDegree, new int[] { 40, 40, 40, 40, 40 }); polyModulusDegree, new int[] { 40, 40, 40, 40, 40 });
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
RelinKeys relinKeys = keygen.RelinKeysLocal(); using RelinKeys relinKeys = keygen.RelinKeysLocal();
GaloisKeys galKeys = keygen.GaloisKeysLocal(); using GaloisKeys galKeys = keygen.GaloisKeysLocal();
Encryptor encryptor = new Encryptor(context, publicKey); using Encryptor encryptor = new Encryptor(context, publicKey);
Evaluator evaluator = new Evaluator(context); using Evaluator evaluator = new Evaluator(context);
Decryptor decryptor = new Decryptor(context, secretKey); using Decryptor decryptor = new Decryptor(context, secretKey);
CKKSEncoder ckksEncoder = new CKKSEncoder(context); using CKKSEncoder ckksEncoder = new CKKSEncoder(context);
ulong slotCount = ckksEncoder.SlotCount; ulong slotCount = ckksEncoder.SlotCount;
Console.WriteLine($"Number of slots: {slotCount}"); Console.WriteLine($"Number of slots: {slotCount}");
@ -168,12 +168,12 @@ namespace SEALNetExamples
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Encode and encrypt."); Console.WriteLine("Encode and encrypt.");
Plaintext plain = new Plaintext(); using Plaintext plain = new Plaintext();
ckksEncoder.Encode(input, scale, plain); ckksEncoder.Encode(input, scale, plain);
Ciphertext encrypted = new Ciphertext(); using Ciphertext encrypted = new Ciphertext();
encryptor.Encrypt(plain, encrypted); encryptor.Encrypt(plain, encrypted);
Ciphertext rotated = new Ciphertext(); using Ciphertext rotated = new Ciphertext();
Utilities.PrintLine(); Utilities.PrintLine();
Console.WriteLine("Rotate 2 steps left."); Console.WriteLine("Rotate 2 steps left.");
evaluator.RotateVector(encrypted, 2, galKeys, rotated); evaluator.RotateVector(encrypted, 2, galKeys, rotated);

Просмотреть файл

@ -28,6 +28,7 @@ namespace SEALNetExamples
if (!Serialization.IsSupportedComprMode(ComprModeType.Deflate)) if (!Serialization.IsSupportedComprMode(ComprModeType.Deflate))
{ {
Console.WriteLine("ZLIB support is not enabled; this example is not available."); Console.WriteLine("ZLIB support is not enabled; this example is not available.");
Console.WriteLine();
return; return;
} }
@ -53,7 +54,7 @@ namespace SEALNetExamples
*/ */
{ {
ulong polyModulusDegree = 8192; ulong polyModulusDegree = 8192;
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.Create( parms.CoeffModulus = CoeffModulus.Create(
polyModulusDegree, new int[]{ 50, 20, 50 }); polyModulusDegree, new int[]{ 50, 20, 50 });
@ -134,7 +135,7 @@ namespace SEALNetExamples
we need to seek our stream back to the beginning. we need to seek our stream back to the beginning.
*/ */
buffer.Seek(0, SeekOrigin.Begin); buffer.Seek(0, SeekOrigin.Begin);
EncryptionParameters parms2 = new EncryptionParameters(); using EncryptionParameters parms2 = new EncryptionParameters();
parms2.Load(buffer); parms2.Load(buffer);
/* /*
@ -149,7 +150,7 @@ namespace SEALNetExamples
and creates the required keys. and creates the required keys.
*/ */
{ {
EncryptionParameters parms = new EncryptionParameters(); using EncryptionParameters parms = new EncryptionParameters();
parms.Load(parmsStream); parms.Load(parmsStream);
/* /*
@ -158,11 +159,11 @@ namespace SEALNetExamples
*/ */
parmsStream.Seek(0, SeekOrigin.Begin); parmsStream.Seek(0, SeekOrigin.Begin);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
SecretKey sk = keygen.SecretKey; using SecretKey sk = keygen.SecretKey;
PublicKey pk = keygen.PublicKey; using PublicKey pk = keygen.PublicKey;
/* /*
We need to save the secret key so we can decrypt later. 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 must be expanded before being used in computations; this is automatically
done by deserialization. done by deserialization.
*/ */
Serializable<RelinKeys> rlk = keygen.RelinKeys(); using Serializable<RelinKeys> rlk = keygen.RelinKeys();
/* /*
Before continuing, we demonstrate the significant space saving from this Before continuing, we demonstrate the significant space saving from this
@ -192,7 +193,7 @@ namespace SEALNetExamples
*/ */
long sizeRlk = rlk.Save(dataStream); long sizeRlk = rlk.Save(dataStream);
RelinKeys rlkLocal = keygen.RelinKeysLocal(); using RelinKeys rlkLocal = keygen.RelinKeysLocal();
long sizeRlkLocal = rlkLocal.Save(dataStream); long sizeRlkLocal = rlkLocal.Save(dataStream);
/* /*
@ -214,14 +215,14 @@ namespace SEALNetExamples
*/ */
double scale = Math.Pow(2.0, 20); double scale = Math.Pow(2.0, 20);
CKKSEncoder encoder = new CKKSEncoder(context); CKKSEncoder encoder = new CKKSEncoder(context);
Plaintext plain1 = new Plaintext(), using Plaintext plain1 = new Plaintext(),
plain2 = new Plaintext(); plain2 = new Plaintext();
encoder.Encode(2.3, scale, plain1); encoder.Encode(2.3, scale, plain1);
encoder.Encode(4.5, scale, plain2); encoder.Encode(4.5, scale, plain2);
Encryptor encryptor = new Encryptor(context, pk); using Encryptor encryptor = new Encryptor(context, pk);
Ciphertext encrypted1 = new Ciphertext(), using Ciphertext encrypted1 = new Ciphertext(),
encrypted2 = new Ciphertext(); encrypted2 = new Ciphertext();
encryptor.Encrypt(plain1, encrypted1); encryptor.Encrypt(plain1, encrypted1);
encryptor.Encrypt(plain2, encrypted2); encryptor.Encrypt(plain2, encrypted2);
@ -242,9 +243,9 @@ namespace SEALNetExamples
To use symmetric-key encryption, we need to set up the Encryptor with the To use symmetric-key encryption, we need to set up the Encryptor with the
secret key instead. secret key instead.
*/ */
Encryptor symEncryptor = new Encryptor(context, sk); using Encryptor symEncryptor = new Encryptor(context, sk);
Serializable<Ciphertext> symEncrypted1 = symEncryptor.EncryptSymmetric(plain1); using Serializable<Ciphertext> symEncrypted1 = symEncryptor.EncryptSymmetric(plain1);
Serializable<Ciphertext> symEncrypted2 = symEncryptor.EncryptSymmetric(plain2); using Serializable<Ciphertext> symEncrypted2 = symEncryptor.EncryptSymmetric(plain2);
/* /*
Before continuing, we demonstrate the significant space saving from this Before continuing, we demonstrate the significant space saving from this
@ -294,20 +295,20 @@ namespace SEALNetExamples
SEALContext and set up an Evaluator here. SEALContext and set up an Evaluator here.
*/ */
{ {
EncryptionParameters parms = new EncryptionParameters(); using EncryptionParameters parms = new EncryptionParameters();
parms.Load(parmsStream); parms.Load(parmsStream);
parmsStream.Seek(0, SeekOrigin.Begin); 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 Next we need to load relinearization keys and the ciphertexts from our
dataStream. dataStream.
*/ */
RelinKeys rlk = new RelinKeys(); using RelinKeys rlk = new RelinKeys();
Ciphertext encrypted1 = new Ciphertext(), using Ciphertext encrypted1 = new Ciphertext(),
encrypted2 = new Ciphertext(); encrypted2 = new Ciphertext();
/* /*
Deserialization is as easy as serialization. Deserialization is as easy as serialization.
@ -319,7 +320,7 @@ namespace SEALNetExamples
/* /*
Compute the product, rescale, and relinearize. Compute the product, rescale, and relinearize.
*/ */
Ciphertext encryptedProd = new Ciphertext(); using Ciphertext encryptedProd = new Ciphertext();
evaluator.Multiply(encrypted1, encrypted2, encryptedProd); evaluator.Multiply(encrypted1, encrypted2, encryptedProd);
evaluator.RelinearizeInplace(encryptedProd, rlk); evaluator.RelinearizeInplace(encryptedProd, rlk);
evaluator.RescaleToNextInplace(encryptedProd); evaluator.RescaleToNextInplace(encryptedProd);
@ -345,23 +346,23 @@ namespace SEALNetExamples
In the final step the client decrypts the result. In the final step the client decrypts the result.
*/ */
{ {
EncryptionParameters parms = new EncryptionParameters(); using EncryptionParameters parms = new EncryptionParameters();
parms.Load(parmsStream); parms.Load(parmsStream);
parmsStream.Seek(0, SeekOrigin.Begin); parmsStream.Seek(0, SeekOrigin.Begin);
SEALContext context = new SEALContext(parms); using SEALContext context = new SEALContext(parms);
/* /*
Load back the secret key from skStream. Load back the secret key from skStream.
*/ */
SecretKey sk = new SecretKey(); using SecretKey sk = new SecretKey();
sk.Load(context, skStream); sk.Load(context, skStream);
Decryptor decryptor = new Decryptor(context, sk); using Decryptor decryptor = new Decryptor(context, sk);
CKKSEncoder encoder = new CKKSEncoder(context); using CKKSEncoder encoder = new CKKSEncoder(context);
Ciphertext encryptedResult = new Ciphertext(); using Ciphertext encryptedResult = new Ciphertext();
encryptedResult.Load(context, dataStream); encryptedResult.Load(context, dataStream);
Plaintext plainResult = new Plaintext(); using Plaintext plainResult = new Plaintext();
decryptor.Decrypt(encryptedResult, plainResult); decryptor.Decrypt(encryptedResult, plainResult);
List<double> result = new List<double>(); List<double> result = new List<double>();
encoder.Decode(plainResult, result); encoder.Decode(plainResult, result);
@ -372,4 +373,4 @@ namespace SEALNetExamples
} }
} }
} }
} }

Просмотреть файл

@ -17,55 +17,73 @@ namespace SEALNetExamples
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
EncryptionParameters parms = context.FirstContextData.Parms; using EncryptionParameters parms = context.FirstContextData.Parms;
SmallModulus plainModulus = parms.PlainModulus; using SmallModulus plainModulus = parms.PlainModulus;
ulong polyModulusDegree = parms.PolyModulusDegree; ulong polyModulusDegree = parms.PolyModulusDegree;
Console.Write("Generating secret/public keys: "); Console.Write("Generating secret/public keys: ");
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
Console.WriteLine("Done"); Console.WriteLine("Done");
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
RelinKeys relinKeys = null; Func<RelinKeys> GetRelinKeys = () => {
GaloisKeys galKeys = null; if (context.UsingKeyswitching)
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)
{ {
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;
}
};
/* Func<GaloisKeys> GetGaloisKeys = () => {
Generate Galois keys. In larger examples the Galois keys can use a lot of if (context.UsingKeyswitching)
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 if (!context.KeyContextData.Qualifiers.UsingBatching)
memory pool allocation size. The key generation can also take a long time, {
as can be observed from the print-out. Console.WriteLine("Given encryption parameters do not support batching.");
*/ return null;
Console.Write($"Generating Galois keys: "); }
timer = Stopwatch.StartNew();
galKeys = keygen.GaloisKeysLocal();
micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
Console.WriteLine($"Done [{micros} microseconds]");
}
Encryptor encryptor = new Encryptor(context, publicKey); /*
Decryptor decryptor = new Decryptor(context, secretKey); Generate Galois keys. In larger examples the Galois keys can use a lot of
Evaluator evaluator = new Evaluator(context); memory, which can be a problem in constrained systems. The user should
BatchEncoder batchEncoder = new BatchEncoder(context); try some of the larger runs of the test and observe their effect on the
IntegerEncoder encoder = new IntegerEncoder(context); 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. 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 into the polynomial. Note how the plaintext we create is of the exactly
right size so unnecessary reallocations are avoided. right size so unnecessary reallocations are avoided.
*/ */
Plaintext plain = new Plaintext(parms.PolyModulusDegree, 0); using Plaintext plain = new Plaintext(parms.PolyModulusDegree, 0);
timeBatchSum.Start(); timeBatchSum.Start();
batchEncoder.Encode(podValues, plain); batchEncoder.Encode(podValues, plain);
timeBatchSum.Stop(); timeBatchSum.Stop();
@ -132,7 +150,7 @@ namespace SEALNetExamples
to hold the encryption with these encryption parameters. We encrypt to hold the encryption with these encryption parameters. We encrypt
our random batched matrix here. our random batched matrix here.
*/ */
Ciphertext encrypted = new Ciphertext(context); using Ciphertext encrypted = new Ciphertext(context);
timeEncryptSum.Start(); timeEncryptSum.Start();
encryptor.Encrypt(plain, encrypted); encryptor.Encrypt(plain, encrypted);
timeEncryptSum.Stop(); timeEncryptSum.Stop();
@ -141,7 +159,7 @@ namespace SEALNetExamples
[Decryption] [Decryption]
We decrypt what we just encrypted. We decrypt what we just encrypted.
*/ */
Plaintext plain2 = new Plaintext(polyModulusDegree, 0); using Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
timeDecryptSum.Start(); timeDecryptSum.Start();
decryptor.Decrypt(encrypted, plain2); decryptor.Decrypt(encrypted, plain2);
timeDecryptSum.Stop(); timeDecryptSum.Stop();
@ -154,9 +172,9 @@ namespace SEALNetExamples
[Add] [Add]
We create two ciphertexts and perform a few additions with them. 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); encryptor.Encrypt(encoder.Encode(i), encrypted1);
Ciphertext encrypted2 = new Ciphertext(context); using Ciphertext encrypted2 = new Ciphertext(context);
encryptor.Encrypt(encoder.Encode(i + 1), encrypted2); encryptor.Encrypt(encoder.Encode(i + 1), encrypted2);
timeAddSum.Start(); timeAddSum.Start();
@ -286,53 +304,71 @@ namespace SEALNetExamples
Utilities.PrintParameters(context); Utilities.PrintParameters(context);
Console.WriteLine(); Console.WriteLine();
EncryptionParameters parms = context.FirstContextData.Parms; using EncryptionParameters parms = context.FirstContextData.Parms;
ulong polyModulusDegree = parms.PolyModulusDegree; ulong polyModulusDegree = parms.PolyModulusDegree;
Console.Write("Generating secret/public keys: "); Console.Write("Generating secret/public keys: ");
KeyGenerator keygen = new KeyGenerator(context); using KeyGenerator keygen = new KeyGenerator(context);
Console.WriteLine("Done"); Console.WriteLine("Done");
SecretKey secretKey = keygen.SecretKey; using SecretKey secretKey = keygen.SecretKey;
PublicKey publicKey = keygen.PublicKey; using PublicKey publicKey = keygen.PublicKey;
RelinKeys relinKeys = null; Func<RelinKeys> GetRelinKeys = () => {
GaloisKeys galKeys = null; if (context.UsingKeyswitching)
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)
{ {
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;
}
};
/* Func<GaloisKeys> GetGaloisKeys = () => {
Generate Galois keys. In larger examples the Galois keys can use a lot of if (context.UsingKeyswitching)
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 if (!context.KeyContextData.Qualifiers.UsingBatching)
memory pool allocation size. The key generation can also take a long time, {
as can be observed from the print-out. Console.WriteLine("Given encryption parameters do not support batching.");
*/ return null;
Console.Write($"Generating Galois keys: "); }
timer = Stopwatch.StartNew();
galKeys = keygen.GaloisKeysLocal();
micros = (int)(timer.Elapsed.TotalMilliseconds * 1000);
Console.WriteLine($"Done [{micros} microseconds]");
}
Encryptor encryptor = new Encryptor(context, publicKey); /*
Decryptor decryptor = new Decryptor(context, secretKey); Generate Galois keys. In larger examples the Galois keys can use a lot of
Evaluator evaluator = new Evaluator(context); memory, which can be a problem in constrained systems. The user should
CKKSEncoder ckksEncoder = new CKKSEncoder(context); 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 timeEncodeSum = new Stopwatch();
Stopwatch timeDecodeSum = new Stopwatch(); Stopwatch timeDecodeSum = new Stopwatch();
@ -374,7 +410,7 @@ namespace SEALNetExamples
from parms. from parms.
*/ */
double scale = Math.Sqrt(parms.CoeffModulus.Last().Value); 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); (ulong)parms.CoeffModulus.Count(), 0);
timeEncodeSum.Start(); timeEncodeSum.Start();
ckksEncoder.Encode(podValues, scale, plain); ckksEncoder.Encode(podValues, scale, plain);
@ -391,7 +427,7 @@ namespace SEALNetExamples
/* /*
[Encryption] [Encryption]
*/ */
Ciphertext encrypted = new Ciphertext(context); using Ciphertext encrypted = new Ciphertext(context);
timeEncryptSum.Start(); timeEncryptSum.Start();
encryptor.Encrypt(plain, encrypted); encryptor.Encrypt(plain, encrypted);
timeEncryptSum.Stop(); timeEncryptSum.Stop();
@ -399,7 +435,7 @@ namespace SEALNetExamples
/* /*
[Decryption] [Decryption]
*/ */
Plaintext plain2 = new Plaintext(polyModulusDegree, 0); using Plaintext plain2 = new Plaintext(polyModulusDegree, 0);
timeDecryptSum.Start(); timeDecryptSum.Start();
decryptor.Decrypt(encrypted, plain2); decryptor.Decrypt(encrypted, plain2);
timeDecryptSum.Stop(); timeDecryptSum.Stop();
@ -407,10 +443,10 @@ namespace SEALNetExamples
/* /*
[Add] [Add]
*/ */
Ciphertext encrypted1 = new Ciphertext(context); using Ciphertext encrypted1 = new Ciphertext(context);
ckksEncoder.Encode(i + 1, plain); ckksEncoder.Encode(i + 1, plain);
encryptor.Encrypt(plain, encrypted1); encryptor.Encrypt(plain, encrypted1);
Ciphertext encrypted2 = new Ciphertext(context); using Ciphertext encrypted2 = new Ciphertext(context);
ckksEncoder.Encode(i + 1, plain2); ckksEncoder.Encode(i + 1, plain2);
encryptor.Encrypt(plain2, encrypted2); encryptor.Encrypt(plain2, encrypted2);
timeAddSum.Start(); timeAddSum.Start();
@ -529,26 +565,35 @@ namespace SEALNetExamples
{ {
Utilities.PrintExampleBanner("BFV Performance Test with Degrees: 4096, 8192, and 16384"); 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; ulong polyModulusDegree = 4096;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
parms.PlainModulus = new SmallModulus(786433); parms.PlainModulus = new SmallModulus(786433);
BFVPerformanceTest(new SEALContext(parms)); using (SEALContext context = new SEALContext(parms))
{
BFVPerformanceTest(context);
}
Console.WriteLine(); Console.WriteLine();
polyModulusDegree = 8192; polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
parms.PlainModulus = new SmallModulus(786433); parms.PlainModulus = new SmallModulus(786433);
BFVPerformanceTest(new SEALContext(parms)); using (SEALContext context = new SEALContext(parms))
{
BFVPerformanceTest(context);
}
Console.WriteLine(); Console.WriteLine();
polyModulusDegree = 16384; polyModulusDegree = 16384;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
parms.PlainModulus = new SmallModulus(786433); 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. Comment out the following to run the biggest example.
@ -558,7 +603,10 @@ namespace SEALNetExamples
//parms.PolyModulusDegree = polyModulusDegree; //parms.PolyModulusDegree = polyModulusDegree;
//parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); //parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
//parms.PlainModulus = new SmallModulus(786433); //parms.PlainModulus = new SmallModulus(786433);
//BFVPerformanceTest(new SEALContext(parms)); //using (SEALContext context = new SEALContext(parms))
//{
// BFVPerformanceTest(context);
//}
} }
private static void ExampleBFVPerformanceCustom() private static void ExampleBFVPerformanceCustom()
@ -580,7 +628,7 @@ namespace SEALNetExamples
string banner = $"BFV Performance Test with Degree: {polyModulusDegree}"; string banner = $"BFV Performance Test with Degree: {polyModulusDegree}";
Utilities.PrintExampleBanner(banner); Utilities.PrintExampleBanner(banner);
EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV) using EncryptionParameters parms = new EncryptionParameters(SchemeType.BFV)
{ {
PolyModulusDegree = polyModulusDegree, PolyModulusDegree = polyModulusDegree,
CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree) CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree)
@ -593,7 +641,11 @@ namespace SEALNetExamples
{ {
parms.PlainModulus = new SmallModulus(786433); parms.PlainModulus = new SmallModulus(786433);
} }
BFVPerformanceTest(new SEALContext(parms));
using (SEALContext context = new SEALContext(parms))
{
BFVPerformanceTest(context);
}
} }
private static void ExampleCKKSPerformanceDefault() private static void ExampleCKKSPerformanceDefault()
@ -602,23 +654,32 @@ namespace SEALNetExamples
// It is not recommended to use BFVDefault primes in CKKS. However, for performance // It is not recommended to use BFVDefault primes in CKKS. However, for performance
// test, BFVDefault primes are good enough. // test, BFVDefault primes are good enough.
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS); using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS);
ulong polyModulusDegree = 4096; ulong polyModulusDegree = 4096;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
CKKSPerformanceTest(new SEALContext(parms)); using (SEALContext context = new SEALContext(parms))
{
CKKSPerformanceTest(context);
}
Console.WriteLine(); Console.WriteLine();
polyModulusDegree = 8192; polyModulusDegree = 8192;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
CKKSPerformanceTest(new SEALContext(parms)); using (SEALContext context = new SEALContext(parms))
{
CKKSPerformanceTest(context);
}
Console.WriteLine(); Console.WriteLine();
polyModulusDegree = 16384; polyModulusDegree = 16384;
parms.PolyModulusDegree = polyModulusDegree; parms.PolyModulusDegree = polyModulusDegree;
parms.CoeffModulus = CoeffModulus.BFVDefault(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. Comment out the following to run the biggest example.
@ -627,7 +688,10 @@ namespace SEALNetExamples
//polyModulusDegree = 32768; //polyModulusDegree = 32768;
//parms.PolyModulusDegree = polyModulusDegree; //parms.PolyModulusDegree = polyModulusDegree;
//parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree); //parms.CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree);
//CKKSPerformanceTest(new SEALContext(parms)); //using (SEALContext context = new SEALContext(parms))
//{
// CKKSPerformanceTest(context);
//}
} }
private static void ExampleCKKSPerformanceCustom() private static void ExampleCKKSPerformanceCustom()
@ -649,12 +713,16 @@ namespace SEALNetExamples
string banner = $"CKKS Performance Test with Degree: {polyModulusDegree}"; string banner = $"CKKS Performance Test with Degree: {polyModulusDegree}";
Utilities.PrintExampleBanner(banner); Utilities.PrintExampleBanner(banner);
EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS) using EncryptionParameters parms = new EncryptionParameters(SchemeType.CKKS)
{ {
PolyModulusDegree = polyModulusDegree, PolyModulusDegree = polyModulusDegree,
CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree) CoeffModulus = CoeffModulus.BFVDefault(polyModulusDegree)
}; };
CKKSPerformanceTest(new SEALContext(parms));
using (SEALContext context = new SEALContext(parms))
{
CKKSPerformanceTest(context);
}
} }
private static void ExamplePerformanceTest() 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(); GC.Collect();
} }