Skip to content

Commit

Permalink
Improved names and signatures of key generation functions and encrypt…
Browse files Browse the repository at this point in the history
…ion functions
  • Loading branch information
kimlaine committed Oct 9, 2020
1 parent 7ecff70 commit 40cdd9f
Show file tree
Hide file tree
Showing 47 changed files with 1,368 additions and 979 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ The performance improvement should be expected to be around 20-30x.

### API Changes

- All `Encryptor::encrypt` variants have now two overloads: one that takes a `Ciphertext` out-parameter, and one that returns a `Serializable<Ciphertext>`.
- Changed the names of the public key generation functions to clearly express that a new key is created each time, e.g., `KeyGenerator::create_public_key`.
- Removed the `KeyGenerator::relin_keys_local` and `KeyGenerator::galois_keys_local` functions.
These were poorly named and have been replaced with overloads of `KeyGenerator::create_relin_keys` and `KeyGenerator::create_galois_keys` that take an out-parameter of type `RelinKeys` or `GaloisKeys`.
- Added public API for modular reduction to the `Modulus` class.
- Added `encrypt` and `encrypt_zero` overloads to `Encryptor` that output asymmetrically encrypted `Serializable<Ciphertext>` objects.
Previously these existed only for symmetric-key encryption mode.
Expand Down
42 changes: 23 additions & 19 deletions dotnet/examples/1_BFV_Basics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,17 @@ form log2(PlainModulus) + (other terms).
object. This is a heavy class that checks the validity and properties of the
parameters we just set.
C# 8.0 introduced the `using` declaration for local variables. This is a very
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.
the object. Releasing the native resources returns the allocated memory to
the Microsoft SEAL memory pool, speeding up further allocations. Another way
would be to call GC::Collect() at a convenient point in the code, but this is
less optimal: it may still cause unnecessary allocations 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.
*/
using SEALContext context = new SEALContext(parms);

Expand Down Expand Up @@ -166,16 +165,22 @@ with the secret key.
We are now ready to generate the secret and public keys. For this purpose
we need an instance of the KeyGenerator class. Constructing a KeyGenerator
automatically generates the public and secret key, which can immediately be
read to local variables.
automatically generates a secret key. We can then create as many public
keys for it as we want using KeyGenerator.CreatePublicKey.
Note that KeyGenerator.CreatePublicKey has another overload that takes no
parameters and returns a Serializable<PublicKey> object. We will discuss
this in `6_Serialization.cs'.
*/
using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
keygen.CreatePublicKey(out PublicKey publicKey);

/*
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. It is also
possible to use Microsoft SEAL in secret-key mode by providing the Encryptor
the secret key instead. We will discuss this in `6_Serialization.cs'.
*/
using Encryptor encryptor = new Encryptor(context, publicKey);

Expand Down Expand Up @@ -222,7 +227,10 @@ a string with coefficients represented as hexadecimal numbers.
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. We note that the
Encryptor.Encrypt function has another overload that takes as input only
a plaintext and returns a Serializable<Ciphertext> object. We will discuss
this in `6_Serialization.cs'.
*/
Utilities.PrintLine();
using Ciphertext xEncrypted = new Ciphertext();
Expand Down Expand Up @@ -353,14 +361,10 @@ the KeyGenerator.
Relinearization is used similarly in both the BFV and the CKKS schemes, but
in this example we continue using BFV. We repeat our computation from before,
but this time relinearize after every multiplication.
Here we use the function KeyGenerator.RelinKeysLocal(). In production code
it is much better to use KeyGenerator.RelinKeys() instead. We will explain
and discuss these differences in `6_Serialization.cs'.
*/
Utilities.PrintLine();
Console.WriteLine("Generate locally usable relinearization keys.");
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreateRelinKeys(out RelinKeys relinKeys);

/*
We now repeat the computation relinearizing after each multiplication.
Expand Down
10 changes: 5 additions & 5 deletions dotnet/examples/2_Encoders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ will be incorrect.
Console.WriteLine();

using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
keygen.CreatePublicKey(out PublicKey publicKey);
using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
using Decryptor decryptor = new Decryptor(context, secretKey);
Expand Down Expand Up @@ -201,9 +201,9 @@ parameter qualifiers created by SEALContext.
Console.WriteLine($"Batching enabled: {qualifiers.UsingBatching}");

using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);
using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
using Decryptor decryptor = new Decryptor(context, secretKey);
Expand Down Expand Up @@ -366,9 +366,9 @@ We create the SEALContext as usual and print the parameters.
Keys are created the same way as for the BFV scheme.
*/
using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);

/*
We also set up an Encryptor, Evaluator, and Decryptor as usual.
Expand Down
13 changes: 2 additions & 11 deletions dotnet/examples/3_Levels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,24 +165,15 @@ Step forward in the chain.
We create some keys and check that indeed they appear at the highest level.
*/
using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);

/*
In this example we create a local version of the GaloisKeys object using
KeyGenerator.GaloisKeysLocal(). In a production setting where the Galois
keys would need to be communicated to a server, it would be much better to
use KeyGenerator.GaloisKeys(), which outputs a Serializable<GaloisKeys>
object for compressed serialization.
*/
using GaloisKeys galoisKeys = keygen.GaloisKeysLocal();
Utilities.PrintLine();
Console.WriteLine("Print the parameter IDs of generated elements.");
Console.WriteLine($" + publicKey: {publicKey.ParmsId}");
Console.WriteLine($" + secretKey: {secretKey.ParmsId}");
Console.WriteLine($" + relinKeys: {relinKeys.ParmsId}");
Console.WriteLine($" + galoisKeys: {galoisKeys.ParmsId}");

using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
Expand Down
4 changes: 2 additions & 2 deletions dotnet/examples/4_CKKS_Basics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ scale stabilization as described above.
Console.WriteLine();

using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);
using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
using Decryptor decryptor = new Decryptor(context, secretKey);
Expand Down
20 changes: 10 additions & 10 deletions dotnet/examples/5_Rotation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ private static void ExampleRotationBFV()
Console.WriteLine();

using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);
using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
using Decryptor decryptor = new Decryptor(context, secretKey);
Expand Down Expand Up @@ -74,14 +74,14 @@ the plaintext as usual.
Rotations require yet another type of special key called `Galois keys'. These
are easily obtained from the KeyGenerator.
*/
using GaloisKeys galKeys = keygen.GaloisKeysLocal();
keygen.CreateGaloisKeys(out GaloisKeys galoisKeys);

/*
Now rotate both matrix rows 3 steps to the left, decrypt, decode, and print.
*/
Utilities.PrintLine();
Console.WriteLine("Rotate rows 3 steps left.");
evaluator.RotateRowsInplace(encryptedMatrix, 3, galKeys);
evaluator.RotateRowsInplace(encryptedMatrix, 3, galoisKeys);
using Plaintext plainResult = new Plaintext();
Console.WriteLine(" + Noise budget after rotation: {0} bits",
decryptor.InvariantNoiseBudget(encryptedMatrix));
Expand All @@ -96,7 +96,7 @@ are easily obtained from the KeyGenerator.
*/
Utilities.PrintLine();
Console.WriteLine("Rotate columns.");
evaluator.RotateColumnsInplace(encryptedMatrix, galKeys);
evaluator.RotateColumnsInplace(encryptedMatrix, galoisKeys);
Console.WriteLine(" + Noise budget after rotation: {0} bits",
decryptor.InvariantNoiseBudget(encryptedMatrix));
Console.WriteLine(" + Decrypt and decode ...... Correct.");
Expand All @@ -109,7 +109,7 @@ are easily obtained from the KeyGenerator.
*/
Utilities.PrintLine();
Console.WriteLine("Rotate rows 4 steps right.");
evaluator.RotateRowsInplace(encryptedMatrix, -4, galKeys);
evaluator.RotateRowsInplace(encryptedMatrix, -4, galoisKeys);
Console.WriteLine(" + Noise budget after rotation: {0} bits",
decryptor.InvariantNoiseBudget(encryptedMatrix));
Console.WriteLine(" + Decrypt and decode ...... Correct.");
Expand Down Expand Up @@ -142,10 +142,10 @@ private static void ExampleRotationCKKS()
Console.WriteLine();

using KeyGenerator keygen = new KeyGenerator(context);
using PublicKey publicKey = keygen.PublicKey;
using SecretKey secretKey = keygen.SecretKey;
using RelinKeys relinKeys = keygen.RelinKeysLocal();
using GaloisKeys galKeys = keygen.GaloisKeysLocal();
keygen.CreatePublicKey(out PublicKey publicKey);
keygen.CreateRelinKeys(out RelinKeys relinKeys);
keygen.CreateGaloisKeys(out GaloisKeys galoisKeys);
using Encryptor encryptor = new Encryptor(context, publicKey);
using Evaluator evaluator = new Evaluator(context);
using Decryptor decryptor = new Decryptor(context, secretKey);
Expand Down Expand Up @@ -176,7 +176,7 @@ private static void ExampleRotationCKKS()
using Ciphertext rotated = new Ciphertext();
Utilities.PrintLine();
Console.WriteLine("Rotate 2 steps left.");
evaluator.RotateVector(encrypted, 2, galKeys, rotated);
evaluator.RotateVector(encrypted, 2, galoisKeys, rotated);
Console.WriteLine(" + Decrypt and decode ...... Correct.");
decryptor.Decrypt(encrypted, plain);
List<double> result = new List<double>();
Expand Down
Loading

0 comments on commit 40cdd9f

Please sign in to comment.