ibarrond / Pyfhel

PYthon For Homomorphic Encryption Libraries, perform encrypted computations such as sum, mult, scalar product or matrix multiplication in Python, with NumPy compatibility. Uses SEAL/PALISADE as backends, implemented using Cython.
https://pyfhel.readthedocs.io/
Apache License 2.0
487 stars 78 forks source link

Will you add self-defined rotation key to Pyfhel? #148

Closed EchizenG closed 2 years ago

EchizenG commented 2 years ago

Describe the feature In SEAL, it is doable to generate rotation key with self-defined steps. This can make one-rotation time consume equals to relineralization. In Pyfhel, I don't find any API to do this. Therefore, I ask here if you will add this feature later. Thank you!

Is this feature related to a project/objective? Please describe briefly The current rotation time consume is HammingDistance(min(k,m/2-k)). Adding the above feature can lead to minimum rotation time consume.

ibarrond commented 2 years ago

It can definitely be done! Do you have any SEAL-based code I can use as inspiration? I could modify the relinKeyGen() function to allow optional parameters.

EchizenG commented 2 years ago

I modified the example code in SEAL/native/examples/6_rotation.cpp.

`

void example_rotation_selfkey_bfv()
{

      EncryptionParameters parms(scheme_type::bfv);

      size_t poly_modulus_degree = 8192;
      parms.set_poly_modulus_degree(poly_modulus_degree);
      parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
      parms.set_plain_modulus(PlainModulus::Batching(poly_modulus_degree, 20));

      SEALContext context(parms);

      KeyGenerator keygen(context);
      SecretKey secret_key = keygen.secret_key();
      PublicKey public_key;
      keygen.create_public_key(public_key);
      RelinKeys relin_keys;
      keygen.create_relin_keys(relin_keys);
      Encryptor encryptor(context, public_key);
      Evaluator evaluator(context);
      Decryptor decryptor(context, secret_key);

      BatchEncoder batch_encoder(context);
      size_t slot_count = batch_encoder.slot_count();
      size_t row_size = slot_count / 2;

      vector<uint64_t> pod_matrix(slot_count, 0ULL);
      pod_matrix[0] = 0ULL;
      pod_matrix[1] = 1ULL;
      pod_matrix[2] = 2ULL;
      pod_matrix[3] = 3ULL;
      pod_matrix[row_size] = 4ULL;
      pod_matrix[row_size + 1] = 5ULL;
      pod_matrix[row_size + 2] = 6ULL;
      pod_matrix[row_size + 3] = 7ULL;

      struct timespec start, end;
      Plaintext plain_matrix;

      Ciphertext encrypted_matrix;

      GaloisKeys galois_keys;
      std::vector<int> steps;
      for(int i = 1; i <100;i++){
          steps.push_back(i);
      }
      keygen.create_galois_keys(steps, galois_keys);

      Plaintext plain_result;

      for(int i = 1; i < 100; i++)
      {
          clock_gettime( CLOCK_REALTIME, &start );
          // printf("here i am\n");
          evaluator.rotate_rows_inplace(encrypted_matrix, i, galois_keys);

          clock_gettime( CLOCK_REALTIME, &end );
          printf("%ld: %f\n", i, (double)(end.tv_nsec-start.tv_nsec)/((double)1000000));
      }
}

` I just create a vector to store steps and feed it to 'keygen.create_galois_keys' and test the rotation time it looks better than default. I have been trying to add this feature but have not done yet.

EchizenG commented 2 years ago

I was trying to compile Pyfhel by 'pip install .' but it looks like finding the SEAL in your repo's directory instead of searching the local computer path.

ibarrond commented 2 years ago

@EchizenG Yeap, Pyfhel comes with its own bundled SEAL version to avoid having external dependencies.

Your self-defined rotation was implemented in 39b6fb3! Feel free to try it out and come back with your errors/suggestions/code.

EchizenG commented 2 years ago

Thank you for your work! This looks fantastic. However, I tried to use 'pip install .' in Pyfhel directory but received following error message.

CMake Error: The source directory "/tmp/pip-req-build-ejv9i6hl/Pyfhel/backend/SEAL" does not appear to contain CMakeLists.txt. Specify --help for usage, or press the help button on the CMake GUI. Error: could not load cache building 'Afhel' shared library cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ In file included from /tmp/pip-req-build-ejv9i6hl/Pyfhel/Afhel/Afseal.cpp:32: /tmp/pip-req-build-ejv9i6hl/Pyfhel/Afhel/Afseal.h:47:10: fatal error: seal/dynarray.h: No such file or directory 47 | #include "seal/dynarray.h" | ^~~~~ compilation terminated. error: command '/usr/bin/gcc' failed with exit code 1

It looks like the compiler cannot find "seal/dynarray.h'.

ibarrond commented 2 years ago

@EchizenG could you open a separate bug_report issue with all the information required to replicate? It is a very simple issue to solve, but I'd rather document it properly for other people to benefit from the answer. I promise a swift answer!

EchizenG commented 2 years ago

Done The installation issue is here #150