homenc / HElib

HElib is an open-source software library that implements homomorphic encryption. It supports the BGV scheme with bootstrapping and the Approximate Number CKKS scheme. HElib also includes optimizations for efficient homomorphic evaluation, focusing on effective use of ciphertext packing techniques and on the Gentry-Halevi-Smart optimizations.
https://homenc.github.io/HElib
Other
3.11k stars 761 forks source link

ExtractDigits issue #349

Open Pistonomaxime opened 4 years ago

Pistonomaxime commented 4 years ago

Maxime Pistono, maxime.pistono@imt-atlantique.fr Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64) I have three questions: -In the following code can I manually increase the parameter r? -If the answer is yes, why I cannot increase it more than 59? (maybe a code limitation) -The most important question. Why if I increase it (to 40 for example) digits extraction fail ? I also have a docker image of an "old" HElib version 1.0.0 beta1 on which if I increase the parameter r everything goes well.

  // Plaintext prime modulus
  unsigned long p = 2;
  // Cyclotomic polynomial - defines phi(m)
  unsigned long m = 3;
  // Hensel lifting (default = 1)
  unsigned long r = 1;
  // Number of bits of the modulus chain
  unsigned long bits = 300;
  // Number of columns of Key-Switching matix (default = 2 or 3)
  unsigned long c = 4;

  double lBound = 30.0;
  long bound = floor(lBound/log2((double)p));
  if (r<2 || r>bound) r = bound;
  //r = 40;
  std::cout << "Value of r = " << r << std::endl;

  long ll = NTL::NextPowerOfTwo(p);
  bits = 30*(r*ll*3 + 2);
  std::cout << "Value of bits = " << bits << std::endl;

  std::cout << "Initialising context object..." << std::endl;
  // Intialise context
  helib::Context context(m, p, r);
  // Modify the context, adding primes to the modulus chain
  std::cout  << "Building modulus chain..." << std::endl;
  buildModChain(context, bits, c);

  // Print the context
  context.zMStar.printout();
  std::cout << std::endl;

  // Print the security level
  std::cout << "Security: " << context.securityLevel() << std::endl;
  // Secret key management
  std::cout << "Creating secret key..." << std::endl;
  // Create a secret key associated with the context
  helib::SecKey secret_key(context);
  // Generate the secret key
  secret_key.GenSecKey();
  std::cout << "Generating key-switching matrices..." << std::endl;
  // Compute key-switching matrices that we need
  helib::addSome1DMatrices(secret_key);

  // Public key management
  // Set the secret key (upcast: SecKey is a subclass of PubKey)
  const helib::PubKey& public_key = secret_key;

  // Get the EncryptedArray of the context
  const helib::EncryptedArray& ea = *(context.ea);

  long nslots = ea.size();
  std::cout << "Number of slots: " << nslots << std::endl;

  std::vector<long> Stream(nslots);
  Stream[0] = 268435455;
  std::vector<long> Verification;

  helib::Ctxt E_Stream(public_key);
  ea.encrypt(E_Stream, public_key, Stream);
  ea.decrypt(E_Stream, secret_key, Verification);
  std::cout << "plaintext=" << helib::vecToStr(Verification) << std::endl;

  std::cout << "extracting " << r << " digits..." << std::flush;
  std::vector<helib::Ctxt> E_Bits;
  helib::extractDigits(E_Bits, E_Stream);
  std::cout << " done\n" << std::flush;

  for (long i=0; i<(long)E_Bits.size(); i++) {
      ea.decrypt(E_Bits[i], secret_key, Verification);
      std::cout << i << "th digit=" << helib::vecToStr(Verification) << std::endl;
  }

  return(0);

Thanks for your help.