зеркало из 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
|
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();
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче