Search code examples
c++seal

Working on SEAL Ciphertexts with multiple users


I have those SEAL settings in my SEAL v2.3.1:

seal::EncryptionParameters parms;
parms.set_poly_modulus("1x^2048 + 1");
parms.set_coeff_modulus(seal::coeff_modulus_128(2048));
parms.set_plain_modulus(1 << 8);

seal::SEALContext context(parms);

seal::IntegerEncoder encoder(context.plain_modulus());
seal::KeyGenerator keygen(context);
seal::PublicKey public_key = keygen.public_key();
seal::SecretKey secret_key = keygen.secret_key();

seal::Encryptor encryptor(context, public_key);
seal::Evaluator evaluator(context);
seal::Decryptor decryptor(context, secret_key);

I've saved the public_key, secret_key and parms into files for later use. I've used the public_key to encrypt some data and store it in a database. I use the saved parms on the server with the database to execute some mathematical operations on the stored Ciphertexts e.g. evaluator.add(stored_ciphertext1, stored_ciphertext2, result_ciphertext3);.

Now let's say another person wants:

  1. To do calculations on the Ciphertexts stored by me.
  2. Upload some new encrypted Ciphertexts to the database next to mine.

For option 1 the second person only needs my stored parms to execute evaluator.add() on my Ciphertexts or can he create new once for this purpose?

For option 2 the second person has to have access to my stored public_key because creating new_public_key, new_secret_key set will not allow me to decrypt any data encrypted with new_public_key correctly, right?

Now to make things more confusing :-) let's say the second person has created his own new_public_key, new_secret_key and uploaded his own Ciphertexts in some other table on the same database. Now I want to execute some cross calculations using his and my Ciphertexts. Is there a way for this to work or it can never work because each of us used a different public_key for encryption?


Solution

  • For option 1 the second person only needs my stored parms to execute evaluator.add() on my Ciphertexts or can he create new once for this purpose?

    The other party needs to know what your encryption parameters are. Moreover, EncryptionParameters object only depends on those parameters: you can give it to them in the serialized (binary) format using EncryptionParameters::save and load, or let them know in some other way so they can then create their own EncryptionParameters object and it will work.

    For option 2 the second person has to have access to my stored public_key because creating new_public_key, new_secret_key set will not allow me to decrypt any data encrypted with new_public_key correctly, right?

    For the second person to encrypt data for you to decrypt they need your public key. Yes, it has to be the same public key that you stored. In theory it would be possible to create multiple public keys corresponding to the same secret key, but SEAL 2.3.1 does not support this.

    Now to make things more confusing :-) let's say the second person has created his own new_public_key, new_secret_key and uploaded his own Ciphertexts in some other table on the same database. Now I want to execute some cross calculations using his and my Ciphertexts. Is there a way for this to work or it can never work because each of us used a different public_key for encryption?

    This cannot work; you'll need to decrypt with the secret key corresponding to the public key that was used for encryption. In these scenarios it is possible to set up a key switching service by introducing a non-colluding third party whose only task is to receive ciphertexts encrypted under one key, switch them to using another key using some key, and forward them to the correct recipient. SEAL 2.3.1 does not support such generic key switches though. Alternatively, there are some multi-key FHE schemes that in theory allow this sort of behavior (both parties need to help in decryption) but at this time they are not very efficient and are not implemented in any library that I know of.