Ctxt.h
1 /* Copyright (C) 2012-2020 IBM Corp.
2  * This program is Licensed under the Apache License, Version 2.0
3  * (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://www.apache.org/licenses/LICENSE-2.0
6  * Unless required by applicable law or agreed to in writing, software
7  * distributed under the License is distributed on an "AS IS" BASIS,
8  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9  * See the License for the specific language governing permissions and
10  * limitations under the License. See accompanying LICENSE file.
11  */
12 #ifndef HELIB_CTXT_H
13 #define HELIB_CTXT_H
14 
57 #include <cfloat> // DBL_MAX
58 #include <helib/DoubleCRT.h>
59 #include <helib/apiAttributes.h>
60 
61 namespace helib {
62 struct CKKS;
63 struct BGV;
64 
65 template <typename Scheme>
66 class Ptxt;
67 
68 class KeySwitch;
69 class PubKey;
70 class SecKey;
71 
77 class SKHandle
78 {
79  long powerOfS, powerOfX, secretKeyID;
80 
81 public:
82  friend class Ctxt;
83 
84  SKHandle(long newPowerOfS = 0, long newPowerOfX = 1, long newSecretKeyID = 0)
85  {
86  powerOfS = newPowerOfS;
87  powerOfX = newPowerOfX;
88  secretKeyID = newSecretKeyID;
89  }
90 
92  void setBase(long newSecretKeyID = -1)
93  {
94  powerOfS = 1;
95  powerOfX = 1;
96  if (newSecretKeyID >= 0)
97  secretKeyID = newSecretKeyID;
98  }
99 
101  bool isBase(long ofKeyID = 0) const
102  {
103  // If ofKeyID<0, only check that this is base of some key,
104  // otherwise check that this is base of the given key
105  return powerOfS == 1 && powerOfX == 1 &&
106  (ofKeyID < 0 || secretKeyID == ofKeyID);
107  }
108 
110  void setOne(long newSecretKeyID = -1)
111  {
112  powerOfS = 0;
113  powerOfX = 1;
114  if (newSecretKeyID >= 0)
115  secretKeyID = newSecretKeyID;
116  }
117 
119  bool isOne() const { return powerOfS == 0; }
120 
121  bool operator==(const SKHandle& other) const
122  {
123  if (powerOfS == 0 && other.powerOfS == 0)
124  return true;
125  else
126  return powerOfS == other.powerOfS && powerOfX == other.powerOfX &&
127  secretKeyID == other.secretKeyID;
128  }
129 
130  bool operator!=(const SKHandle& other) const { return !(*this == other); }
131 
132  /* access functions */
133 
134  long getPowerOfS() const { return powerOfS; }
135  long getPowerOfX() const { return powerOfX; }
136  long getSecretKeyID() const { return secretKeyID; }
137 
150  bool mul(const SKHandle& a, const SKHandle& b)
151  {
152  // If either of the inputs is one, the output equals to the other input
153  if (a.isOne()) {
154  *this = b;
155  return (b.secretKeyID >= 0);
156  }
157  if (b.isOne()) {
158  *this = a;
159  return (a.secretKeyID >= 0);
160  }
161 
162  if (a.secretKeyID == -1 || b.secretKeyID == -1) {
163  secretKeyID = -1; // -1 will be used to indicate an "error state"
164  return false;
165  }
166 
167  if (a.secretKeyID != b.secretKeyID) {
168  secretKeyID = -1;
169  return false;
170  }
171 
172  if (a.powerOfX != b.powerOfX) {
173  secretKeyID = -1;
174  return false;
175  }
176 
177  secretKeyID = a.secretKeyID;
178  powerOfX = a.powerOfX;
179  powerOfS = a.powerOfS + b.powerOfS;
180  return true;
181  }
182 
183  friend std::istream& operator>>(std::istream& s, SKHandle& handle);
184 
185  // Raw IO
186  void read(std::istream& str);
187  void write(std::ostream& str) const;
188 };
189 
190 inline std::ostream& operator<<(std::ostream& s, const SKHandle& handle)
191 {
192  return s << "[" << handle.getPowerOfS() << " " << handle.getPowerOfX() << " "
193  << handle.getSecretKeyID() << "]";
194 }
195 
203 class CtxtPart : public DoubleCRT
204 {
205 public:
207  SKHandle skHandle; // The secret-key polynomial corresponding to this part
208 
209  bool operator==(const CtxtPart& other) const;
210  bool operator!=(const CtxtPart& other) const { return !(*this == other); }
211 
212  // Constructors
213 
214  CtxtPart(const Context& _context, const IndexSet& s) : DoubleCRT(_context, s)
215  {
216  skHandle.setOne();
217  }
218 
219  CtxtPart(const Context& _context,
220  const IndexSet& s,
221  const SKHandle& otherHandle) :
222  DoubleCRT(_context, s), skHandle(otherHandle)
223  {}
224 
225  // Copy constructors from the base class
226  explicit CtxtPart(const DoubleCRT& other) : DoubleCRT(other)
227  {
228  skHandle.setOne();
229  }
230 
231  CtxtPart(const DoubleCRT& other, const SKHandle& otherHandle) :
232  DoubleCRT(other), skHandle(otherHandle)
233  {}
234 
235  void read(std::istream& str);
236  void write(std::ostream& str) const;
237 };
238 
239 std::istream& operator>>(std::istream& s, CtxtPart& p);
240 std::ostream& operator<<(std::ostream& s, const CtxtPart& p);
241 
243 struct ZeroCtxtLike_type
244 {}; // used to select a constructor
245 
246 const ZeroCtxtLike_type ZeroCtxtLike = ZeroCtxtLike_type();
248 
272 class Ctxt
273 {
274  friend class PubKey;
275  friend class SecKey;
276  friend class BasicAutomorphPrecon;
277 
278  const Context& context; // points to the parameters of this FHE instance
279  const PubKey& pubKey; // points to the public encryption key;
280  std::vector<CtxtPart> parts; // the ciphertext parts
281  IndexSet primeSet; // the primes relative to which the parts are defined
282  long ptxtSpace; // plaintext space for this ciphertext (either p or p^r)
283 
284  // a high-probability bound on the the noise magnitude
285  NTL::xdouble noiseBound;
286 
287  long intFactor; // an integer factor to divide by on decryption (for BGV)
288  NTL::xdouble ratFactor; // rational factor to divide on decryption (for CKKS)
289  NTL::xdouble ptxtMag; // bound on the plaintext size (for CKKS)
290 
291  // Create a tensor product of c1,c2. It is assumed that *this,c1,c2
292  // are defined relative to the same set of primes and plaintext space,
293  // and that *this DOES NOT point to the same object as c1,c2
294  void tensorProduct(const Ctxt& c1, const Ctxt& c2);
295 
296  // Add/subtract a ciphertext part to/from a ciphertext. These are private
297  // methods, they cannot update the noiseBound so they must be called
298  // from a procedure that will eventually update that estimate.
299  Ctxt& operator-=(const CtxtPart& part)
300  {
301  subPart(part);
302  return *this;
303  }
304 
305  Ctxt& operator+=(const CtxtPart& part)
306  {
307  addPart(part);
308  return *this;
309  }
310 
311  // NOTE: the matchPrimeSets business in the following routines
312  // is DEPRECATED. The requirement is that the prime set of part
313  // must contain the prime set of *this, unless *this is empty
314  // (in which case *this takes on the prime set of part).
315  // If not, an exception is raised.
316  // Also, if matchPrimeSets == true and the prime set of *this does
317  // not contain the prime set of part, an exception is also raised.
318 
319  // Procedural versions with additional parameter
320  void subPart(const CtxtPart& part, bool matchPrimeSet = false)
321  {
322  subPart(part, part.skHandle, matchPrimeSet);
323  }
324 
325  void addPart(const CtxtPart& part, bool matchPrimeSet = false)
326  {
327  addPart(part, part.skHandle, matchPrimeSet);
328  }
329 
330  void subPart(const DoubleCRT& part,
331  const SKHandle& handle,
332  bool matchPrimeSet = false)
333  {
334  addPart(part, handle, matchPrimeSet, true);
335  }
336 
337  void addPart(const DoubleCRT& part,
338  const SKHandle& handle,
339  bool matchPrimeSet = false,
340  bool negative = false);
341 
342  // Takes as arguments a ciphertext-part p relative to s' and a key-switching
343  // matrix W = W[s'->s], use W to switch p relative to (1,s), and add the
344  // result to *this.
345  void keySwitchPart(const CtxtPart& p, const KeySwitch& W);
346 
347  // internal procedure used in key-switching
348  void keySwitchDigits(const KeySwitch& W, std::vector<DoubleCRT>& digits);
349 
350  long getPartIndexByHandle(const SKHandle& handle) const
351  {
352  for (size_t i = 0; i < parts.size(); i++)
353  if (parts[i].skHandle == handle)
354  return i;
355  return -1;
356  }
357 
358  // Sanity-check: Check that prime-set is "valid", i.e. that it
359  // contains either all the special primes or none of them
360  bool verifyPrimeSet() const;
361 
362  // A private assignment method that does not check equality of context or
363  // public key, this is needed when we copy the pubEncrKey member between
364  // different public keys.
365  Ctxt& privateAssign(const Ctxt& other);
366 
367  // explicitly multiply intFactor by e, which should be
368  // in the interval [0, ptxtSpace)
369  void mulIntFactor(long e);
370 
371 public:
372  // Default copy-constructor
373  Ctxt(const Ctxt& other) = default;
374 
375  // VJS-FIXME: this was really a messy design choice to not
376  // have ciphertext cosntructors that specify prime sets.
377  // The default value of ctxtPrimes is kind of pointless.
378 
379  //__attribute__((deprecated))
380  explicit Ctxt(const PubKey& newPubKey, long newPtxtSpace = 0); // constructor
381 
382  //__attribute__((deprecated))
383  Ctxt(ZeroCtxtLike_type, const Ctxt& ctxt);
384  // constructs a zero ciphertext with same public key and
385  // plaintext space as ctxt
386 
390  void DummyEncrypt(const NTL::ZZX& ptxt, double size = -1.0);
391 
392  Ctxt& operator=(const Ctxt& other)
393  { // public assignment operator
394  assertEq(&context,
395  &other.context,
396  "Cannot assign Ctxts with different context");
397  assertEq(&pubKey,
398  &other.pubKey,
399  "Cannot assign Ctxts with different pubKey");
400  return privateAssign(other);
401  }
402 
403  bool operator==(const Ctxt& other) const { return equalsTo(other); }
404  bool operator!=(const Ctxt& other) const { return !equalsTo(other); }
405 
406  // a procedural variant with an additional parameter
407  bool equalsTo(const Ctxt& other, bool comparePkeys = true) const;
408 
409  // Encryption and decryption are done by the friends [Pub|Sec]Key
410 
413  void negate();
414 
415  // Add/subtract another ciphertext
416  Ctxt& operator+=(const Ctxt& other)
417  {
418  addCtxt(other);
419  return *this;
420  }
421 
422  Ctxt& operator-=(const Ctxt& other)
423  {
424  addCtxt(other, true);
425  return *this;
426  }
427 
428  void addCtxt(const Ctxt& other, bool negative = false);
429 
430  // Multiply by another ciphertext
431  void multLowLvl(const Ctxt& other, bool destructive = false);
432  Ctxt& operator*=(const Ctxt& other)
433  {
434  multLowLvl(other);
435  return *this;
436  }
437 
438  void automorph(long k); // Apply automorphism F(X) -> F(X^k) (gcd(k,m)=1)
439  Ctxt& operator>>=(long k)
440  {
441  automorph(k);
442  return *this;
443  }
444 
445  void complexConj(); // Complex conjugate, same as automorph(m-1)
446 
448  void smartAutomorph(long k);
449  // Apply F(X)->F(X^k) followed by re-linearization. The automorphism is
450  // possibly evaluated via a sequence of steps, to ensure that we can
451  // re-linearize the result of every step.
452 
454  void frobeniusAutomorph(long j);
455 
456  // Operators acting between ciphertexts and plaintext objects
457 
458  // BGV case
464  Ctxt& operator+=(const Ptxt<BGV>& other);
465 
471  Ctxt& operator-=(const Ptxt<BGV>& other);
472 
478  Ctxt& operator*=(const Ptxt<BGV>& other);
479 
480  // CKKS case
486  Ctxt& operator+=(const Ptxt<CKKS>& other);
487 
493  Ctxt& operator-=(const Ptxt<CKKS>& other);
494 
500  Ctxt& operator*=(const Ptxt<CKKS>& other);
501 
507  Ctxt& operator*=(const NTL::ZZX& poly);
508 
514  Ctxt& operator*=(const long scalar);
515 
523  void addConstant(const DoubleCRT& dcrt, double size = -1.0);
524  void addConstant(const NTL::ZZX& poly, double size = -1.0);
525 
530  template <typename Scheme>
531  void addConstant(const Ptxt<Scheme>& ptxt)
532  {
533  addConstant(ptxt.getPolyRepr());
534  }
535 
536  void addConstant(const NTL::ZZ& c);
538  void addConstantCKKS(std::pair</*numerator=*/long, /*denominator=*/long>);
539  void addConstantCKKS(double x)
540  { // FIXME: not enough precision when x is large
542  rationalApprox(x, /*denomBound=*/1 << getContext().alMod.getR()));
543  }
544 
545  void addConstantCKKS(const DoubleCRT& dcrt,
546  NTL::xdouble size = NTL::xdouble(-1.0),
547  NTL::xdouble factor = NTL::xdouble(-1.0));
548 
549  void addConstantCKKS(const NTL::ZZX& poly,
550  NTL::xdouble size = NTL::xdouble(-1.0),
551  NTL::xdouble factor = NTL::xdouble(-1.0));
552 
553  void addConstantCKKS(const std::vector<std::complex<double>>& ptxt);
554 
559  void addConstantCKKS(const Ptxt<CKKS>& ptxt);
560  void addConstantCKKS(const NTL::ZZ& c);
561 
567  void multByConstant(const DoubleCRT& dcrt, double size = -1.0);
568  void multByConstant(const NTL::ZZX& poly, double size = -1.0);
569  void multByConstant(const zzX& poly, double size = -1.0);
570  void multByConstant(const NTL::ZZ& c);
571 
576  template <typename Scheme>
577  void multByConstant(const Ptxt<Scheme>& ptxt)
578  {
579  multByConstant(ptxt.getPolyRepr());
580  }
581 
583  // [[deprecated]]
584  void multByConstantCKKS(double x)
585  {
586  if (this->isEmpty())
587  return;
588 
589  if (x == 1)
590  return;
591 
592  if (x == 0) {
593  clear();
594  return;
595  }
596 
597  double size = std::abs(x);
598  ptxtMag *= size;
599  ratFactor /= size;
600  if (x < 0)
601  this->negate();
602  }
603 
604  void multByConstantCKKS(std::pair<long, long> num) // rational number
605  {
606  multByConstantCKKS(double(num.first) / num.second);
607  }
608 
609  void multByConstantCKKS(const DoubleCRT& dcrt,
610  NTL::xdouble size = NTL::xdouble(-1.0),
611  NTL::xdouble factor = NTL::xdouble(-1.0),
612  double roundingErr = -1.0);
613 
614  void multByConstantCKKS(const NTL::ZZX& poly,
615  NTL::xdouble size = NTL::xdouble(-1.0),
616  NTL::xdouble factor = NTL::xdouble(-1.0),
617  double roundingErr = -1.0)
618  {
619  DoubleCRT dcrt(poly, context, primeSet);
620  multByConstantCKKS(dcrt, size, factor, roundingErr);
621  }
622 
623  // TODO: Ptxt: refactor into single function for getting the
624  // std::vector<cx_double> repr of slots
629  void multByConstantCKKS(const Ptxt<CKKS>& ptxt);
630  void multByConstantCKKS(const std::vector<std::complex<double>>& ptxt);
631 
635  void xorConstant(const DoubleCRT& poly, UNUSED double size = -1.0)
636  {
637  DoubleCRT tmp = poly;
638  tmp *= -2;
639  tmp += 1; // tmp = 1-2*poly
640  multByConstant(tmp);
641  addConstant(poly);
642  }
643 
644  void xorConstant(const NTL::ZZX& poly, double size = -1.0)
645  {
646  xorConstant(DoubleCRT(poly, context, primeSet), size);
647  }
648 
649  void nxorConstant(const DoubleCRT& poly, UNUSED double size = -1.0)
650  {
651  DoubleCRT tmp = poly;
652  tmp *= 2;
653  tmp -= 1; // 2a-1
654  addConstant(NTL::to_ZZX(-1L)); // b11
655  multByConstant(tmp); // (b-1)(2a-1)
656  addConstant(poly); // (b-1)(2a-1)+a = 1-a-b+2ab
657  }
658 
659  void nxorConstant(const NTL::ZZX& poly, double size = -1.0)
660  {
661  nxorConstant(DoubleCRT(poly, context, primeSet), size);
662  }
663 
668  void divideByP();
669 
672  void multByP(long e = 1)
673  {
674  long p2e = NTL::power_long(context.zMStar.getP(), e);
675  ptxtSpace *= p2e;
676  multByConstant(NTL::to_ZZ(p2e));
677  }
678 
679  // For backward compatibility
680  void divideBy2();
681  void extractBits(std::vector<Ctxt>& bits, long nBits2extract = 0);
682 
683  // Higher-level multiply routines
684  void multiplyBy(const Ctxt& other);
685  void multiplyBy2(const Ctxt& other1, const Ctxt& other2);
686  void square() { multiplyBy(*this); }
687  void cube() { multiplyBy2(*this, *this); }
688 
690  void power(long e); // in polyEval.cpp
691 
693 
696 
698  void reducePtxtSpace(long newPtxtSpace);
699 
700  // This method can be used to increase the plaintext space, but the
701  // high-order digits that you get this way are noise. Do not use it
702  // unless you know what you are doing.
703  void hackPtxtSpace(long newPtxtSpace) { ptxtSpace = newPtxtSpace; }
704 
705  void bumpNoiseBound(double factor) { noiseBound *= factor; }
706 
707  void reLinearize(long keyIdx = 0);
708  // key-switch to (1,s_i), s_i is the base key with index keyIdx
709 
710  Ctxt& cleanUp();
711  // relinearize, then reduce, then drop special primes and small primes.
712 
713  // void reduce() const;
714 
716  void blindCtxt(const NTL::ZZX& poly);
717 
719  NTL::xdouble modSwitchAddedNoiseBound() const;
720 
724  void modUpToSet(const IndexSet& s);
725 
729  void modDownToSet(const IndexSet& s);
730 
733  void bringToSet(const IndexSet& s);
734 
735  // Finding the "natural" state of a ciphertext
736  double naturalSize() const;
737  IndexSet naturalPrimeSet() const;
738 
743 
747  double capacity() const
748  {
749  if (noiseBound <= 1.0)
750  return context.logOfProduct(getPrimeSet());
751  else
752  return context.logOfProduct(getPrimeSet()) - log(noiseBound);
753  }
754 
755  // VJS-FIXME:
756  // For CKKS, the "total noise" for a Ctxt is
757  // ptxtMag * ratFactor + noiseBound. We should define a function
758  // totalNoiseBound() that returns this value for CKKS, and
759  // noiseBound o/w. We might also define a function netCapacity
760  // (or something) that is defined in terms of totalNoiseBound().
761 
763  long bitCapacity() const { return long(capacity() / log(2.0)); }
764 
766  double logOfPrimeSet() const { return context.logOfProduct(getPrimeSet()); }
767 
776  double rawModSwitch(std::vector<NTL::ZZX>& zzParts, long toModulus) const;
777 
779  // void computePowers(std::vector<Ctxt>& v, long nPowers) const;
780 
782  void evalPoly(const NTL::ZZX& poly);
784 
787 
788  void clear()
789  { // set as an empty ciphertext
790  primeSet = context.ctxtPrimes;
791  parts.clear();
792  noiseBound = NTL::to_xdouble(0.0);
793  // VJS-FIXME: we should also make sure the other fields
794  // are set to their default values for a new, empty ctxt.
795  }
796 
798  bool isEmpty() const { return (parts.size() == 0); }
799 
801  bool inCanonicalForm(long keyID = 0) const
802  {
803  if (parts.size() > 2)
804  return false;
805  if (parts.size() > 0 && !parts[0].skHandle.isOne())
806  return false;
807  if (parts.size() > 1 && !parts[1].skHandle.isBase(keyID))
808  return false;
809  return true;
810  }
811 
813  bool isCorrect() const
814  {
815  NTL::ZZ q = context.productOfPrimes(primeSet);
816  return NTL::to_xdouble(q) > noiseBound * 2;
817  }
818 
819  const Context& getContext() const { return context; }
820  const PubKey& getPubKey() const { return pubKey; }
821  const IndexSet& getPrimeSet() const { return primeSet; }
822  long getPtxtSpace() const { return ptxtSpace; }
823  const NTL::xdouble& getNoiseBound() const { return noiseBound; }
824  const NTL::xdouble& getRatFactor() const { return ratFactor; }
825  const NTL::xdouble& getPtxtMag() const { return ptxtMag; }
826  void setPtxtMag(const NTL::xdouble& z) { ptxtMag = z; }
827  long getKeyID() const;
828 
829  bool isCKKS() const { return (getContext().alMod.getTag() == PA_cx_tag); }
830 
831  // Return r such that p^r = ptxtSpace
832  long effectiveR() const
833  {
834  long p = context.zMStar.getP();
835  for (long r = 1, p2r = p; r < NTL_SP_NBITS; r++, p2r *= p) {
836  if (p2r == ptxtSpace)
837  return r;
838  if (p2r > ptxtSpace)
839  throw RuntimeError("ctxt.ptxtSpace is not of the form p^r");
840  }
841  throw RuntimeError("ctxt.ptxtSpace is not of the form p^r");
842  return 0; // just to keep the compiler happy
843  }
844 
846  double log_of_ratio() const
847  {
848  double logNoise =
849  (getNoiseBound() <= 0.0) ? -DBL_MAX : log(getNoiseBound());
850  double logMod =
851  empty(getPrimeSet()) ? -DBL_MAX : context.logOfProduct(getPrimeSet());
852  return logNoise - logMod;
853  }
855  friend std::istream& operator>>(std::istream& str, Ctxt& ctxt);
856  friend std::ostream& operator<<(std::ostream& str, const Ctxt& ctxt);
857 
858  // Raw IO
859  void write(std::ostream& str) const;
860  void read(std::istream& str);
861 
862  // scale up c1, c2 so they have the same ratFactor
863  static void equalizeRationalFactors(Ctxt& c1, Ctxt& c2);
864 };
865 
866 // set out=prod_{i=0}^{n-1} v[j], takes depth log n and n-1 products
867 // out could point to v[0], but having it pointing to any other v[i]
868 // will make the result unpredictable.
869 void totalProduct(Ctxt& out, const std::vector<Ctxt>& v);
870 
873 void incrementalProduct(std::vector<Ctxt>& v);
874 
875 void innerProduct(Ctxt& result,
876  const std::vector<Ctxt>& v1,
877  const std::vector<Ctxt>& v2);
878 inline Ctxt innerProduct(const std::vector<Ctxt>& v1,
879  const std::vector<Ctxt>& v2)
880 {
881  Ctxt ret(v1[0].getPubKey());
882  innerProduct(ret, v1, v2);
883  return ret;
884 }
885 
887 void innerProduct(Ctxt& result,
888  const std::vector<Ctxt>& v1,
889  const std::vector<DoubleCRT>& v2);
890 inline Ctxt innerProduct(const std::vector<Ctxt>& v1,
891  const std::vector<DoubleCRT>& v2)
892 {
893  Ctxt ret(v1[0].getPubKey());
894  innerProduct(ret, v1, v2);
895  return ret;
896 }
897 
898 void innerProduct(Ctxt& result,
899  const std::vector<Ctxt>& v1,
900  const std::vector<NTL::ZZX>& v2);
901 inline Ctxt innerProduct(const std::vector<Ctxt>& v1,
902  const std::vector<NTL::ZZX>& v2)
903 {
904  Ctxt ret(v1[0].getPubKey());
905  innerProduct(ret, v1, v2);
906  return ret;
907 }
908 
910 void CheckCtxt(const Ctxt& c, const char* label);
911 
933 void extractDigits(std::vector<Ctxt>& digits, const Ctxt& c, long r = 0);
934 // implemented in extractDigits.cpp
935 
936 inline void extractDigits(std::vector<Ctxt>& digits,
937  const Ctxt& c,
938  long r,
939  bool shortCut)
940 {
941  if (shortCut)
942  std::cerr << "extractDigits: the shortCut flag is disabled\n";
943  extractDigits(digits, c, r);
944 }
945 
946 inline void Ctxt::extractBits(std::vector<Ctxt>& bits, long nBits2extract)
947 {
948  extractDigits(bits, *this, nBits2extract);
949 }
950 
951 // @brief Extract the mod-p digits of a mod-p^{r+e} ciphertext.
952 
953 // extendExtractDigits assumes that the slots of *this contains integers mod
954 // p^{r+e} i.e., that only the free terms are nonzero. (If that assumptions
955 // does not hold then the result will not be a valid ciphertext anymore.)
956 //
957 // It returns in the slots of digits[j] the j'th-lowest digits from the
958 // integers in the slots of the input. Namely, the i'th slot of digits[j]
959 // contains the j'th digit in the p-base expansion of the integer in the i'th
960 // slot of the *this. The plaintext space of digits[j] is mod p^{e+r-j}.
961 
962 void extendExtractDigits(std::vector<Ctxt>& digits,
963  const Ctxt& c,
964  long r,
965  long e);
966 // implemented in extractDigits.cpp
967 
968 } // namespace helib
969 
970 #endif // ifndef HELIB_CTXT_H
An object that mimics the functionality of the Ctxt object, and acts as a convenient entry point for ...
Definition: Ptxt.h:280
void setOne(long newSecretKeyID=-1)
Set powerOfS=0, powerOfX=1.
Definition: Ctxt.h:110
Pre-computation to speed many automorphism on the same ciphertext.
Definition: matmul.cpp:61
const Context & getContext() const
Definition: Ctxt.h:819
long effectiveR() const
Definition: Ctxt.h:832
void setBase(long newSecretKeyID=-1)
Set powerOfS=powerOfX=1.
Definition: Ctxt.h:92
double log_of_ratio() const
Returns log(noiseBound) - log(q)
Definition: Ctxt.h:846
Inherits from Exception and std::runtime_error.
Definition: exceptions.h:105
CtxtPart(const Context &_context, const IndexSet &s, const SKHandle &otherHandle)
Definition: Ctxt.h:219
void frobeniusAutomorph(long j)
applies the automorphism p^j using smartAutomorphism
Definition: Ctxt.cpp:2082
long getKeyID() const
Definition: Ctxt.cpp:2106
bool equalsTo(const Ctxt &other, bool comparePkeys=true) const
Definition: Ctxt.cpp:165
void multiplyBy2(const Ctxt &other1, const Ctxt &other2)
Definition: Ctxt.cpp:1700
void multByConstantCKKS(double x)
multiply by a rational number or floating point
Definition: Ctxt.h:584
NTL::Vec< long > zzX
Definition: zzX.h:24
bool empty(const IndexSet &s)
Definition: IndexSet.h:182
long getPowerOfX() const
Definition: Ctxt.h:135
Ctxt & operator+=(const Ctxt &other)
Definition: Ctxt.h:416
void setPtxtMag(const NTL::xdouble &z)
Definition: Ctxt.h:826
void DummyEncrypt(const NTL::ZZX &ptxt, double size=-1.0)
Definition: Ctxt.cpp:56
Implementing polynomials (elements in the ring R_Q) in double-CRT form.
Definition: DoubleCRT.h:76
CtxtPart(const DoubleCRT &other)
Definition: Ctxt.h:226
const IndexSet & getPrimeSet() const
Definition: Ctxt.h:821
bool isOne() const
Is powerOfS==0?
Definition: Ctxt.h:119
Ctxt & operator-=(const Ctxt &other)
Definition: Ctxt.h:422
Ctxt & operator>>=(long k)
Definition: Ctxt.h:439
bool operator!=(const CtxtPart &other) const
Definition: Ctxt.h:210
void CheckCtxt(const Ctxt &c, const char *label)
print to cerr some info about ciphertext
Definition: debugging.cpp:165
const NTL::xdouble & getNoiseBound() const
Definition: Ctxt.h:823
void multByConstant(const DoubleCRT &dcrt, double size=-1.0)
Definition: Ctxt.cpp:1832
void reLinearize(long keyIdx=0)
Definition: Ctxt.cpp:591
void totalProduct(Ctxt &out, const std::vector< Ctxt > &v)
Definition: Ctxt.cpp:2309
void assertEq(const T &a, const T &b, const std::string &message)
Definition: assertions.h:108
void multByConstantCKKS(const NTL::ZZX &poly, NTL::xdouble size=NTL::xdouble(-1.0), NTL::xdouble factor=NTL::xdouble(-1.0), double roundingErr=-1.0)
Definition: Ctxt.h:614
NTL::xdouble modSwitchAddedNoiseBound() const
Estimate the added noise.
Definition: Ctxt.cpp:2116
long getP() const
Returns p.
Definition: PAlgebra.h:165
static void equalizeRationalFactors(Ctxt &c1, Ctxt &c2)
Definition: Ctxt.cpp:1151
void xorConstant(const DoubleCRT &poly, UNUSED double size=-1.0)
Definition: Ctxt.h:635
void reducePtxtSpace(long newPtxtSpace)
Reduce plaintext space to a divisor of the original plaintext space.
Definition: Ctxt.cpp:503
void multByConstantCKKS(std::pair< long, long > num)
Definition: Ctxt.h:604
bool operator!=(const Ctxt &other) const
Definition: Ctxt.h:404
A handle, describing the secret-key element that "matches" a part, of the form s^r(X^t).
Definition: Ctxt.h:78
void complexConj()
Definition: Ctxt.cpp:2012
void divideByP()
Definition: Ctxt.cpp:1969
Ctxt & operator=(const Ctxt &other)
Definition: Ctxt.h:392
std::pair< long, long > rationalApprox(double x, long denomBound=0)
Definition: NumbTh.cpp:1709
bool isCorrect() const
Would this ciphertext be decrypted without errors?
Definition: Ctxt.h:813
void addConstant(const DoubleCRT &dcrt, double size=-1.0)
Definition: Ctxt.cpp:793
bool mul(const SKHandle &a, const SKHandle &b)
Computes the "product" of two handles.
Definition: Ctxt.h:150
void read(std::istream &str)
Definition: Ctxt.cpp:2185
A dynamic set of non-negative integers.
Definition: IndexSet.h:31
void bumpNoiseBound(double factor)
Definition: Ctxt.h:705
void extendExtractDigits(std::vector< Ctxt > &digits, const Ctxt &c, long r, long e)
Definition: extractDigits.cpp:225
One entry in a ciphertext std::vector.
Definition: Ctxt.h:204
void evalPoly(const NTL::ZZX &poly)
compute the power X,X^2,...,X^n
void clear()
Definition: Ctxt.h:788
const PubKey & getPubKey() const
Definition: Ctxt.h:820
SKHandle skHandle
The handle is a public data member.
Definition: Ctxt.h:207
bool operator==(const CtxtPart &other) const
Definition: Ctxt.cpp:155
bool inCanonicalForm(long keyID=0) const
A canonical ciphertext has (at most) handles pointing to (1,s)
Definition: Ctxt.h:801
double logOfPrimeSet() const
returns the log of the prime set
Definition: Ctxt.h:766
void multByP(long e=1)
Definition: Ctxt.h:672
void read(std::istream &str)
Definition: Ctxt.cpp:2161
IndexSet naturalPrimeSet() const
"natural size" is size before squaring
Definition: Ctxt.cpp:1599
void write(std::ostream &str) const
Definition: Ctxt.cpp:2179
void multByConstant(const Ptxt< Scheme > &ptxt)
Multiply a BGV plaintext to this Ctxt.
Definition: Ctxt.h:577
long getSecretKeyID() const
Definition: Ctxt.h:136
friend std::istream & operator>>(std::istream &str, Ctxt &ctxt)
Definition: Ctxt.cpp:2225
long getPtxtSpace() const
Definition: Ctxt.h:822
SKHandle(long newPowerOfS=0, long newPowerOfX=1, long newSecretKeyID=0)
Definition: Ctxt.h:84
bool isBase(long ofKeyID=0) const
Is powerOfS==powerOfX==1?
Definition: Ctxt.h:101
Ctxt & cleanUp()
Definition: Ctxt.cpp:654
Ctxt & operator*=(const Ctxt &other)
Definition: Ctxt.h:432
void nxorConstant(const DoubleCRT &poly, UNUSED double size=-1.0)
Definition: Ctxt.h:649
void square()
Definition: Ctxt.h:686
double logOfProduct(const IndexSet &s) const
Returns the natural logarithm of productOfPrimes(s)
Definition: Context.h:467
void power(long e)
raise ciphertext to some power
Definition: polyEval.cpp:392
void multiplyBy(const Ctxt &other)
Definition: Ctxt.cpp:1681
bool operator==(const Ctxt &other) const
Definition: Ctxt.h:403
The public key.
Definition: keys.h:47
void divideBy2()
Definition: Ctxt.cpp:1944
void innerProduct(Ctxt &result, const CtPtrs &v1, const CtPtrs &v2)
Definition: Ctxt.cpp:2318
void negate()
Definition: Ctxt.cpp:1129
friend std::istream & operator>>(std::istream &s, SKHandle &handle)
Definition: Ctxt.cpp:2191
Definition: apiAttributes.h:21
void addConstantCKKS(std::pair< long, long >)
add a rational number in the form a/b, a,b are long
Definition: Ctxt.cpp:1070
void incrementalProduct(std::vector< Ctxt > &v)
Definition: Ctxt.cpp:2274
void smartAutomorph(long k)
automorphism with re-linearization
Definition: Ctxt.cpp:2031
void clear()
Set to the empty set.
Definition: IndexSet.cpp:120
void modUpToSet(const IndexSet &s)
Modulus-switching up (to a larger modulus). Must have primeSet <= s, and s must contain either all th...
Definition: Ctxt.cpp:275
void extractBits(std::vector< Ctxt > &bits, long nBits2extract=0)
Definition: Ctxt.h:946
void read(std::istream &str)
Definition: Ctxt.cpp:34
void productOfPrimes(NTL::ZZ &p, const IndexSet &s) const
The product of all the primes in the given set.
Definition: Context.cpp:178
void bringToSet(const IndexSet &s)
make the primeSet equal to newPrimeSet, via modUpToSet and modDownToSet
Definition: Ctxt.cpp:302
void automorph(long k)
Definition: Ctxt.cpp:1991
std::ostream & operator<<(std::ostream &s, const SKHandle &handle)
Definition: Ctxt.h:190
void addCtxt(const Ctxt &other, bool negative=false)
Definition: Ctxt.cpp:1333
void modDownToSet(const IndexSet &s)
Modulus-switching down (to a smaller modulus). mod-switch down to primeSet \intersect s,...
Definition: Ctxt.cpp:326
CtxtPart(const DoubleCRT &other, const SKHandle &otherHandle)
Definition: Ctxt.h:231
bool operator!=(const SKHandle &other) const
Definition: Ctxt.h:130
@ PA_cx_tag
Definition: PAlgebra.h:300
void addConstantCKKS(double x)
Definition: Ctxt.h:539
double rawModSwitch(std::vector< NTL::ZZX > &zzParts, long toModulus) const
Special-purpose modulus-switching for bootstrapping.
Definition: Ctxt.cpp:2389
const NTL::xdouble & getRatFactor() const
Definition: Ctxt.h:824
void multLowLvl(const Ctxt &other, bool destructive=false)
Definition: Ctxt.cpp:1609
void nxorConstant(const NTL::ZZX &poly, double size=-1.0)
Definition: Ctxt.h:659
friend std::ostream & operator<<(std::ostream &str, const Ctxt &ctxt)
Definition: Ctxt.cpp:2215
void dropSmallAndSpecialPrimes()
the corresponding primeSet
Definition: Ctxt.cpp:516
The secret key.
Definition: keys.h:241
Maintaining the parameters.
Definition: Context.h:121
NTL::ZZX getPolyRepr() const
Converts the slot data in this to its single polynomial representation.
long bitCapacity() const
the capacity in bits, returned as an integer
Definition: Ctxt.h:763
void addConstant(const Ptxt< Scheme > &ptxt)
Add a BGV plaintext to this Ctxt.
Definition: Ctxt.h:531
Ctxt(const Ctxt &other)=default
void write(std::ostream &str) const
Definition: Ctxt.cpp:2139
const NTL::xdouble & getPtxtMag() const
Definition: Ctxt.h:825
bool isEmpty() const
Is this an empty ciphertext without any parts.
Definition: Ctxt.h:798
void write(std::ostream &str) const
Definition: Ctxt.cpp:41
long getPowerOfS() const
Definition: Ctxt.h:134
void xorConstant(const NTL::ZZX &poly, double size=-1.0)
Definition: Ctxt.h:644
void extractDigits(std::vector< Ctxt > &digits, const Ctxt &c, long r=0)
Extract the mod-p digits of a mod-p^r ciphertext.
Definition: extractDigits.cpp:70
A Ctxt object holds a single ciphertext.
Definition: Ctxt.h:273
CtxtPart(const Context &_context, const IndexSet &s)
Definition: Ctxt.h:214
std::istream & operator>>(std::istream &s, CtxtPart &p)
Definition: Ctxt.cpp:2206
void cube()
Definition: Ctxt.h:687
void blindCtxt(const NTL::ZZX &poly)
Add a high-noise encryption of the given constant.
Definition: Ctxt.cpp:491
IndexSet ctxtPrimes
Definition: Context.h:343
bool isCKKS() const
Definition: Ctxt.h:829
bool operator==(const SKHandle &other) const
Definition: Ctxt.h:121
double naturalSize() const
Definition: Ctxt.cpp:1589
double capacity() const
returns the "capacity" of a ciphertext, which is the log of the ratio of the modulus to the noise bou...
Definition: Ctxt.h:747
PAlgebra zMStar
The structure of Zm*.
Definition: Context.h:131
void hackPtxtSpace(long newPtxtSpace)
Definition: Ctxt.h:703