EncryptedArray.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_ENCRYPTEDARRAY_H
13 #define HELIB_ENCRYPTEDARRAY_H
18 #include <exception>
19 #include <cmath>
20 #include <complex>
21 #include <NTL/Lazy.h>
22 #include <NTL/pair.h>
23 #include <NTL/SmartPtr.h>
24 
25 #include <helib/DoubleCRT.h>
26 #include <helib/Context.h>
27 #include <helib/Ctxt.h>
28 #include <helib/keys.h>
29 #include <helib/exceptions.h>
30 #include <helib/log.h>
31 
32 namespace helib {
33 
34 typedef std::complex<double> cx_double;
35 
36 // DIRT: we're using undocumented NTL interfaces here
37 // also...this probably should be defined in NTL, anyway....
38 #define HELIB_MORE_UNWRAPARGS(n) \
39  NTL_SEPARATOR_##n NTL_REPEATER_##n(NTL_UNWRAPARG)
40 
41 // these are used to implement PlaintextArray stuff routines
42 
43 // NOTE: Variables have been marked as UNUSED to silence the unused variable
44 // warnings due to unused injected variables. It has not been possible to mark
45 // the whole section with:
46 // _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") because GCC 5.4 does
47 // not honor such _Pragma.
48 // NOTE: Consider marking the section with _Pragma removing the UNUSED tag when
49 // GCC 5.4 won't be supported anymore.
50 #define PA_BOILER(type) \
51  const PAlgebraModDerived<type>& tab = ea.getTab(); \
52  UNUSED const RX& G = ea.getG(); \
53  UNUSED long n = ea.size(); \
54  UNUSED long d = ea.getDegree(); \
55  std::vector<RX>& data = pa.getData<type>(); \
56  RBak bak; \
57  bak.save(); \
58  tab.restoreContext();
59 
60 // NOTE: Variables have been marked as UNUSED to silence the unused variable
61 // warnings due to unused injected variables. It has not been possible to mark
62 // the whole section with:
63 // _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") because GCC 5.4 does
64 // not honor such _Pragma.
65 // NOTE: Consider marking the section with _Pragma removing the UNUSED tag when
66 // GCC 5.4 won't be supported anymore.
67 #define CPA_BOILER(type) \
68  const PAlgebraModDerived<type>& tab = ea.getTab(); \
69  UNUSED const RX& G = ea.getG(); \
70  UNUSED long n = ea.size(); \
71  UNUSED long d = ea.getDegree(); \
72  const std::vector<RX>& data = pa.getData<type>(); \
73  RBak bak; \
74  bak.save(); \
75  tab.restoreContext();
76 
77 class PlaintextArray; // forward reference
78 class PtxtArray; // forward reference
79 class EncryptedArray; // forward reference
80 
82 // New and improved name for EncryptedArray.
83 // Documentation should use this name.
84 
120 { // purely abstract interface
121 public:
122  virtual ~EncryptedArrayBase() {}
123 
124  virtual EncryptedArrayBase* clone() const = 0;
125  // makes this usable with ClonedPtr
126 
127  virtual PA_tag getTag() const = 0;
128 
129  virtual const Context& getContext() const = 0;
130  virtual const PAlgebra& getPAlgebra() const = 0;
131  virtual long getDegree() const = 0;
132  virtual long getP2R() const = 0;
133 
136  virtual void rotate(Ctxt& ctxt, long k) const = 0;
137 
140  virtual void shift(Ctxt& ctxt, long k) const = 0;
141 
146  virtual void rotate1D(Ctxt& ctxt, long i, long k, bool dc = false) const = 0;
147 
149  virtual void shift1D(Ctxt& ctxt, long i, long k) const = 0;
150 
153  // encode/decode arrays into plaintext polynomials
154  // These methods are working for some of the derived classes (throwing
155  // otherwise)
156  virtual void encode(zzX& ptxt, const std::vector<long>& array) const = 0;
157  virtual void encode(NTL::ZZX& ptxt, const std::vector<long>& array) const = 0;
158 
159  virtual void encode(zzX& ptxt, const std::vector<NTL::ZZX>& array) const = 0;
160  virtual void encode(NTL::ZZX& ptxt,
161  const std::vector<NTL::ZZX>& array) const = 0;
162 
163  virtual void encode(zzX& ptxt, const PlaintextArray& array) const = 0;
164  virtual void encode(NTL::ZZX& ptxt, const PlaintextArray& array) const = 0;
165 
166  virtual void encode(zzX& ptxt, const std::vector<zzX>& array) const = 0;
167 
168  //=============== new EncodedPtxt interfaces
169 
170  // BGV only
171  virtual void encode(EncodedPtxt& eptxt,
172  const std::vector<NTL::ZZX>& array) const = 0;
173  virtual void encode(EncodedPtxt& eptxt,
174  const std::vector<long>& array) const = 0;
175 
176  // CKKS only
177  // mag: defaults to Norm(array).
178  // prec: defaults to r=getAlMod().getR(), which
179  // is usually the same as context.getPrecision().
180 
181  // mag should be an upper bound on Norm(array).
182  // If an encoding will be encrypted, the user may wish
183  // to hide Norm(array) by setting mag to some data-independent
184  // upper bound. A warning is issued if Norm(array) > mag.
185 
186  // The encoding will normally have an accuracy of 2^{-prec}, meaning that
187  // Norm(array - decode(encode(array))) <= 2^{-prec}.
188  // Note that prec may be positive, negative, or zero.
189  // The exact logic is a bit heuristic, and a warning is
190  // issued if the the accuracy exceeds 2^{-prec}.
191 
192  // NOTE: Norm above is the infinity (i.e., max) norm.
193 
194  virtual void encode(EncodedPtxt& eptxt,
195  const std::vector<cx_double>& array,
196  double mag = -1,
197  OptLong prec = OptLong()) const = 0;
198 
199  virtual void encode(EncodedPtxt& eptxt,
200  const std::vector<double>& array,
201  double mag = -1,
202  OptLong prec = OptLong()) const = 0;
203 
204  // BGV and CKKS
205  virtual void encode(EncodedPtxt& eptxt,
206  const PlaintextArray& array,
207  double mag = -1,
208  OptLong prec = OptLong()) const = 0;
209  // NOTE: for BGV, mag,prec must be defaulted
210 
211  virtual void encode(EncodedPtxt& eptxt,
212  const std::vector<bool>& array) const = 0;
213  // NOTE: for CKKS, mag,prec are default
214 
215  virtual void encodeUnitSelector(EncodedPtxt& eptxt, long i) const = 0;
216  // NOTE: for CKKS, mag,prec are default
217 
218  virtual double defaultScale(UNUSED double err,
219  UNUSED OptLong prec = OptLong()) const
220  {
221  throw LogicError("function not implemented");
222  }
223 
224  virtual double defaultErr() const
225  {
226  throw LogicError("function not implemented");
227  }
228 
229  //================================
230 
231  // These methods are working for some of the derived classes (throwing
232  // otherwise)
233  virtual void decode(std::vector<long>& array, const NTL::ZZX& ptxt) const = 0;
234  virtual void decode(std::vector<NTL::ZZX>& array,
235  const NTL::ZZX& ptxt) const = 0;
236  virtual void decode(PlaintextArray& array, const NTL::ZZX& ptxt) const = 0;
237 
238  virtual void random(std::vector<long>& array) const = 0; // must be defined
239 
240  // These methods are working for some of the derived classes (throwing
241  // otherwise)
242  virtual void random(std::vector<NTL::ZZX>& array) const = 0;
243 
244  // FIXME: Inefficient implementation, calls usual decode and returns one slot
245  long decode1Slot(const NTL::ZZX& ptxt, long i) const
246  {
247  std::vector<long> v;
248  decode(v, ptxt);
249  return v.at(i);
250  }
251  void decode1Slot(NTL::ZZX& slot, const NTL::ZZX& ptxt, long i) const
252  {
253  std::vector<NTL::ZZX> v;
254  decode(v, ptxt);
255  slot = v.at(i);
256  }
257 
259  virtual void encodeUnitSelector(zzX& ptxt, long i) const = 0;
261 
263 
264  // These methods are working for some of the derived calsses (throwing
265  // otherwise)
266  virtual void decrypt(const Ctxt& ctxt,
267  const SecKey& sKey,
268  std::vector<long>& ptxt) const = 0;
269 
270  virtual void decrypt(const Ctxt& ctxt,
271  const SecKey& sKey,
272  std::vector<NTL::ZZX>& ptxt) const = 0;
273 
274  virtual void decrypt(const Ctxt& ctxt,
275  const SecKey& sKey,
276  std::vector<double>& ptxt,
277  OptLong prec = OptLong()) const = 0;
278 
279  virtual void decrypt(const Ctxt& ctxt,
280  const SecKey& sKey,
281  std::vector<cx_double>& ptxt,
282  OptLong prec = OptLong()) const = 0;
283 
284  virtual void rawDecrypt(const Ctxt& ctxt,
285  const SecKey& sKey,
286  std::vector<cx_double>& ptxt) const = 0;
287 
288  virtual void rawDecrypt(const Ctxt& ctxt,
289  const SecKey& sKey,
290  std::vector<double>& ptxt) const = 0;
291 
292  virtual void decrypt(const Ctxt& ctxt,
293  const SecKey& sKey,
294  PlaintextArray& ptxt,
295  OptLong prec = OptLong()) const = 0;
296 
297  virtual void decryptComplex(const Ctxt& ctxt,
298  const SecKey& sKey,
299  PlaintextArray& ptxt,
300  OptLong prec = OptLong()) const = 0;
301 
302  virtual void decryptReal(const Ctxt& ctxt,
303  const SecKey& sKey,
304  PlaintextArray& ptxt,
305  OptLong prec = OptLong()) const = 0;
306 
307  virtual void rawDecrypt(const Ctxt& ctxt,
308  const SecKey& sKey,
309  PlaintextArray& ptxt) const = 0;
310 
311  virtual void rawDecryptComplex(const Ctxt& ctxt,
312  const SecKey& sKey,
313  PlaintextArray& ptxt) const = 0;
314 
315  virtual void rawDecryptReal(const Ctxt& ctxt,
316  const SecKey& sKey,
317  PlaintextArray& ptxt) const = 0;
318 
319  // FIXME: Inefficient implementation, calls usual decrypt and returns one slot
320  long decrypt1Slot(const Ctxt& ctxt, const SecKey& sKey, long i) const
321  {
322  std::vector<long> v;
323  decrypt(ctxt, sKey, v);
324  return v.at(i);
325  }
326  void decrypt1Slot(NTL::ZZX& slot,
327  const Ctxt& ctxt,
328  const SecKey& sKey,
329  long i) const
330  {
331  std::vector<NTL::ZZX> v;
332  decrypt(ctxt, sKey, v);
333  slot = v.at(i);
334  }
336 
345  // These methods are working for some of the derived calsses (throwing
346  // otherwise)
347  virtual void buildLinPolyCoeffs(std::vector<NTL::ZZX>& C,
348  const std::vector<NTL::ZZX>& L) const = 0;
349 
350  // restore contexts mod p and mod G
351  virtual void restoreContext() const {}
352  virtual void restoreContextForG() const {}
353 
354  /* some non-virtual convenience functions */
355 
357  long size() const { return getPAlgebra().getNSlots(); }
358 
360  long dimension() const { return getPAlgebra().numOfGens(); }
361 
363  long sizeOfDimension(long i) const { return getPAlgebra().OrderOf(i); }
364 
366  bool nativeDimension(long i) const { return getPAlgebra().SameOrd(i); }
367 
369  long coordinate(long i, long k) const
370  {
371  return getPAlgebra().coordinate(i, k);
372  }
373 
375  long addCoord(long i, long k, long offset) const
376  {
377  return getPAlgebra().addCoord(i, k, offset);
378  }
379 
382  template <typename U>
383  void rotate1D(std::vector<U>& out,
384  const std::vector<U>& in,
385  long i,
386  long offset) const
387  {
388  assertEq(lsize(in),
389  size(),
390  "Input vector has wrong size (must equal EncryptedArray::size())");
391  out.resize(in.size());
392  for (long j : range(size()))
393  out[addCoord(i, j, offset)] = in[j];
394  }
395 };
396 
401 template <typename type>
403 {
404 public:
405  PA_INJECT(type)
406 
407 private:
408  const Context& context;
409  const PAlgebraModDerived<type>& tab;
410 
411  // FIXME: all of these types should be copyable
412  // out of context, but NTL 8.0 still does not copy
413  // matrix copies out of context correctly, as it
414  // relies on plain SetLength...I need to fix this
415  // in NTL
416  //
417  MappingData<type> mappingData; // MappingData is defined in PAlgebra.h
418 
419  NTL::Lazy<NTL::Mat<RE>> linPolyMatrix;
420 
421  NTL::Lazy<NTL::Pair<NTL::Mat<R>, NTL::Mat<R>>> normalBasisMatrices;
422  // a is the matrix, b is its inverse
423 
424 public:
425  explicit EncryptedArrayDerived(const Context& _context,
426  const RX& _G,
427  const PAlgebraMod& _tab);
428 
429  EncryptedArrayDerived(const EncryptedArrayDerived& other) // copy constructor
430  :
431  context(other.context), tab(other.tab)
432  {
433  RBak bak;
434  bak.save();
435  tab.restoreContext();
436  REBak ebak;
437  ebak.save();
438  other.mappingData.restoreContextForG();
439  mappingData = other.mappingData;
440  linPolyMatrix = other.linPolyMatrix;
441  normalBasisMatrices = other.normalBasisMatrices;
442  }
443 
445 
446  virtual EncryptedArrayBase* clone() const override
447  {
448  return new EncryptedArrayDerived(*this);
449  }
450 
451  virtual PA_tag getTag() const override { return tag; }
452  // tag is defined in PA_INJECT, see PAlgebra.h
453 
454  template <template <typename> class T, typename... Args>
455  void dispatch(Args&&... args) const
456  {
457  T<type>::apply(*this, std::forward<Args>(args)...);
458  }
459 
460  const RX& getG() const { return mappingData.getG(); }
461 
462  const NTL::Mat<R>& getNormalBasisMatrix() const
463  {
464  if (!normalBasisMatrices.built())
466  return normalBasisMatrices->a;
467  }
468 
469  const NTL::Mat<R>& getNormalBasisMatrixInverse() const
470  {
471  if (!normalBasisMatrices.built())
473  return normalBasisMatrices->b;
474  }
475 
476  void initNormalBasisMatrix() const;
477 
478  virtual void restoreContext() const override { tab.restoreContext(); }
479  virtual void restoreContextForG() const override
480  {
481  mappingData.restoreContextForG();
482  }
483 
484  virtual const Context& getContext() const override { return context; }
485  virtual const PAlgebra& getPAlgebra() const override
486  {
487  return tab.getZMStar();
488  }
489  virtual long getDegree() const override { return mappingData.getDegG(); }
490  const PAlgebraModDerived<type>& getTab() const { return tab; }
491 
492  virtual void rotate(Ctxt& ctxt, long k) const override;
493  virtual void shift(Ctxt& ctxt, long k) const override;
494  virtual void rotate1D(Ctxt& ctxt,
495  long i,
496  long k,
497  bool dc = false) const override;
498 
499  long getP2R() const override { return getTab().getPPowR(); }
500 
501  // avoid this being "hidden" by other rotate1D's
502  template <typename U>
503  void rotate1D(std::vector<U>& out,
504  const std::vector<U>& in,
505  long i,
506  long offset) const
507  {
508  EncryptedArrayBase::rotate1D(out, in, i, offset);
509  }
510  virtual void shift1D(Ctxt& ctxt, long i, long k) const override;
511 
512  /* Begin CKKS functions. They will simply throw here. */
521  // TODO: document this better (especially the prec parameter)
522  void decrypt(UNUSED const Ctxt& ctxt,
523  UNUSED const SecKey& sKey,
524  UNUSED std::vector<double>& ptxt,
525  UNUSED OptLong prec = OptLong()) const override
526  {
527  throw LogicError("Unimplemented: "
528  "EncryptedArrayDerived::decrypt for CKKS type");
529  }
538  // TODO: document this better (especially the prec parameter)
539  void decrypt(UNUSED const Ctxt& ctxt,
540  UNUSED const SecKey& sKey,
541  UNUSED std::vector<cx_double>& ptxt,
542  UNUSED OptLong prec = OptLong()) const override
543  {
544  throw LogicError("Unimplemented: "
545  "EncryptedArrayDerived::decrypt for CKKS type");
546  }
547 
548  void rawDecrypt(UNUSED const Ctxt& ctxt,
549  UNUSED const SecKey& sKey,
550  UNUSED std::vector<cx_double>& ptxt) const override
551  {
552  throw LogicError("Unimplemented: function only available for CKKS");
553  }
554 
555  void rawDecrypt(UNUSED const Ctxt& ctxt,
556  UNUSED const SecKey& sKey,
557  UNUSED std::vector<double>& ptxt) const override
558  {
559  throw LogicError("Unimplemented: function only available for CKKS");
560  }
561 
562  void rawDecrypt(UNUSED const Ctxt& ctxt,
563  UNUSED const SecKey& sKey,
564  UNUSED PlaintextArray& ptxt) const override
565  {
566  throw LogicError("function not implemented");
567  }
568 
569  void decryptComplex(UNUSED const Ctxt& ctxt,
570  UNUSED const SecKey& sKey,
571  UNUSED PlaintextArray& ptxt,
572  UNUSED OptLong prec = OptLong()) const override
573  {
574  throw LogicError("function not implemented");
575  }
576 
577  void rawDecryptComplex(UNUSED const Ctxt& ctxt,
578  UNUSED const SecKey& sKey,
579  UNUSED PlaintextArray& ptxt) const override
580  {
581  throw LogicError("function not implemented");
582  }
583 
584  void decryptReal(UNUSED const Ctxt& ctxt,
585  UNUSED const SecKey& sKey,
586  UNUSED PlaintextArray& ptxt,
587  UNUSED OptLong prec = OptLong()) const override
588  {
589  throw LogicError("function not implemented");
590  }
591 
592  void rawDecryptReal(UNUSED const Ctxt& ctxt,
593  UNUSED const SecKey& sKey,
594  UNUSED PlaintextArray& ptxt) const override
595  {
596  throw LogicError("function not implemented");
597  }
598  /* End CKKS functions. */
599 
600  virtual void encode(NTL::ZZX& ptxt,
601  const std::vector<long>& array) const override
602  {
603  genericEncode(ptxt, array);
604  }
605 
606  virtual void encode(zzX& ptxt, const std::vector<long>& array) const override
607  {
608  genericEncode(ptxt, array);
609  }
610 
611  virtual void encode(NTL::ZZX& ptxt,
612  const std::vector<NTL::ZZX>& array) const override
613  {
614  genericEncode(ptxt, array);
615  }
616 
617  virtual void encode(zzX& ptxt, const std::vector<zzX>& array) const override
618  {
619  genericEncode(ptxt, array);
620  }
621 
622  virtual void encode(NTL::ZZX& ptxt,
623  const PlaintextArray& array) const override;
624  virtual void encode(zzX& ptxt, const PlaintextArray& array) const override;
625 
626  virtual void encodeUnitSelector(zzX& ptxt, long i) const override;
627 
628  virtual void encode(zzX& ptxt,
629  const std::vector<NTL::ZZX>& array) const override
630  {
631  NTL::ZZX tmp;
632  encode(tmp, array);
633  convert(ptxt, tmp);
634  }
635 
636  //================ new EncodedPtxt interfaces
637 
638  virtual void encode(EncodedPtxt& eptxt,
639  const std::vector<NTL::ZZX>& array) const override
640  {
641  zzX poly;
642  encode(poly, array);
643  eptxt.resetBGV(poly, getP2R(), getContext());
644  }
645 
646  virtual void encode(EncodedPtxt& eptxt,
647  const std::vector<long>& array) const override
648  {
649  zzX poly;
650  encode(poly, array);
651  eptxt.resetBGV(poly, getP2R(), getContext());
652  }
653 
654  virtual void encode(UNUSED EncodedPtxt& eptxt,
655  UNUSED const std::vector<cx_double>& array,
656  UNUSED double mag = -1,
657  UNUSED OptLong prec = OptLong()) const override
658  {
659  throw LogicError("function not implemented for BGV");
660  }
661 
662  virtual void encode(UNUSED EncodedPtxt& eptxt,
663  UNUSED const std::vector<double>& array,
664  UNUSED double mag = -1,
665  UNUSED OptLong prec = OptLong()) const override
666  {
667  throw LogicError("function not implemented for BGV");
668  }
669 
670  virtual void encode(EncodedPtxt& eptxt,
671  const PlaintextArray& array,
672  double mag = -1,
673  OptLong prec = OptLong()) const override
674  {
675  assertTrue(mag < 0 && !prec.isDefined(),
676  "BGV encoding: mag,prec set must be defaulted");
677  zzX poly;
678  encode(poly, array);
679  eptxt.resetBGV(poly, getP2R(), getContext());
680  }
681 
682  virtual void encode(EncodedPtxt& eptxt,
683  const std::vector<bool>& array) const override
684  {
685  std::vector<long> array1;
686  convert(array1, array);
687  encode(eptxt, array1);
688  }
689 
690  virtual void encodeUnitSelector(EncodedPtxt& eptxt, long i) const override
691  {
692  zzX poly;
693  encodeUnitSelector(poly, i);
694  eptxt.resetBGV(poly, getP2R(), getContext());
695  }
696 
697  //===========================================
698 
699  virtual void decode(std::vector<long>& array,
700  const NTL::ZZX& ptxt) const override
701  {
702  genericDecode(array, ptxt);
703  }
704 
705  virtual void decode(std::vector<NTL::ZZX>& array,
706  const NTL::ZZX& ptxt) const override
707  {
708  genericDecode(array, ptxt);
709  }
710 
711  virtual void decode(PlaintextArray& array,
712  const NTL::ZZX& ptxt) const override;
713  virtual void decode(PlaintextArray& array, const zzX& ptxt) const;
714 
715  // choose at random and convert to std::vector<long>
716  virtual void random(std::vector<long>& array) const override
717  {
718  genericRandom(array);
719  }
720 
721  // choose at random and convert to std::vector<ZZX>
722  virtual void random(std::vector<NTL::ZZX>& array) const override
723  {
724  genericRandom(array);
725  }
726 
727  virtual void decrypt(const Ctxt& ctxt,
728  const SecKey& sKey,
729  std::vector<long>& ptxt) const override
730  {
731  genericDecrypt(ctxt, sKey, ptxt);
732  if (ctxt.getPtxtSpace() < getP2R()) {
733  helib::Warning("EncryptedArray::decrypt: reducing plaintext modulus");
734  for (long i = 0; i < (long)ptxt.size(); i++)
735  ptxt[i] %= ctxt.getPtxtSpace();
736  }
737  }
738 
739  virtual void decrypt(const Ctxt& ctxt,
740  const SecKey& sKey,
741  std::vector<NTL::ZZX>& ptxt) const override
742  {
743  genericDecrypt(ctxt, sKey, ptxt);
744  if (ctxt.getPtxtSpace() < getP2R()) {
745  helib::Warning("EncryptedArray::decrypt: reducing plaintext modulus");
746  for (long i = 0; i < (long)ptxt.size(); i++)
747  PolyRed(ptxt[i], ctxt.getPtxtSpace(), /*abs=*/true);
748  }
749  }
750 
751  virtual void decrypt(const Ctxt& ctxt,
752  const SecKey& sKey,
753  PlaintextArray& ptxt,
754  OptLong prec = OptLong()) const override
755  {
756  if (prec.isDefined())
757  throw LogicError("EncryptedArray::decrypt: the precision parameter "
758  "(prec) must be defaulted");
759 
760  genericDecrypt(ctxt, sKey, ptxt);
761  if (ctxt.getPtxtSpace() < getP2R()) {
762  throw LogicError("EncryptedArray::decrypt: bad plaintext modulus");
763  // FIXME: Reduce mod the ciphertext plaintext space as above
764  // What we would have to do is:
765  // 1. convert the PlaintextArray to a vector of ZZX's
766  // 2. call PolyRed as above to reduce coefficients
767  // 3. convert the vector of ZZX's back to a PlaintextArray
768  // But do we *really* want to do this?
769  }
770  }
771 
772  virtual void buildLinPolyCoeffs(
773  std::vector<NTL::ZZX>& C,
774  const std::vector<NTL::ZZX>& L) const override;
775 
776  /* the following are specialized methods, used to work over extension
777  fields... they assume the modulus context is already set
778  */
779 
780  void encode(zzX& ptxt, const std::vector<RX>& array) const;
781  void decode(std::vector<RX>& array, const zzX& ptxt) const;
782 
783  void encode(NTL::ZZX& ptxt, const std::vector<RX>& array) const;
784  void decode(std::vector<RX>& array, const NTL::ZZX& ptxt) const;
785 
786  void encode(RX& ptxt, const std::vector<RX>& array) const;
787  void decode(std::vector<RX>& array, const RX& ptxt) const;
788 
789  // Choose random polynomial of the right degree, coeffs in GF2 or zz_p
790  void random(std::vector<RX>& array) const
791  {
792  array.resize(size());
793  for (long i = 0; i < size(); i++)
794  NTL::random(array[i], getDegree());
795  }
796 
797  void decrypt(const Ctxt& ctxt,
798  const SecKey& sKey,
799  std::vector<RX>& ptxt) const
800  {
801  genericDecrypt(ctxt, sKey, ptxt);
802  }
803 
804  virtual void buildLinPolyCoeffs(std::vector<RX>& C,
805  const std::vector<RX>& L) const;
806 
807 private:
808  /* helper template methods, to avoid repetitive code */
809 
810  template <typename T>
811  void genericEncode(NTL::ZZX& ptxt, const T& array) const
812  {
813  RBak bak;
814  bak.save();
815  tab.restoreContext();
816 
817  std::vector<RX> array1;
818  convert(array1, array);
819  encode(ptxt, array1);
820  }
821 
822  template <typename T>
823  void genericEncode(zzX& ptxt, const T& array) const
824  {
825  RBak bak;
826  bak.save();
827  tab.restoreContext();
828 
829  std::vector<RX> array1;
830  convert(array1, array);
831  encode(ptxt, array1);
832  }
833 
834  template <typename T>
835  void genericDecode(T& array, const NTL::ZZX& ptxt) const
836  {
837  RBak bak;
838  bak.save();
839  tab.restoreContext();
840 
841  std::vector<RX> array1;
842  decode(array1, ptxt);
843  convert(array, array1);
844  }
845 
846  // T is std::vector<long> or std::vector<ZZX>
847  template <typename T>
848  void genericRandom(T& array) const
849  {
850  static_assert(std::is_same<T, std::vector<long>>::value ||
851  std::is_same<T, std::vector<NTL::ZZX>>::value,
852  "Template type T must be either std::vector<long> or "
853  "std::vector<NTL::ZZX>.");
854  RBak bak;
855  // backup NTL modulus
856  bak.save();
857  tab.restoreContext();
858 
859  std::vector<RX> array1; // RX is GF2X or zz_pX
860  random(array1); // choose random coefficients from GF2/zz_p
861  convert(array, array1); // convert to type T (see NumbTh.h)
862  }
863 
864  template <typename T>
865  void genericDecrypt(const Ctxt& ctxt, const SecKey& sKey, T& array) const
866  {
867  assertEq(&context,
868  &ctxt.getContext(),
869  "Cannot decrypt when ciphertext has different context than "
870  "EncryptedArray");
871  NTL::ZZX pp;
872  sKey.Decrypt(pp, ctxt);
873  decode(array, pp);
874  }
875 };
876 
878 template <>
880 {
881  const Context& context;
882  const PAlgebraModCx& alMod;
883 
884  zzX iEncoded; // an encoded plaintext with i in all the slots
885  // VJS-FIXME: this is a bad idea...see commenets in EaCx.cpp
886 
887 public:
888  static double roundedSize(double x)
889  {
890  long rounded = std::ceil(std::fabs(x));
891  if (rounded < 1)
892  rounded = 1;
893  return double(1L << NTL::NumBits(rounded - 1));
894  }
895 
896  double encodei(zzX& ptxt, long precision = -1) const; // encode i in all slots
897 
898  explicit EncryptedArrayDerived(const Context& _context) :
899  context(_context), alMod(context.getAlMod().getCx())
900  {
901  clear(iEncoded);
902  }
903  EncryptedArrayDerived(const Context& _context, const PAlgebraModCx& _alMod) :
904  context(_context), alMod(_alMod)
905  {
906  clear(iEncoded);
907  }
908 
909  EncryptedArrayBase* clone() const override
910  {
911  return new EncryptedArrayDerived(*this);
912  }
913 
914  const zzX& getiEncoded() const;
915  PA_tag getTag() const override { return PA_cx_tag; }
916  const Context& getContext() const override { return context; }
917  const PAlgebra& getPAlgebra() const override { return alMod.getZMStar(); }
918  long getDegree() const override { return 2L; }
919 
920  void rotate(Ctxt& ctxt, long k) const override;
921  void shift(Ctxt& ctxt, long k) const override;
922  void rotate1D(Ctxt& ctxt, long i, long k, bool dc = false) const override;
923  void shift1D(Ctxt& ctxt, long i, long k) const override;
924 
925  long getP2R() const override { return alMod.getPPowR(); }
926 
927  // the following help with some template code
928  cx_double getG() const { return 0.0; }
929  const PAlgebraModCx getTab() const { return alMod; }
930 
931  template <template <typename> class T, typename... Args>
932  void dispatch(Args&&... args) const
933  {
934  T<PA_cx>::apply(*this, std::forward<Args>(args)...);
935  }
936 
937  /* Begin BGV functions. They will simply throw here. */
938  // encode
945  void encode(UNUSED zzX& ptxt,
946  UNUSED const std::vector<long>& array) const override
947  {
948  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
949  }
956  void encode(UNUSED NTL::ZZX& ptxt,
957  UNUSED const std::vector<long>& array) const override
958  {
959  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
960  }
967  void encode(UNUSED zzX& ptxt,
968  UNUSED const std::vector<zzX>& array) const override
969  {
970  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
971  }
978  void encode(UNUSED zzX& ptxt,
979  UNUSED const PlaintextArray& array) const override
980  {
981  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
982  }
989  void encode(UNUSED NTL::ZZX& ptxt,
990  UNUSED const std::vector<NTL::ZZX>& array) const override
991  {
992  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
993  }
1000  void encode(UNUSED NTL::ZZX& ptxt,
1001  UNUSED const PlaintextArray& array) const override
1002  {
1003  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
1004  }
1005 
1006  void encode(UNUSED zzX& ptxt,
1007  UNUSED const std::vector<NTL::ZZX>& array) const override
1008  {
1009  throw LogicError("Unimplemented: EncryptedArrayCx::encode for BGV type");
1010  }
1011 
1012  // decode
1019  void decode(UNUSED std::vector<long>& array,
1020  UNUSED const NTL::ZZX& ptxt) const override
1021  {
1022  throw LogicError("Unimplemented: EncryptedArrayCx::decode for BGV type");
1023  }
1030  void decode(UNUSED std::vector<NTL::ZZX>& array,
1031  UNUSED const NTL::ZZX& ptxt) const override
1032  {
1033  throw LogicError("Unimplemented: EncryptedArrayCx::decode for BGV type");
1034  }
1041  void decode(UNUSED PlaintextArray& array,
1042  UNUSED const NTL::ZZX& ptxt) const override
1043  {
1044  throw LogicError("Unimplemented: EncryptedArrayCx::decode for BGV type");
1045  }
1046 
1047  // random
1053  void random(UNUSED std::vector<NTL::ZZX>& array) const override
1054  {
1055  throw LogicError("Unimplemented: EncryptedArrayCx::decode for BGV type");
1056  }
1057 
1058  // decrypt
1066  void decrypt(UNUSED const Ctxt& ctxt,
1067  UNUSED const SecKey& sKey,
1068  UNUSED std::vector<long>& ptxt) const override
1069  {
1070  throw LogicError("Unimplemented: EncryptedArrayCx::decrypt for BGV type");
1071  }
1079  void decrypt(UNUSED const Ctxt& ctxt,
1080  UNUSED const SecKey& sKey,
1081  UNUSED std::vector<NTL::ZZX>& ptxt) const override
1082  {
1083  throw LogicError("Unimplemented: EncryptedArrayCx::decrypt for BGV type");
1084  }
1085 
1086  // buildLinPolyCoeffs
1093  void buildLinPolyCoeffs(UNUSED std::vector<NTL::ZZX>& C,
1094  UNUSED const std::vector<NTL::ZZX>& L) const override
1095  {
1096  throw LogicError("Unimplemented: "
1097  "EncryptedArrayCx::buildLinPolyCoeffs for BGV type");
1098  }
1099  /* End BGV functions. */
1100 
1101  // These EaCx-specific encoding routines return the
1102  // scaling factor that was used in the encoding routine
1103  double encode(zzX& ptxt,
1104  const std::vector<cx_double>& array,
1105  double useThisSize,
1106  long precision = -1) const;
1107  double encode(zzX& ptxt,
1108  const std::vector<double>& array,
1109  double useThisSize,
1110  long precision = -1) const
1111  {
1112  std::vector<cx_double> tmp;
1113  convert(tmp, array);
1114  return encode(ptxt, tmp, useThisSize, precision);
1115  }
1116  double encode(zzX& ptxt,
1117  const std::vector<long>& array,
1118  double useThisSize,
1119  long precision = -1) const
1120  {
1121  std::vector<cx_double> tmp;
1122  convert(tmp, array);
1123  return encode(ptxt, tmp, useThisSize, precision);
1124  }
1125 
1135  template <typename Scheme>
1136  double encode(zzX& out,
1137  const Ptxt<Scheme>& ptxt,
1138  double useThisSize,
1139  long precision = -1) const
1140  {
1141  return encode(out, ptxt.getSlotRepr(), useThisSize, precision);
1142  }
1143 
1144  // VJS-FIXME: why do some encode functions have a
1145  // default value for useThisSize and others do not???
1146  // It's very confusing
1147 
1148  // VJS-FIXME: these routine have a number of issues and should
1149  // be deprecated in favor of the new EncodedPtxt-based routines
1150 
1157  double encode(zzX& ptxt,
1158  double aSingleNumber,
1159  double useThisSize = -1,
1160  long precision = -1) const;
1161 
1168  template <typename PTXT>
1169  double encode(NTL::ZZX& ptxt,
1170  const PTXT& pt,
1171  double useThisSize = -1,
1172  long precision = -1) const
1173  {
1174  zzX tmp;
1175  double f = encode(tmp, pt, useThisSize, precision);
1176  convert(ptxt, tmp);
1177  return f;
1178  }
1179 
1180  //========= new EncodedPtxt interface
1181 
1182  virtual void encode(UNUSED EncodedPtxt& eptxt,
1183  UNUSED const std::vector<NTL::ZZX>& array) const override
1184  {
1185  throw LogicError("function not implemented for CKKS");
1186  }
1187 
1188  virtual void encode(UNUSED EncodedPtxt& eptxt,
1189  UNUSED const std::vector<long>& array) const override
1190  {
1191  throw LogicError("function not implemented for CKKS");
1192  }
1193 
1194  virtual void encode(EncodedPtxt& eptxt,
1195  const std::vector<cx_double>& array,
1196  double mag = -1,
1197  OptLong prec = OptLong()) const override;
1198  // implemented in EaCx.cpp
1199 
1200  virtual void encode(EncodedPtxt& eptxt,
1201  const std::vector<double>& array,
1202  double mag = -1,
1203  OptLong prec = OptLong()) const override
1204  {
1205  std::vector<cx_double> array1;
1206  convert(array1, array);
1207  encode(eptxt, array1, mag, prec);
1208  }
1209 
1210  virtual void encode(EncodedPtxt& eptxt,
1211  const PlaintextArray& array,
1212  double mag = -1,
1213  OptLong prec = OptLong()) const override;
1214  // implemented in EaCx.cpp
1215 
1216  virtual void encode(EncodedPtxt& eptxt,
1217  const std::vector<bool>& array) const override
1218  {
1219  std::vector<cx_double> array1;
1220  convert(array1, array);
1221  encode(eptxt, array1);
1222  }
1223 
1224  virtual void encodeUnitSelector(EncodedPtxt& eptxt, long i) const override
1225  {
1226  std::vector<cx_double> array(this->size(), cx_double(0.0));
1227  array.at(i) = 1.0;
1228  encode(eptxt, array);
1229  // VJS-FIXME: this could be much more efficient
1230  }
1231 
1232  //==========================================
1233 
1234  void encryptOneNum(Ctxt& ctxt,
1235  const PubKey& key,
1236  double num,
1237  double useThisSize = -1,
1238  long precision = -1) const
1239  {
1240  assertEq(&getContext(),
1241  &ctxt.getContext(),
1242  "Cannot encrypt when ciphertext has different context than "
1243  "EncryptedArray");
1244  if (useThisSize <= 0.0)
1245  useThisSize = roundedSize(num); // rounded to power of two
1246  zzX pp; // Convert num into a plaintext polynomial
1247  double f = encode(pp, num, useThisSize, precision);
1248 
1249  key.CKKSencrypt(ctxt, pp, useThisSize, f); // encrypt resulting polynomial
1250  }
1251 
1252  template <typename PTXT>
1253  void encrypt(Ctxt& ctxt,
1254  const PubKey& key,
1255  const PTXT& ptxt,
1256  double useThisSize,
1257  long precision = -1) const
1258  {
1259  assertEq(&getContext(),
1260  &ctxt.getContext(),
1261  "Cannot encrypt when ciphertext has different context than "
1262  "EncryptedArray");
1263  zzX pp;
1264  double f = encode(pp, ptxt, useThisSize, precision);
1265  // Convert into a polynomial
1266  key.CKKSencrypt(ctxt, pp, useThisSize, f); // encrypt the polynomial
1267  }
1268 
1269  template <typename PTXT>
1270  void encrypt(Ctxt& ctxt, const PubKey& key, const PTXT& ptxt) const
1271  {
1272  encrypt(ctxt, key, ptxt, -1.0, -1);
1273  }
1274 
1275  // The methods below override EncryptedArrayBase, they use
1276  // the default size=0 and precision=0, which yield size=1
1277  // and precision=2^{-alMod.getR()-1}
1278  void encodeUnitSelector(zzX& ptxt, long i) const override
1279  {
1280  std::vector<cx_double> v(this->size(), cx_double(0.0));
1281  v.at(i) = cx_double(1.0, 0.0);
1282  encode(ptxt, v, /*size=*/1.0, /*default precision*/ -1);
1283  // VJS-FIXME: this could be much more efficient
1284  } // The implicit scaling factor is encodeScalingFactor() below
1285 
1286  // A bound on the rounding error for encoding
1287  double encodeRoundingError() const
1288  {
1289  const Context& context = getContext();
1290  long phim = context.getPhiM();
1291 
1292  // VJS-NOTE: I changed m to phi(m).
1293  // VJS-FIXME: for the power of two case, noiseBoundForUniform
1294  // is a bit too pessimistic, as this is the circularly symmetric
1295  // case.
1296  return context.noiseBoundForUniform(0.5, phim);
1297  }
1298  // The scaling factor to use when encoding/decoding plaintext elements
1299  long encodeScalingFactor(long precision = -1, double roundErr = -1.0) const
1300  {
1301  assertTrue<InvalidArgument>(precision < NTL_SP_BOUND,
1302  "Precision exceeds max single precision bound");
1303  if (precision <= 0)
1304  precision = (1L << alMod.getR());
1305  if (roundErr < 0)
1306  roundErr = encodeRoundingError();
1307 
1308  // VJS-FIXME: the computation of f and/or return value could overflow
1309 
1310  long f = std::ceil(precision * roundErr);
1311  // We round the factor up to the next power of two
1312  return (1L << NTL::NextPowerOfTwo(f));
1313  }
1314 
1315  virtual double defaultErr() const override
1316  {
1317  const Context& context = getContext();
1318  long phim = context.getPhiM();
1319 
1320  // VJS-FIXME: For the power of two case, noiseBoundForUniform
1321  // is a bit too pessimistic, as this is the circularly symmetric
1322  // case.
1323 
1324  // VJS-NOTE: this is extremey heuristic: we are assuming
1325  // that the coefficients mod 1 are modeled as uniform
1326  // on [0,1].
1327 
1328  return context.noiseBoundForUniform(0.5, phim);
1329  }
1330 
1331  virtual double defaultScale(double err,
1332  OptLong prec = OptLong()) const override
1333  {
1334  if (err < 1.0)
1335  err = 1.0;
1336  long r = alMod.getR(); // default r-value
1337  if (prec.isDefined())
1338  r = prec; // override if necessary
1339 
1340  // we want to compute
1341  // 2^(ceil(log2(err*2^r))) = 2^(ceil(log2(err) + r))
1342  // = 2^(r + ceil(log2(err)))
1343  int e;
1344  std::frexp(1 / err, &e);
1345  // we have 2^{e-1} <= 1/err < 2^e, i.e.,
1346  // 2^{-e} < err <= 2^{-e+1}
1347  // so ceil(log2(err)) = -e+1
1348  return std::ldexp(1.0, r - e + 1);
1349  }
1350 
1351  void decode(std::vector<cx_double>& array,
1352  const zzX& ptxt,
1353  double scaling) const;
1354 
1355  void decode(std::vector<cx_double>& array,
1356  const NTL::ZZX& ptxt,
1357  double scaling) const
1358  {
1359  zzX tmp;
1360  convert(tmp, ptxt);
1361  decode(array, tmp, scaling);
1362  }
1363 
1364  void decode(std::vector<double>& array, const zzX& ptxt, double scaling) const
1365  {
1366  std::vector<cx_double> v;
1367  decode(v, ptxt, scaling);
1368  project(array, v);
1369  }
1370 
1371  void decode(std::vector<double>& array,
1372  const NTL::ZZX& ptxt,
1373  double scaling) const
1374  {
1375  std::vector<cx_double> v;
1376  decode(v, ptxt, scaling);
1377  project(array, v);
1378  }
1379 
1384  void random(std::vector<cx_double>& array, double rad = 1.0) const;
1385  void random(std::vector<double>& array, double rad = 1.0) const
1386  {
1387  std::vector<cx_double> v;
1388  random(v, rad);
1389  project(array, v);
1390  }
1391  void random(std::vector<long>& array) const override
1392  {
1393  std::vector<cx_double> v;
1394  random(v, 1.0);
1395  project_and_round(array, v);
1396  }
1397 
1398  void decrypt(const Ctxt& ctxt,
1399  const SecKey& sKey,
1400  std::vector<cx_double>& ptxt,
1401  OptLong prec = OptLong()) const override;
1402 
1403  void decrypt(const Ctxt& ctxt,
1404  const SecKey& sKey,
1405  std::vector<double>& ptxt,
1406  OptLong prec = OptLong()) const override;
1407 
1408  void rawDecrypt(const Ctxt& ctxt,
1409  const SecKey& sKey,
1410  std::vector<cx_double>& ptxt) const override;
1411 
1412  void rawDecrypt(const Ctxt& ctxt,
1413  const SecKey& sKey,
1414  std::vector<double>& ptxt) const override;
1415 
1416  void decrypt(const Ctxt& ctxt,
1417  const SecKey& sKey,
1418  PlaintextArray& ptxt,
1419  OptLong prec = OptLong()) const override
1420  {
1421  decryptReal(ctxt, sKey, ptxt, prec);
1422  }
1423 
1424  void rawDecrypt(const Ctxt& ctxt,
1425  const SecKey& sKey,
1426  PlaintextArray& ptxt) const override
1427  {
1428  rawDecryptReal(ctxt, sKey, ptxt);
1429  }
1430 
1431  void decryptComplex(const Ctxt& ctxt,
1432  const SecKey& sKey,
1433  PlaintextArray& ptxt,
1434  OptLong prec = OptLong()) const override;
1435 
1436  void rawDecryptComplex(const Ctxt& ctxt,
1437  const SecKey& sKey,
1438  PlaintextArray& ptxt) const override;
1439 
1440  void decryptReal(const Ctxt& ctxt,
1441  const SecKey& sKey,
1442  PlaintextArray& ptxt,
1443  OptLong prec = OptLong()) const override;
1444 
1445  void rawDecryptReal(const Ctxt& ctxt,
1446  const SecKey& sKey,
1447  PlaintextArray& ptxt) const override;
1448 
1460  // VJS-FIXME: something seems odd here. This code clearly only
1461  // works for CKKS because ptxtArray has type vector<cx_double>.
1462  // However, Scheme could be CKKS or BGV. Is there a specialized
1463  // version of this somewhere?
1464  // TODO: document this better (especially the prec parameter)
1465  template <typename Scheme>
1466  void decrypt(const Ctxt& ctxt,
1467  const SecKey& sKey,
1468  Ptxt<Scheme>& ptxt,
1469  OptLong prec = OptLong()) const
1470  {
1471  std::vector<cx_double> ptxtArray;
1472  decrypt(ctxt, sKey, ptxtArray, prec);
1473  ptxt.setData(std::move(ptxtArray));
1474  }
1475 
1476  void extractRealPart(Ctxt& c) const;
1477 
1483  template <typename Scheme>
1485  {
1486  p = p.real();
1487  }
1488 
1494  template <typename Scheme>
1496  {
1497  p = p.imag();
1498  }
1499 
1503  void extractImPart(Ctxt& c, DoubleCRT* dcrt = nullptr) const;
1504 
1515 
1517  void buildLinPolyCoeffs(std::vector<zzX>& C,
1518  const cx_double& oneImage,
1519  const cx_double& iImage,
1520  long precision = 0) const;
1521 
1523  void buildLinPolyCoeffs(std::vector<zzX>& C,
1524  const std::vector<cx_double>& oneImages,
1525  const std::vector<cx_double>& iImages,
1526  long precision = 0) const;
1528 };
1529 
1531 
1532 // plaintextAutomorph: Compute b(X) = a(X^k) mod Phi_m(X).
1533 template <typename RX, typename RXModulus>
1535  const RX& a,
1536  long k,
1537  long m,
1538  const RXModulus& PhimX)
1539 {
1540  // compute b(X) = a(X^k) mod (X^m-1)
1541  if (k == 1 || deg(a) <= 0) {
1542  bb = a;
1543  return;
1544  }
1545 
1546  RX b;
1547  b.SetLength(m);
1548  NTL::mulmod_precon_t precon = NTL::PrepMulModPrecon(k, m);
1549  for (long j = 0; j <= deg(a); j++)
1550  b[NTL::MulModPrecon(j, k, m, precon)] = a[j]; // b[j*k mod m] = a[j]
1551  b.normalize();
1552 
1553  rem(bb, b, PhimX); // reduce modulo the m'th cyclotomic
1554 }
1555 
1556 // same as above, but k = g_i^j mod m.
1557 // also works with i == ea.getPalgebra().numOfGens(),
1558 // which means Frobenius
1559 
1560 template <typename RX, typename type>
1562  const RX& a,
1563  long i,
1564  long j,
1565  const EncryptedArrayDerived<type>& ea)
1566 {
1567  const PAlgebra& zMStar = ea.getPAlgebra();
1568  const auto& F = ea.getTab().getPhimXMod();
1569  long k = zMStar.genToPow(i, j);
1570  long m = zMStar.getM();
1571  plaintextAutomorph(b, a, k, m, F);
1572 }
1573 
1575 EncryptedArrayBase* buildEncryptedArray(const Context& context,
1576  const PAlgebraMod& alMod,
1577  const NTL::ZZX& G = NTL::ZZX::zero());
1578 
1583 {
1584 private:
1585  const PAlgebraMod& alMod;
1587 
1588 public:
1590  EncryptedArray(const Context& context, const NTL::ZZX& G = NTL::ZZX(1, 1)) :
1591  alMod(context.getAlMod()),
1592  rep(buildEncryptedArray(context, context.getAlMod(), G))
1593  {}
1595  EncryptedArray(const Context& context, const PAlgebraMod& _alMod) :
1596  alMod(_alMod), rep(buildEncryptedArray(context, _alMod))
1597  {}
1598 
1599  // NOTES:
1600  // (1) the second constructor is provided mainly for BGV bootstrapping
1601  // (2) we do not currently provide a constructor that allows
1602  // the user to select both G and alMod, but this could be added
1603 
1604  // copy constructor:
1605 
1606 #if 1
1607  EncryptedArray& operator=(const EncryptedArray& other) = delete;
1608 #else
1609  EncryptedArray& operator=(const EncryptedArray& other)
1610  {
1611  if (this == &other)
1612  return *this;
1613  assertEq(&alMod,
1614  &other.alMod,
1615  "Cannot assign EncryptedArrays with different algebras");
1616  rep = other.rep;
1617  return *this;
1618  }
1619 #endif
1620 
1624  template <typename type>
1626  {
1627  return dynamic_cast<const EncryptedArrayDerived<type>&>(*rep);
1628  }
1629 
1630  const EncryptedArrayCx& getCx() const
1631  {
1632  return dynamic_cast<const EncryptedArrayCx&>(*rep);
1633  }
1634 
1637 
1638  PA_tag getTag() const { return rep->getTag(); }
1639  bool isCKKS() const { return getTag() == PA_cx_tag; }
1640 
1641  template <template <typename> class T, typename... Args>
1642  void dispatch(Args&&... args) const
1643  {
1644  switch (getTag()) {
1645  case PA_GF2_tag: {
1647  static_cast<const EncryptedArrayDerived<PA_GF2>*>(rep.get());
1648  p->dispatch<T>(std::forward<Args>(args)...);
1649  break;
1650  }
1651  case PA_zz_p_tag: {
1653  static_cast<const EncryptedArrayDerived<PA_zz_p>*>(rep.get());
1654  p->dispatch<T>(std::forward<Args>(args)...);
1655  break;
1656  }
1657  case PA_cx_tag: {
1658  const EncryptedArrayDerived<PA_cx>* p =
1659  static_cast<const EncryptedArrayDerived<PA_cx>*>(rep.get());
1660  p->dispatch<T>(std::forward<Args>(args)...);
1661  break;
1662  }
1663  default:
1664  throw RuntimeError("EncryptedArray: bad tag");
1665  }
1666  }
1667 
1668  const Context& getContext() const { return rep->getContext(); }
1669  const PAlgebraMod& getAlMod() const { return alMod; }
1670  const PAlgebra& getPAlgebra() const { return rep->getPAlgebra(); }
1671  long getDegree() const { return rep->getDegree(); }
1672  void rotate(Ctxt& ctxt, long k) const { rep->rotate(ctxt, k); }
1673  void shift(Ctxt& ctxt, long k) const { rep->shift(ctxt, k); }
1674  void rotate1D(Ctxt& ctxt, long i, long k, bool dc = false) const
1675  {
1676  rep->rotate1D(ctxt, i, k, dc);
1677  }
1678  void shift1D(Ctxt& ctxt, long i, long k) const { rep->shift1D(ctxt, i, k); }
1679 
1680  void encode(zzX& ptxt, const std::vector<long>& array) const
1681  {
1682  rep->encode(ptxt, array);
1683  }
1684 
1685  void encode(NTL::ZZX& ptxt, const std::vector<long>& array) const
1686  {
1687  rep->encode(ptxt, array);
1688  }
1689 
1690  void encode(zzX& ptxt, const std::vector<zzX>& array) const
1691  {
1692  rep->encode(ptxt, array);
1693  }
1694 
1695  void encode(zzX& ptxt, const PlaintextArray& array) const
1696  {
1697  rep->encode(ptxt, array);
1698  }
1699 
1700  void encode(NTL::ZZX& ptxt, const std::vector<NTL::ZZX>& array) const
1701  {
1702  rep->encode(ptxt, array);
1703  }
1704 
1705  void encode(NTL::ZZX& ptxt, const PlaintextArray& array) const
1706  {
1707  rep->encode(ptxt, array);
1708  }
1709 
1710  void encode(zzX& ptxt, const std::vector<NTL::ZZX>& array) const
1711  {
1712  rep->encode(ptxt, array);
1713  }
1714 
1715  //=============== new EncodedPtxt interfaces
1716 
1717  void encode(EncodedPtxt& eptxt, const std::vector<NTL::ZZX>& array) const
1718  {
1719  rep->encode(eptxt, array);
1720  }
1721 
1722  void encode(EncodedPtxt& eptxt, const std::vector<long>& array) const
1723  {
1724  rep->encode(eptxt, array);
1725  }
1726 
1727  void encode(EncodedPtxt& eptxt,
1728  const std::vector<cx_double>& array,
1729  double mag = -1,
1730  OptLong prec = OptLong()) const
1731  {
1732  rep->encode(eptxt, array, mag, prec);
1733  }
1734 
1735  void encode(EncodedPtxt& eptxt,
1736  const std::vector<double>& array,
1737  double mag = -1,
1738  OptLong prec = OptLong()) const
1739  {
1740  rep->encode(eptxt, array, mag, prec);
1741  }
1742 
1743  void encode(EncodedPtxt& eptxt,
1744  const PlaintextArray& array,
1745  double mag = -1,
1746  OptLong prec = OptLong()) const
1747  {
1748  rep->encode(eptxt, array, mag, prec);
1749  }
1750 
1751  void encode(EncodedPtxt& eptxt, const std::vector<bool>& array) const
1752  {
1753  rep->encode(eptxt, array);
1754  }
1755 
1756  void encodeUnitSelector(EncodedPtxt& eptxt, long i) const
1757  {
1758  rep->encodeUnitSelector(eptxt, i);
1759  }
1760 
1761  //================================
1762 
1763  void encodeUnitSelector(zzX& ptxt, long i) const
1764  {
1765  rep->encodeUnitSelector(ptxt, i);
1766  }
1767 
1768  template <typename PTXT, typename ARRAY>
1769  void decode(ARRAY& array, const PTXT& ptxt) const
1770  {
1771  rep->decode(array, ptxt);
1772  }
1773 
1774  template <typename T>
1775  void random(std::vector<T>& array) const
1776  {
1777  rep->random(array);
1778  }
1779 
1780  //========= new encryption interfaces
1781  // NOTE: I provide both a "legacy" interface that includes
1782  // Ctxt and PubKey, and a cleaner interface that includes
1783  // only Ctxt.
1784 
1785  // BGV only
1786  void encrypt(Ctxt& ctxt,
1787  const PubKey& key,
1788  const std::vector<NTL::ZZX>& array) const
1789  {
1790  EncodedPtxt eptxt;
1791  encode(eptxt, array);
1792  key.Encrypt(ctxt, eptxt);
1793  }
1794 
1795  void encrypt(Ctxt& ctxt, const std::vector<NTL::ZZX>& array) const
1796  {
1797  encrypt(ctxt, ctxt.getPubKey(), array);
1798  }
1799 
1800  void encrypt(Ctxt& ctxt,
1801  const PubKey& key,
1802  const std::vector<long>& array) const
1803  {
1804  EncodedPtxt eptxt;
1805  encode(eptxt, array);
1806  key.Encrypt(ctxt, eptxt);
1807  }
1808 
1809  void encrypt(Ctxt& ctxt, const std::vector<long>& array) const
1810  {
1811  encrypt(ctxt, ctxt.getPubKey(), array);
1812  }
1813 
1814  // CKKS only
1815  void encrypt(Ctxt& ctxt,
1816  const PubKey& key,
1817  const std::vector<cx_double>& array,
1818  double mag,
1819  OptLong prec = OptLong()) const
1820  {
1821  if (mag < 0)
1822  throw LogicError("CKKS encryption: mag must be set to non-default");
1823  EncodedPtxt eptxt;
1824  encode(eptxt, array, mag, prec);
1825  key.Encrypt(ctxt, eptxt);
1826  }
1827 
1828  void encrypt(Ctxt& ctxt,
1829  const std::vector<cx_double>& array,
1830  UNUSED double mag,
1831  OptLong prec = OptLong()) const
1832  {
1833  encrypt(ctxt, ctxt.getPubKey(), array, prec);
1834  }
1835 
1836  void encrypt(Ctxt& ctxt,
1837  const PubKey& key,
1838  const std::vector<double>& array,
1839  double mag,
1840  OptLong prec = OptLong()) const
1841  {
1842  if (mag < 0)
1843  throw LogicError("CKKS encryption: mag must be set to non-default");
1844  EncodedPtxt eptxt;
1845  encode(eptxt, array, mag, prec);
1846  key.Encrypt(ctxt, eptxt);
1847  }
1848 
1849  void encrypt(Ctxt& ctxt,
1850  const std::vector<double>& array,
1851  double mag,
1852  OptLong prec = OptLong()) const
1853  {
1854  encrypt(ctxt, ctxt.getPubKey(), array, mag, prec);
1855  }
1856 
1857  // BGV and CKKS
1858  void encrypt(Ctxt& ctxt,
1859  const PubKey& key,
1860  const PlaintextArray& array,
1861  double mag = -1,
1862  OptLong prec = OptLong()) const
1863  // NOTES: (1) for BGV, mag,prec must be defaulted;
1864  // (2) for CKKS, mag must be set to non-default value
1865  {
1866  if (getTag() == PA_cx_tag && mag < 0)
1867  throw LogicError("CKKS encryption: mag must be set to non-default");
1868  EncodedPtxt eptxt;
1869  encode(eptxt, array, mag, prec);
1870  key.Encrypt(ctxt, eptxt);
1871  }
1872 
1873  void encrypt(Ctxt& ctxt,
1874  const PlaintextArray& array,
1875  double mag = -1,
1876  OptLong prec = OptLong()) const
1877  {
1878  encrypt(ctxt, ctxt.getPubKey(), array, mag, prec);
1879  }
1880 
1881  //=========================
1882 
1883  template <typename T>
1884  void decrypt(const Ctxt& ctxt, const SecKey& sKey, T& ptxt) const
1885  {
1886  rep->decrypt(ctxt, sKey, ptxt);
1887  }
1888 
1889  template <typename T>
1890  void decrypt(const Ctxt& ctxt,
1891  const SecKey& sKey,
1892  T& ptxt,
1893  OptLong prec) const
1894  {
1895  rep->decrypt(ctxt, sKey, ptxt, prec);
1896  }
1897 
1898  template <typename T>
1899  void rawDecrypt(const Ctxt& ctxt, const SecKey& sKey, T& ptxt) const
1900  {
1901  rep->rawDecrypt(ctxt, sKey, ptxt);
1902  }
1903 
1904  void decryptComplex(const Ctxt& ctxt,
1905  const SecKey& sKey,
1906  PlaintextArray& ptxt,
1907  OptLong prec = OptLong()) const
1908  {
1909  rep->decryptComplex(ctxt, sKey, ptxt, prec);
1910  }
1911 
1912  void rawDecryptComplex(const Ctxt& ctxt,
1913  const SecKey& sKey,
1914  PlaintextArray& ptxt) const
1915  {
1916  rep->rawDecryptComplex(ctxt, sKey, ptxt);
1917  }
1918 
1919  void decryptReal(const Ctxt& ctxt,
1920  const SecKey& sKey,
1921  PlaintextArray& ptxt,
1922  OptLong prec = OptLong()) const
1923  {
1924  rep->decryptReal(ctxt, sKey, ptxt, prec);
1925  }
1926 
1927  void rawDecryptReal(const Ctxt& ctxt,
1928  const SecKey& sKey,
1929  PlaintextArray& ptxt) const
1930  {
1931  rep->rawDecryptReal(ctxt, sKey, ptxt);
1932  }
1933 
1934  void buildLinPolyCoeffs(std::vector<NTL::ZZX>& C,
1935  const std::vector<NTL::ZZX>& L) const
1936  {
1937  rep->buildLinPolyCoeffs(C, L);
1938  }
1939 
1940  void restoreContext() const { rep->restoreContext(); }
1941  void restoreContextForG() const { rep->restoreContextForG(); }
1942 
1943  long size() const { return rep->size(); }
1944  long dimension() const { return rep->dimension(); }
1945  long sizeOfDimension(long i) const { return rep->sizeOfDimension(i); }
1946  long nativeDimension(long i) const { return rep->nativeDimension(i); }
1947  long coordinate(long i, long k) const { return rep->coordinate(i, k); }
1948  long addCoord(long i, long k, long offset) const
1949  {
1950  return rep->addCoord(i, k, offset);
1951  }
1952 
1955  template <typename U>
1956  void rotate1D(std::vector<U>& out,
1957  const std::vector<U>& in,
1958  long i,
1959  long offset) const
1960  {
1961  rep->rotate1D(out, in, i, offset);
1962  }
1964 };
1965 
1966 // Convenience routines to avoid EncryptedArray's when
1967 // using the "default" one in Context
1968 
1969 inline void rotate(Ctxt& ctxt, long k)
1970 {
1971  ctxt.getContext().getView().rotate(ctxt, k);
1972 }
1973 
1974 inline void shift(Ctxt& ctxt, long k)
1975 {
1976  ctxt.getContext().getView().shift(ctxt, k);
1977 }
1978 
1979 inline void rotate1D(Ctxt& ctxt, long i, long k, bool dc = false)
1980 {
1981  ctxt.getContext().getView().rotate1D(ctxt, i, k, dc);
1982 }
1983 
1984 inline void shift1D(Ctxt& ctxt, long i, long k)
1985 {
1986  ctxt.getContext().getView().shift1D(ctxt, i, k);
1987 }
1988 
1989 // PlaintextArray
1990 
1992 { // purely abstract interface
1993 public:
1994  virtual ~PlaintextArrayBase() {}
1995  virtual void print(std::ostream& s) const = 0;
1996 };
1997 
1998 template <typename type>
2000 {
2001 public:
2002  PA_INJECT(type)
2003 
2004  std::vector<RX> data;
2005 
2006  virtual void print(std::ostream& s) const { s << data; }
2007 };
2008 
2016 {
2017 private:
2018  NTL::CloneablePtr<PlaintextArrayBase> rep;
2019 
2020  template <typename type>
2021  class ConstructorImpl
2022  {
2023  public:
2024  PA_INJECT(type)
2025 
2026  static void apply(const EncryptedArrayDerived<type>& ea, PlaintextArray& pa)
2027  {
2028  NTL::CloneablePtr<PlaintextArrayDerived<type>> ptr =
2029  NTL::MakeCloneable<PlaintextArrayDerived<type>>();
2030  ptr->data.resize(ea.size());
2031  pa.rep = ptr;
2032  }
2033  };
2034 
2035 public:
2037  {
2038  ea.dispatch<ConstructorImpl>(*this);
2039  }
2040 
2041  PlaintextArray(const PlaintextArray& other) : rep(other.rep.clone()) {}
2043  {
2044  rep = other.rep.clone();
2045  return *this;
2046  }
2047 
2048  template <typename type>
2049  std::vector<typename type::RX>& getData()
2050  {
2051  return (dynamic_cast<PlaintextArrayDerived<type>&>(*rep)).data;
2052  }
2053 
2054  template <typename type>
2055  const std::vector<typename type::RX>& getData() const
2056  {
2057  return (dynamic_cast<PlaintextArrayDerived<type>&>(*rep)).data;
2058  }
2059 
2060  void print(std::ostream& s) const { rep->print(s); }
2061 };
2062 
2063 inline std::ostream& operator<<(std::ostream& s, const PlaintextArray& pa)
2064 {
2065  pa.print(s);
2066  return s;
2067 }
2068 
2069 void rotate(const EncryptedArray& ea, PlaintextArray& pa, long k);
2070 void shift(const EncryptedArray& ea, PlaintextArray& pa, long k);
2071 
2072 void rotate1D(const EncryptedArray& ea, PlaintextArray& pa, long i, long k);
2073 void shift1D(const EncryptedArray& ea, PlaintextArray& pa, long i, long k);
2074 
2075 void encode(const EncryptedArray& ea,
2076  PlaintextArray& pa,
2077  const std::vector<long>& array);
2078 void encode(const EncryptedArray& ea,
2079  PlaintextArray& pa,
2080  const std::vector<NTL::ZZX>& array);
2081 void encode(const EncryptedArray& ea,
2082  PlaintextArray& pa,
2083  const std::vector<cx_double>& array);
2084 void encode(const EncryptedArray& ea,
2085  PlaintextArray& pa,
2086  const std::vector<double>& array);
2087 
2088 void encode(const EncryptedArray& ea, PlaintextArray& pa, long val);
2089 void encode(const EncryptedArray& ea, PlaintextArray& pa, const NTL::ZZX& val);
2090 void encode(const EncryptedArray& ea, PlaintextArray& pa, double val);
2091 void encode(const EncryptedArray& ea, PlaintextArray& pa, cx_double val);
2092 
2093 void decode(const EncryptedArray& ea,
2094  std::vector<long>& array,
2095  const PlaintextArray& pa);
2096 void decode(const EncryptedArray& ea,
2097  std::vector<NTL::ZZX>& array,
2098  const PlaintextArray& pa);
2099 void decode(const EncryptedArray& ea,
2100  std::vector<cx_double>& array,
2101  const PlaintextArray& pa);
2102 void decode(const EncryptedArray& ea,
2103  std::vector<double>& array,
2104  const PlaintextArray& pa);
2105 
2106 void random(const EncryptedArray& ea, PlaintextArray& pa);
2107 void randomReal(const EncryptedArray& ea, PlaintextArray& pa);
2108 void randomComplex(const EncryptedArray& ea, PlaintextArray& pa);
2109 
2110 bool equals(const EncryptedArray& ea,
2111  const PlaintextArray& pa,
2112  const PlaintextArray& other);
2113 bool equals(const EncryptedArray& ea,
2114  const PlaintextArray& pa,
2115  const std::vector<long>& other);
2116 bool equals(const EncryptedArray& ea,
2117  const PlaintextArray& pa,
2118  const std::vector<NTL::ZZX>& other);
2119 
2120 bool equals(const EncryptedArray& ea,
2121  const PlaintextArray& pa,
2122  const PlaintextArray& other,
2123  double tolerance,
2124  double floor);
2125 
2126 void add(const EncryptedArray& ea,
2127  PlaintextArray& pa,
2128  const PlaintextArray& other);
2129 void sub(const EncryptedArray& ea,
2130  PlaintextArray& pa,
2131  const PlaintextArray& other);
2132 void mul(const EncryptedArray& ea,
2133  PlaintextArray& pa,
2134  const PlaintextArray& other);
2135 void negate(const EncryptedArray& ea, PlaintextArray& pa);
2136 
2137 void frobeniusAutomorph(const EncryptedArray& ea, PlaintextArray& pa, long j);
2138 void frobeniusAutomorph(const EncryptedArray& ea,
2139  PlaintextArray& pa,
2140  const NTL::Vec<long>& vec);
2141 
2142 void extractRealPart(const EncryptedArray& ea, PlaintextArray& pa);
2143 void extractImPart(const EncryptedArray& ea, PlaintextArray& pa);
2144 
2145 void applyPerm(const EncryptedArray& ea,
2146  PlaintextArray& pa,
2147  const NTL::Vec<long>& pi);
2148 
2149 void power(const EncryptedArray& ea, PlaintextArray& pa, long e);
2150 
2151 double Norm(const EncryptedArray& ea, const PlaintextArray& pa);
2152 double Distance(const EncryptedArray& ea,
2153  const PlaintextArray& pa,
2154  const PlaintextArray& other);
2155 
2156 void totalSums(const EncryptedArray& ea, PlaintextArray& pa);
2157 void runningSums(const EncryptedArray& ea, PlaintextArray& pa);
2158 
2159 //=====================================
2160 
2161 // PtxtArray is a somewhat "friendlier" interface than
2162 // PlaintextArray, as it carries with it a reference to
2163 // an EncryptedArray. It is recommended that PlaintextArray
2164 // is deprecated in favor of PtxtArray.
2165 
2167 {
2168 public:
2173  static constexpr std::string_view typeName = "PtxtArray";
2174 
2175  // These two data fields should really be private, but there are
2176  // a lot of internal functions that need to access them
2179 
2180  explicit PtxtArray(const EncryptedArray& ea_) : ea(ea_), pa(ea) {}
2181 
2182  explicit PtxtArray(const Context& context) : ea(context.getView()), pa(ea) {}
2183 
2184  // copy constructor: default
2185  PtxtArray(const PtxtArray&) = default;
2186 
2187  // templates that allows construction via convert:
2188  // T can be any type supported by convert(PtxtArray,T)
2189  template <class T>
2190  PtxtArray(const EncryptedArray& ea, const T& t) : PtxtArray(ea)
2191  {
2192  load(t);
2193  }
2194 
2195  template <class T>
2196  PtxtArray(const Context& context, const T& t) : PtxtArray(context)
2197  {
2198  load(t);
2199  }
2200 
2202  {
2203  assertTrue(&ea == &other.ea, "PtxtArray: inconsistent assignment");
2204  pa = other.pa;
2205  return *this;
2206  }
2207 
2208  // template that allows assignment via convert:
2209  // T can be any type supported by PxtArray::load(T)
2210  template <class T>
2211  PtxtArray& operator=(const T& t)
2212  {
2213  load(t);
2214  return *this;
2215  }
2216 
2217  const EncryptedArray& getView() const { return ea; }
2218  const EncryptedArray& getEA() const { return ea; }
2219 
2220  long size() const { return ea.size(); }
2221 
2222  // direct encode, encrypt, and decrypt methods
2223  void encode(EncodedPtxt& eptxt,
2224  double mag = -1,
2225  OptLong prec = OptLong()) const
2226  {
2227  if (ea.isCKKS())
2228  ea.encode(eptxt, pa, mag, prec);
2229  else
2230  ea.encode(eptxt, pa); // ignore mag,prec for BGV
2231  }
2232 
2233  void encrypt(Ctxt& ctxt, double mag = -1, OptLong prec = OptLong()) const
2234  {
2235  if (ea.isCKKS()) {
2236  if (mag < 0)
2237  mag = NextPow2(Norm(pa.getData<PA_cx>()));
2238  // if mag is defaulted, set it to 2^(ceil(log2(max(Norm(pa),1))))
2239  ea.encrypt(ctxt, pa, mag, prec);
2240  } else {
2241  ea.encrypt(ctxt, pa); // ignore mag,prec for BGV
2242  }
2243  }
2244 
2245  void decrypt(const Ctxt& ctxt, const SecKey& sKey, OptLong prec = OptLong())
2246  {
2247  if (ea.isCKKS())
2248  ea.decrypt(ctxt, sKey, pa, prec);
2249  else
2250  ea.decrypt(ctxt, sKey, pa);
2251  }
2252 
2253  void rawDecrypt(const Ctxt& ctxt, const SecKey& sKey)
2254  {
2255  ea.rawDecrypt(ctxt, sKey, pa);
2256  }
2257 
2258  void decryptComplex(const Ctxt& ctxt,
2259  const SecKey& sKey,
2260  OptLong prec = OptLong())
2261  {
2262  ea.decryptComplex(ctxt, sKey, pa, prec);
2263  }
2264 
2265  void rawDecryptComplex(const Ctxt& ctxt, const SecKey& sKey)
2266  {
2267  ea.rawDecryptComplex(ctxt, sKey, pa);
2268  }
2269 
2270  void decryptReal(const Ctxt& ctxt,
2271  const SecKey& sKey,
2272  OptLong prec = OptLong())
2273  {
2274  ea.decryptReal(ctxt, sKey, pa, prec);
2275  }
2276 
2277  void rawDecryptReal(const Ctxt& ctxt, const SecKey& sKey)
2278  {
2279  ea.rawDecryptReal(ctxt, sKey, pa);
2280  }
2281 
2283 
2285 
2286  void random() { helib::random(ea, pa); }
2287 
2288  //======== load ========
2289  // Puts vector or scalar data into a PtxtArray
2290 
2291  void load(const std::vector<int>& array)
2292  {
2293  std::vector<long> array1;
2294  convert(array1, array);
2295  helib::encode(ea, pa, array1);
2296  }
2297 
2298  void load(const std::vector<long>& array) { helib::encode(ea, pa, array); }
2299 
2300  void load(const std::vector<NTL::ZZX>& array)
2301  {
2302  helib::encode(ea, pa, array);
2303  }
2304 
2305  void load(const std::vector<cx_double>& array)
2306  {
2307  helib::encode(ea, pa, array);
2308  }
2309 
2310  void load(const std::vector<double>& array) { helib::encode(ea, pa, array); }
2311 
2312  void load(int val) { helib::encode(ea, pa, long(val)); }
2313 
2314  void load(long val) { helib::encode(ea, pa, val); }
2315 
2316  void load(const NTL::ZZX& val) { helib::encode(ea, pa, val); }
2317 
2318  void load(double val) { helib::encode(ea, pa, val); }
2319 
2320  void load(cx_double val) { helib::encode(ea, pa, val); }
2321 
2322  // additional convenience conversions from NTL types (BGV only)
2323  // NTL vectors of NTL ring types
2324  // Implementation note: these all go via conversion to
2325  // std::vector<NTL::ZZX> to enforce BGV. This is not
2326  // the most efficient way to do this, and if it
2327  // becomes a bottleneck, we can revisit this implementation
2328  // (without changing semantics).
2329  void load(const NTL::Vec<NTL::GF2>& vec)
2330  {
2331  std::vector<NTL::ZZX> v;
2332  convert(v, vec);
2333  load(v);
2334  }
2335  void load(const NTL::Vec<NTL::GF2X>& vec)
2336  {
2337  std::vector<NTL::ZZX> v;
2338  convert(v, vec);
2339  load(v);
2340  }
2341  void load(const NTL::Vec<NTL::zz_p>& vec)
2342  {
2343  std::vector<NTL::ZZX> v;
2344  convert(v, vec);
2345  load(v);
2346  }
2347  void load(const NTL::Vec<NTL::zz_pX>& vec)
2348  {
2349  std::vector<NTL::ZZX> v;
2350  convert(v, vec);
2351  load(v);
2352  }
2353 
2354  // NTL scalar ring types
2355  // Implementation note: these all go via conversion to
2356  // NTL::ZZX to enforce BGV
2357  void load(NTL::GF2 scalar)
2358  {
2359  NTL::ZZX s;
2360  convert(s, scalar);
2361  load(s);
2362  }
2363  void load(const NTL::GF2X& scalar)
2364  {
2365  NTL::ZZX s;
2366  convert(s, scalar);
2367  load(s);
2368  }
2369  void load(NTL::zz_p scalar)
2370  {
2371  NTL::ZZX s;
2372  convert(s, scalar);
2373  load(s);
2374  }
2375  void load(const NTL::zz_pX& scalar)
2376  {
2377  NTL::ZZX s;
2378  convert(s, scalar);
2379  load(s);
2380  }
2381 
2382  //============== store ============
2383  // Puts data into a std::vector aka `unload`
2384 
2385  void store(std::vector<long>& array) const { decode(ea, array, pa); }
2386 
2387  void store(std::vector<NTL::ZZX>& array) const { decode(ea, array, pa); }
2388 
2389  void store(std::vector<cx_double>& array) const { decode(ea, array, pa); }
2390 
2391  void store(std::vector<double>& array) const { decode(ea, array, pa); }
2392 
2393  //===============================
2394 
2395  // this is here for consistency with Ctxt class
2396  void negate() { helib::negate(ea, pa); }
2397 
2398  void writeToJSON(std::ostream& os) const;
2399 
2400  JsonWrapper writeToJSON() const;
2401 
2402  static PtxtArray readFromJSON(std::istream& is, const Context& context);
2403 
2404  static PtxtArray readFromJSON(const JsonWrapper& jw, const Context& context);
2405 
2406  void readJSON(std::istream& is);
2407 
2408  void readJSON(const JsonWrapper& jw);
2409 
2410  friend std::istream& operator>>(std::istream& is, PtxtArray& pa);
2411 
2412  friend std::ostream& operator<<(std::ostream& os, const PtxtArray& pa);
2413 };
2414 
2415 inline void rotate(PtxtArray& a, long k) { rotate(a.ea, a.pa, k); }
2416 
2417 inline void shift(PtxtArray& a, long k) { shift(a.ea, a.pa, k); }
2418 
2419 inline void rotate1D(PtxtArray& a, long i, long k)
2420 {
2421  rotate1D(a.ea, a.pa, i, k);
2422 }
2423 
2424 inline void shift1D(PtxtArray& a, long i, long k) { shift1D(a.ea, a.pa, i, k); }
2425 
2426 inline bool operator==(const PtxtArray& a, const PtxtArray& b)
2427 {
2428  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2429  return equals(a.ea, a.pa, b.pa);
2430 }
2431 
2432 inline bool operator!=(const PtxtArray& a, const PtxtArray& b)
2433 {
2434  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2435  return !equals(a.ea, a.pa, b.pa);
2436 }
2437 
2439 {
2440  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2441  add(a.ea, a.pa, b.pa);
2442  return a;
2443 }
2444 
2445 template <class T>
2446 auto operator+=(PtxtArray& a, const T& b) -> decltype(a.load(b), a)
2447 // SFINAE: this allows operator+= to be more easily overloaded
2448 // PtxtArray& operator+=(PtxtArray& a, const T& b)
2449 {
2450  return a += PtxtArray(a.ea, b);
2451 }
2452 
2454 {
2455  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2456  sub(a.ea, a.pa, b.pa);
2457  return a;
2458 }
2459 
2460 template <class T>
2461 auto operator-=(PtxtArray& a, const T& b) -> decltype(a.load(b), a)
2462 // SFINAE: this allows operator-= to be more easily overloaded
2463 // PtxtArray& operator-=(PtxtArray& a, const T& b)
2464 {
2465  return a -= PtxtArray(a.ea, b);
2466 }
2467 
2469 {
2470  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2471  mul(a.ea, a.pa, b.pa);
2472  return a;
2473 }
2474 
2475 template <class T>
2476 auto operator*=(PtxtArray& a, const T& b) -> decltype(a.load(b), a)
2477 // SFINAE: this allows operator*= to be more easily overloaded
2478 // PtxtArray& operator*=(PtxtArray& a, const T& b)
2479 {
2480  return a *= PtxtArray(a.ea, b);
2481 }
2482 
2483 inline void frobeniusAutomorph(PtxtArray& a, long j)
2484 {
2485  frobeniusAutomorph(a.ea, a.pa, j);
2486 }
2487 
2488 inline void frobeniusAutomorph(PtxtArray& a, const NTL::Vec<long>& vec)
2489 {
2490  frobeniusAutomorph(a.ea, a.pa, vec);
2491 }
2492 
2493 inline void conjugate(PtxtArray& a) { frobeniusAutomorph(a, 1); }
2494 
2495 inline void extractRealPart(PtxtArray& a) { extractRealPart(a.ea, a.pa); }
2496 
2497 inline void extractImPart(PtxtArray& a) { extractImPart(a.ea, a.pa); }
2498 
2499 inline void applyPerm(PtxtArray& a, const NTL::Vec<long>& pi)
2500 {
2501  applyPerm(a.ea, a.pa, pi);
2502 }
2503 
2504 inline void power(PtxtArray& a, long e) { power(a.ea, a.pa, e); }
2505 
2506 // For CKKS, returns max norm of slots, for BGV the trivial norm
2507 // (i.e., 0 if zero, 1 otherwise)
2508 inline double Norm(const PtxtArray& a) { return Norm(a.ea, a.pa); }
2509 
2510 inline double Distance(const PtxtArray& a, const PtxtArray& b)
2511 {
2512  assertTrue(&a.ea == &b.ea, "PtxtArray: inconsistent operation");
2513  return Distance(a.ea, a.pa, b.pa);
2514 }
2515 
2516 inline void totalSums(PtxtArray& a) { totalSums(a.ea, a.pa); }
2517 inline void runningSums(PtxtArray& a) { runningSums(a.ea, a.pa); }
2518 
2519 //=====================================
2520 
2521 // Following are functions for performing "higher level"
2522 // operations on "encrypted arrays". There is really no
2523 // reason for these to be members of the EncryptedArray class,
2524 // so they are just declared as separate functions.
2525 
2528 void runningSums(const EncryptedArray& ea, Ctxt& ctxt);
2529 // The implementation uses O(log n) shift operations.
2530 
2531 inline void runningSums(Ctxt& ctxt)
2532 {
2533  runningSums(ctxt.getContext().getView(), ctxt);
2534 }
2535 
2538 void totalSums(const EncryptedArray& ea, Ctxt& ctxt);
2539 
2540 inline void totalSums(Ctxt& ctxt)
2541 {
2542  totalSums(ctxt.getContext().getView(), ctxt);
2543 }
2544 
2547 void mapTo01(const EncryptedArray& ea, Ctxt& ctxt);
2548 // Implemented in eqtesting.cpp. We compute
2549 // x^{p^d-1} = x^{(1+p+...+p^{d-1})*(p-1)}
2550 // by setting y=x^{p-1} and then outputting y * y^p * ... * y^{p^{d-1}},
2551 // with exponentiation to powers of p done via Frobenius.
2552 
2554 template <typename Scheme>
2555 void mapTo01(const EncryptedArray&, Ptxt<Scheme>& ptxt);
2556 
2561 void incrementalZeroTest(Ctxt* res[],
2562  const EncryptedArray& ea,
2563  const Ctxt& ctxt,
2564  long n);
2565 // Complexity: O(d + n log d) smart automorphisms
2566 // O(n d)
2567 
2568 /*************** End linear transformation functions ****************/
2569 /********************************************************************/
2570 
2572 
2588 // VJS-FIXME: we plan on re-implementing this logic in matmul.{h,cpp}.
2589 // The reasons are two-fold:
2590 // (1) the interfaces should look a lot more like the matmul interfaces,
2591 // instead of a completely different interface
2592 // (2) we want to exploit better algorithms, like BS/GS and hoisting,
2593 // which we don't do now.
2594 
2597 void applyLinPoly1(const EncryptedArray& ea,
2598  Ctxt& ctxt,
2599  const std::vector<NTL::ZZX>& C);
2600 
2604 void applyLinPolyMany(const EncryptedArray& ea,
2605  Ctxt& ctxt,
2606  const std::vector<std::vector<NTL::ZZX>>& Cvec);
2607 
2611 template <typename P> // P can be ZZX or DoubleCRT
2612 void applyLinPolyLL(Ctxt& ctxt, const std::vector<P>& encodedC, long d);
2614 
2615 // Helper class for unimplemented pa_impl classes
2616 
2617 template <typename type>
2618 struct pa_no_impl
2619 {
2620  template <typename... Args>
2621  static void apply(UNUSED Args&&... args)
2622  {
2623  throw helib::LogicError("function not implemented");
2624  }
2625 };
2626 
2627 #define HELIB_NO_CKKS_IMPL(impl) \
2628  template <> \
2629  class impl<PA_cx> : public pa_no_impl<PA_cx> \
2630  {};
2631 
2632 } // namespace helib
2633 
2634 #endif // ifndef HELIB_ENCRYPTEDARRAY_H
A smart pointer that clones the object it holds when it is copied.
Definition: ClonedPtr.h:101
const T * get() const
Get the pointer managed by ClonedPtr object.
Definition: ClonedPtr.h:235
Maintaining the HE scheme parameters.
Definition: Context.h:100
const EncryptedArray & getView() const
Getter method returning the default view object of the created context.
Definition: Context.h:416
long getPhiM() const
Getter method for the phi(m) of the created context.
Definition: Context.h:264
double noiseBoundForUniform(double magBound, long degBound) const
Definition: Context.h:474
A Ctxt object holds a single ciphertext.
Definition: Ctxt.h:396
const Context & getContext() const
Definition: Ctxt.h:1367
const PubKey & getPubKey() const
Definition: Ctxt.h:1368
long getPtxtSpace() const
Definition: Ctxt.h:1370
Implementing polynomials (elements in the ring R_Q) in double-CRT form.
Definition: DoubleCRT.h:76
Definition: EncodedPtxt.h:143
void resetBGV(const zzX &poly, long ptxtSpace, const Context &context)
Definition: EncodedPtxt.h:164
virtual class for data-movement operations on arrays of slots
Definition: EncryptedArray.h:120
virtual void decode(std::vector< NTL::ZZX > &array, const NTL::ZZX &ptxt) const =0
virtual void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< cx_double > &ptxt) const =0
virtual void decryptReal(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const =0
long coordinate(long i, long k) const
returns coordinate of index k along the i'th dimension
Definition: EncryptedArray.h:369
virtual void buildLinPolyCoeffs(std::vector< NTL::ZZX > &C, const std::vector< NTL::ZZX > &L) const =0
Linearized polynomials. L describes a linear map M by describing its action on the standard power bas...
virtual void shift1D(Ctxt &ctxt, long i, long k) const =0
Right shift k positions along the i'th dimension with zero fill.
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const =0
virtual double defaultScale(UNUSED double err, UNUSED OptLong prec=OptLong()) const
Definition: EncryptedArray.h:218
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< cx_double > &ptxt, OptLong prec=OptLong()) const =0
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< double > &ptxt, OptLong prec=OptLong()) const =0
bool nativeDimension(long i) const
Is rotations in given dimension a "native" operation?
Definition: EncryptedArray.h:366
virtual void restoreContext() const
Definition: EncryptedArray.h:351
virtual long getDegree() const =0
virtual void rotate1D(Ctxt &ctxt, long i, long k, bool dc=false) const =0
right-rotate k positions along the i'th dimension
virtual ~EncryptedArrayBase()
Definition: EncryptedArray.h:122
void decrypt1Slot(NTL::ZZX &slot, const Ctxt &ctxt, const SecKey &sKey, long i) const
Definition: EncryptedArray.h:326
virtual void encode(EncodedPtxt &eptxt, const std::vector< bool > &array) const =0
virtual void encode(EncodedPtxt &eptxt, const std::vector< cx_double > &array, double mag=-1, OptLong prec=OptLong()) const =0
virtual long getP2R() const =0
virtual void rawDecryptReal(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const =0
virtual void encode(NTL::ZZX &ptxt, const std::vector< NTL::ZZX > &array) const =0
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< long > &ptxt) const =0
virtual void random(std::vector< NTL::ZZX > &array) const =0
long dimension() const
Number of dimensions of hypercube.
Definition: EncryptedArray.h:360
virtual PA_tag getTag() const =0
virtual void encode(zzX &ptxt, const std::vector< zzX > &array) const =0
virtual void encode(EncodedPtxt &eptxt, const std::vector< NTL::ZZX > &array) const =0
long size() const
Total size (# of slots) of hypercube.
Definition: EncryptedArray.h:357
virtual void encode(NTL::ZZX &ptxt, const std::vector< long > &array) const =0
virtual void encode(EncodedPtxt &eptxt, const std::vector< long > &array) const =0
virtual void shift(Ctxt &ctxt, long k) const =0
Non-cyclic right shift with zero fill E.g., shifting ctxt=Enc(1 2 3 ... n) by k=1 gives Enc(0 1 2....
virtual void decode(PlaintextArray &array, const NTL::ZZX &ptxt) const =0
long sizeOfDimension(long i) const
Size of given dimension.
Definition: EncryptedArray.h:363
virtual void encode(zzX &ptxt, const PlaintextArray &array) const =0
virtual void encode(zzX &ptxt, const std::vector< long > &array) const =0
virtual const Context & getContext() const =0
virtual void encode(EncodedPtxt &eptxt, const std::vector< double > &array, double mag=-1, OptLong prec=OptLong()) const =0
virtual void decode(std::vector< long > &array, const NTL::ZZX &ptxt) const =0
virtual void rotate(Ctxt &ctxt, long k) const =0
Right rotation as a linear array. E.g., rotating ctxt=Enc(1 2 3 ... n) by k=1 gives Enc(n 1 2 ....
virtual void encodeUnitSelector(EncodedPtxt &eptxt, long i) const =0
long decode1Slot(const NTL::ZZX &ptxt, long i) const
Definition: EncryptedArray.h:245
long decrypt1Slot(const Ctxt &ctxt, const SecKey &sKey, long i) const
Definition: EncryptedArray.h:320
virtual void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< double > &ptxt) const =0
void decode1Slot(NTL::ZZX &slot, const NTL::ZZX &ptxt, long i) const
Definition: EncryptedArray.h:251
virtual void encode(zzX &ptxt, const std::vector< NTL::ZZX > &array) const =0
virtual void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const =0
virtual void rawDecryptComplex(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const =0
virtual void encode(EncodedPtxt &eptxt, const PlaintextArray &array, double mag=-1, OptLong prec=OptLong()) const =0
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< NTL::ZZX > &ptxt) const =0
virtual void restoreContextForG() const
Definition: EncryptedArray.h:352
virtual void encodeUnitSelector(zzX &ptxt, long i) const =0
Encodes a std::vector with 1 at position i and 0 everywhere else.
virtual const PAlgebra & getPAlgebra() const =0
virtual void decryptComplex(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const =0
virtual void random(std::vector< long > &array) const =0
void rotate1D(std::vector< U > &out, const std::vector< U > &in, long i, long offset) const
rotate an array by offset in the i'th dimension (output should not alias input)
Definition: EncryptedArray.h:383
virtual double defaultErr() const
Definition: EncryptedArray.h:224
long addCoord(long i, long k, long offset) const
adds offset to index k in the i'th dimension
Definition: EncryptedArray.h:375
virtual void encode(NTL::ZZX &ptxt, const PlaintextArray &array) const =0
virtual EncryptedArrayBase * clone() const =0
A different derived class to be used for the approximate-numbers scheme.
Definition: EncryptedArray.h:880
PA_tag getTag() const override
Definition: EncryptedArray.h:915
virtual void encode(EncodedPtxt &eptxt, const std::vector< bool > &array) const override
Definition: EncryptedArray.h:1216
void decode(std::vector< cx_double > &array, const NTL::ZZX &ptxt, double scaling) const
Definition: EncryptedArray.h:1355
void encode(UNUSED NTL::ZZX &ptxt, UNUSED const std::vector< NTL::ZZX > &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:989
void encodeUnitSelector(zzX &ptxt, long i) const override
Encodes a std::vector with 1 at position i and 0 everywhere else.
Definition: EncryptedArray.h:1278
virtual double defaultScale(double err, OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:1331
const Context & getContext() const override
Definition: EncryptedArray.h:916
void decrypt(const Ctxt &ctxt, const SecKey &sKey, Ptxt< Scheme > &ptxt, OptLong prec=OptLong()) const
Decrypt ciphertext to a plaintext relative to a specific scheme.
Definition: EncryptedArray.h:1466
void decode(UNUSED PlaintextArray &array, UNUSED const NTL::ZZX &ptxt) const override
Unimplemented decode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1041
void extractImPart(Ptxt< Scheme > &p) const
Extract the imaginary part of a CKKS plaintext.
Definition: EncryptedArray.h:1495
EncryptedArrayBase * clone() const override
Definition: EncryptedArray.h:909
void encode(UNUSED NTL::ZZX &ptxt, UNUSED const std::vector< long > &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:956
static double roundedSize(double x)
Definition: EncryptedArray.h:888
long getP2R() const override
Definition: EncryptedArray.h:925
void encode(UNUSED zzX &ptxt, UNUSED const std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:1006
void encode(UNUSED zzX &ptxt, UNUSED const std::vector< zzX > &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:967
double encode(NTL::ZZX &ptxt, const PTXT &pt, double useThisSize=-1, long precision=-1) const
Function for encoding a double into a zzX.
Definition: EncryptedArray.h:1169
virtual void encode(UNUSED EncodedPtxt &eptxt, UNUSED const std::vector< long > &array) const override
Definition: EncryptedArray.h:1188
virtual double defaultErr() const override
Definition: EncryptedArray.h:1315
virtual void encode(EncodedPtxt &eptxt, const std::vector< double > &array, double mag=-1, OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:1200
void decode(std::vector< double > &array, const NTL::ZZX &ptxt, double scaling) const
Definition: EncryptedArray.h:1371
void decrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< NTL::ZZX > &ptxt) const override
Unimplemented decrypt function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1079
double encodeRoundingError() const
Definition: EncryptedArray.h:1287
void encode(UNUSED zzX &ptxt, UNUSED const PlaintextArray &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:978
const PAlgebraModCx getTab() const
Definition: EncryptedArray.h:929
void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const override
Definition: EncryptedArray.h:1424
cx_double getG() const
Definition: EncryptedArray.h:928
virtual void encode(UNUSED EncodedPtxt &eptxt, UNUSED const std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:1182
void decrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< long > &ptxt) const override
Unimplemented decrypt function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1066
void random(std::vector< double > &array, double rad=1.0) const
Definition: EncryptedArray.h:1385
EncryptedArrayDerived(const Context &_context, const PAlgebraModCx &_alMod)
Definition: EncryptedArray.h:903
void buildLinPolyCoeffs(UNUSED std::vector< NTL::ZZX > &C, UNUSED const std::vector< NTL::ZZX > &L) const override
Unimplemented buildLinPolyCoeffs function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1093
long encodeScalingFactor(long precision=-1, double roundErr=-1.0) const
Definition: EncryptedArray.h:1299
long getDegree() const override
Definition: EncryptedArray.h:918
void decrypt(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:1416
void decode(UNUSED std::vector< NTL::ZZX > &array, UNUSED const NTL::ZZX &ptxt) const override
Unimplemented decode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1030
virtual void encodeUnitSelector(EncodedPtxt &eptxt, long i) const override
Definition: EncryptedArray.h:1224
double encode(zzX &ptxt, const std::vector< long > &array, double useThisSize, long precision=-1) const
Definition: EncryptedArray.h:1116
void encode(UNUSED zzX &ptxt, UNUSED const std::vector< long > &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:945
void encrypt(Ctxt &ctxt, const PubKey &key, const PTXT &ptxt) const
Definition: EncryptedArray.h:1270
void rotate1D(Ctxt &ctxt, long i, long k, bool dc=false) const override
right-rotate k positions along the i'th dimension
void extractRealPart(Ptxt< Scheme > &p) const
Extract the real part of a CKKS plaintext.
Definition: EncryptedArray.h:1484
const PAlgebra & getPAlgebra() const override
Definition: EncryptedArray.h:917
void decode(UNUSED std::vector< long > &array, UNUSED const NTL::ZZX &ptxt) const override
Unimplemented decode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1019
double encode(zzX &out, const Ptxt< Scheme > &ptxt, double useThisSize, long precision=-1) const
Encode a Ptxt object into a zzX.
Definition: EncryptedArray.h:1136
double encode(zzX &ptxt, const std::vector< double > &array, double useThisSize, long precision=-1) const
Definition: EncryptedArray.h:1107
void random(UNUSED std::vector< NTL::ZZX > &array) const override
Unimplemented random function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1053
void random(std::vector< long > &array) const override
Definition: EncryptedArray.h:1391
void encode(UNUSED NTL::ZZX &ptxt, UNUSED const PlaintextArray &array) const override
Unimplemented encode function for BGV. It will always throw helib::LogicError.
Definition: EncryptedArray.h:1000
void encrypt(Ctxt &ctxt, const PubKey &key, const PTXT &ptxt, double useThisSize, long precision=-1) const
Definition: EncryptedArray.h:1253
void dispatch(Args &&... args) const
Definition: EncryptedArray.h:932
void decode(std::vector< double > &array, const zzX &ptxt, double scaling) const
Definition: EncryptedArray.h:1364
void encryptOneNum(Ctxt &ctxt, const PubKey &key, double num, double useThisSize=-1, long precision=-1) const
Definition: EncryptedArray.h:1234
EncryptedArrayDerived(const Context &_context)
Definition: EncryptedArray.h:898
Derived concrete implementation of EncryptedArrayBase.
Definition: EncryptedArray.h:403
void rawDecrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< double > &ptxt) const override
Definition: EncryptedArray.h:555
virtual void encode(UNUSED EncodedPtxt &eptxt, UNUSED const std::vector< double > &array, UNUSED double mag=-1, UNUSED OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:662
void decrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< double > &ptxt, UNUSED OptLong prec=OptLong()) const override
Unimplemented decrypt function for CKKS. It will always throw helib::LogicError.
Definition: EncryptedArray.h:522
void dispatch(Args &&... args) const
Definition: EncryptedArray.h:455
void decryptReal(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED PlaintextArray &ptxt, UNUSED OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:584
virtual void random(std::vector< long > &array) const override
Definition: EncryptedArray.h:716
virtual long getDegree() const override
Definition: EncryptedArray.h:489
virtual void rotate(Ctxt &ctxt, long k) const override
Right rotation as a linear array. E.g., rotating ctxt=Enc(1 2 3 ... n) by k=1 gives Enc(n 1 2 ....
Definition: EncryptedArray.cpp:181
virtual PA_tag getTag() const override
Definition: EncryptedArray.h:451
void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< RX > &ptxt) const
Definition: EncryptedArray.h:797
virtual void encode(EncodedPtxt &eptxt, const std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:638
void rawDecrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED PlaintextArray &ptxt) const override
Definition: EncryptedArray.h:562
virtual void restoreContextForG() const override
Definition: EncryptedArray.h:479
const NTL::Mat< R > & getNormalBasisMatrixInverse() const
Definition: EncryptedArray.h:469
virtual void encode(zzX &ptxt, const std::vector< zzX > &array) const override
Definition: EncryptedArray.h:617
void decryptComplex(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED PlaintextArray &ptxt, UNUSED OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:569
void rotate1D(std::vector< U > &out, const std::vector< U > &in, long i, long offset) const
Definition: EncryptedArray.h:503
virtual void shift(Ctxt &ctxt, long k) const override
Non-cyclic right shift with zero fill E.g., shifting ctxt=Enc(1 2 3 ... n) by k=1 gives Enc(0 1 2....
Definition: EncryptedArray.cpp:288
const RX & getG() const
Definition: EncryptedArray.h:460
void rawDecryptComplex(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED PlaintextArray &ptxt) const override
Definition: EncryptedArray.h:577
void initNormalBasisMatrix() const
Definition: EncryptedArray.cpp:488
void rawDecryptReal(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED PlaintextArray &ptxt) const override
Definition: EncryptedArray.h:592
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< long > &ptxt) const override
Definition: EncryptedArray.h:727
const NTL::Mat< R > & getNormalBasisMatrix() const
Definition: EncryptedArray.h:462
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, std::vector< NTL::ZZX > &ptxt) const override
Definition: EncryptedArray.h:739
virtual void encode(zzX &ptxt, const std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:628
virtual void encodeUnitSelector(zzX &ptxt, long i) const override
Encodes a std::vector with 1 at position i and 0 everywhere else.
Definition: EncryptedArray.cpp:417
EncryptedArrayDerived(const Context &_context, const RX &_G, const PAlgebraMod &_tab)
Definition: EncryptedArray.cpp:57
long getP2R() const override
Definition: EncryptedArray.h:499
virtual void encode(zzX &ptxt, const std::vector< long > &array) const override
Definition: EncryptedArray.h:606
virtual void encode(NTL::ZZX &ptxt, const std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:611
virtual void restoreContext() const override
Definition: EncryptedArray.h:478
const PAlgebraModDerived< type > & getTab() const
Definition: EncryptedArray.h:490
virtual void decrypt(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:751
virtual void random(std::vector< NTL::ZZX > &array) const override
Definition: EncryptedArray.h:722
virtual void encode(EncodedPtxt &eptxt, const std::vector< long > &array) const override
Definition: EncryptedArray.h:646
virtual void encode(UNUSED EncodedPtxt &eptxt, UNUSED const std::vector< cx_double > &array, UNUSED double mag=-1, UNUSED OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:654
virtual void encodeUnitSelector(EncodedPtxt &eptxt, long i) const override
Definition: EncryptedArray.h:690
virtual void encode(EncodedPtxt &eptxt, const std::vector< bool > &array) const override
Definition: EncryptedArray.h:682
EncryptedArrayDerived(const EncryptedArrayDerived &other)
Definition: EncryptedArray.h:429
virtual void decode(std::vector< NTL::ZZX > &array, const NTL::ZZX &ptxt) const override
Definition: EncryptedArray.h:705
EncryptedArrayDerived & operator=(const EncryptedArrayDerived &)=delete
void decrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< cx_double > &ptxt, UNUSED OptLong prec=OptLong()) const override
Unimplemented decrypt function for CKKS. It will always throw helib::LogicError.
Definition: EncryptedArray.h:539
virtual void shift1D(Ctxt &ctxt, long i, long k) const override
Right shift k positions along the i'th dimension with zero fill.
Definition: EncryptedArray.cpp:130
virtual void rotate1D(Ctxt &ctxt, long i, long k, bool dc=false) const override
right-rotate k positions along the i'th dimension
Definition: EncryptedArray.cpp:67
virtual void buildLinPolyCoeffs(std::vector< NTL::ZZX > &C, const std::vector< NTL::ZZX > &L) const override
Linearized polynomials. L describes a linear map M by describing its action on the standard power bas...
Definition: EncryptedArray.cpp:746
virtual void encode(EncodedPtxt &eptxt, const PlaintextArray &array, double mag=-1, OptLong prec=OptLong()) const override
Definition: EncryptedArray.h:670
void random(std::vector< RX > &array) const
Definition: EncryptedArray.h:790
virtual EncryptedArrayBase * clone() const override
Definition: EncryptedArray.h:446
virtual const Context & getContext() const override
Definition: EncryptedArray.h:484
virtual const PAlgebra & getPAlgebra() const override
Definition: EncryptedArray.h:485
void rawDecrypt(UNUSED const Ctxt &ctxt, UNUSED const SecKey &sKey, UNUSED std::vector< cx_double > &ptxt) const override
Definition: EncryptedArray.h:548
virtual void decode(std::vector< long > &array, const NTL::ZZX &ptxt) const override
Definition: EncryptedArray.h:699
virtual void encode(NTL::ZZX &ptxt, const std::vector< long > &array) const override
Definition: EncryptedArray.h:600
A simple wrapper for a smart pointer to an EncryptedArrayBase. This is the interface that higher-leve...
Definition: EncryptedArray.h:1583
void rotate(Ctxt &ctxt, long k) const
Definition: EncryptedArray.h:1672
EncryptedArray(const Context &context, const PAlgebraMod &_alMod)
constructor: G defaults to F0, PAlgebraMod explicitly given
Definition: EncryptedArray.h:1595
void encode(zzX &ptxt, const std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:1710
const EncryptedArrayCx & getCx() const
Definition: EncryptedArray.h:1630
void encode(NTL::ZZX &ptxt, const PlaintextArray &array) const
Definition: EncryptedArray.h:1705
void encodeUnitSelector(zzX &ptxt, long i) const
Definition: EncryptedArray.h:1763
void encode(EncodedPtxt &eptxt, const PlaintextArray &array, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1743
bool isCKKS() const
Definition: EncryptedArray.h:1639
long sizeOfDimension(long i) const
Definition: EncryptedArray.h:1945
PA_tag getTag() const
Definition: EncryptedArray.h:1638
void encrypt(Ctxt &ctxt, const PubKey &key, const std::vector< long > &array) const
Definition: EncryptedArray.h:1800
void decryptReal(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1919
void encrypt(Ctxt &ctxt, const std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:1795
void encrypt(Ctxt &ctxt, const PlaintextArray &array, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1873
void restoreContextForG() const
Definition: EncryptedArray.h:1941
void rotate1D(std::vector< U > &out, const std::vector< U > &in, long i, long offset) const
rotate an array by offset in the i'th dimension (output should not alias input)
Definition: EncryptedArray.h:1956
EncryptedArray(const Context &context, const NTL::ZZX &G=NTL::ZZX(1, 1))
constructor: G defaults to the monomial X, PAlgebraMod from context
Definition: EncryptedArray.h:1590
void encode(zzX &ptxt, const PlaintextArray &array) const
Definition: EncryptedArray.h:1695
void rawDecryptReal(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const
Definition: EncryptedArray.h:1927
void encrypt(Ctxt &ctxt, const std::vector< cx_double > &array, UNUSED double mag, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1828
EncryptedArray & operator=(const EncryptedArray &other)=delete
void decryptComplex(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1904
void encode(zzX &ptxt, const std::vector< long > &array) const
Definition: EncryptedArray.h:1680
void encode(EncodedPtxt &eptxt, const std::vector< bool > &array) const
Definition: EncryptedArray.h:1751
void random(std::vector< T > &array) const
Definition: EncryptedArray.h:1775
void encode(NTL::ZZX &ptxt, const std::vector< long > &array) const
Definition: EncryptedArray.h:1685
long addCoord(long i, long k, long offset) const
Definition: EncryptedArray.h:1948
void encode(EncodedPtxt &eptxt, const std::vector< long > &array) const
Definition: EncryptedArray.h:1722
void encrypt(Ctxt &ctxt, const PubKey &key, const std::vector< cx_double > &array, double mag, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1815
void decode(ARRAY &array, const PTXT &ptxt) const
Definition: EncryptedArray.h:1769
void buildLinPolyCoeffs(std::vector< NTL::ZZX > &C, const std::vector< NTL::ZZX > &L) const
Definition: EncryptedArray.h:1934
void encode(EncodedPtxt &eptxt, const std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:1717
long size() const
Definition: EncryptedArray.h:1943
void decrypt(const Ctxt &ctxt, const SecKey &sKey, T &ptxt) const
Definition: EncryptedArray.h:1884
void shift(Ctxt &ctxt, long k) const
Definition: EncryptedArray.h:1673
void encode(EncodedPtxt &eptxt, const std::vector< cx_double > &array, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1727
const EncryptedArrayDerived< type > & getDerived(type) const
downcast operator example: const EncryptedArrayDerived<PA_GF2>& rep = ea.getDerived(PA_GF2());
Definition: EncryptedArray.h:1625
void rawDecryptComplex(const Ctxt &ctxt, const SecKey &sKey, PlaintextArray &ptxt) const
Definition: EncryptedArray.h:1912
const PAlgebra & getPAlgebra() const
Definition: EncryptedArray.h:1670
long coordinate(long i, long k) const
Definition: EncryptedArray.h:1947
void encrypt(Ctxt &ctxt, const PubKey &key, const PlaintextArray &array, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1858
void encrypt(Ctxt &ctxt, const std::vector< long > &array) const
Definition: EncryptedArray.h:1809
void dispatch(Args &&... args) const
Definition: EncryptedArray.h:1642
void encrypt(Ctxt &ctxt, const std::vector< double > &array, double mag, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1849
void restoreContext() const
Definition: EncryptedArray.h:1940
void encrypt(Ctxt &ctxt, const PubKey &key, const std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:1786
void encode(EncodedPtxt &eptxt, const std::vector< double > &array, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1735
void shift1D(Ctxt &ctxt, long i, long k) const
Definition: EncryptedArray.h:1678
long getDegree() const
Definition: EncryptedArray.h:1671
void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey, T &ptxt) const
Definition: EncryptedArray.h:1899
const PAlgebraMod & getAlMod() const
Definition: EncryptedArray.h:1669
const Context & getContext() const
Definition: EncryptedArray.h:1668
long dimension() const
Definition: EncryptedArray.h:1944
void decrypt(const Ctxt &ctxt, const SecKey &sKey, T &ptxt, OptLong prec) const
Definition: EncryptedArray.h:1890
void rotate1D(Ctxt &ctxt, long i, long k, bool dc=false) const
Definition: EncryptedArray.h:1674
void encode(NTL::ZZX &ptxt, const std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:1700
void encode(zzX &ptxt, const std::vector< zzX > &array) const
Definition: EncryptedArray.h:1690
void encrypt(Ctxt &ctxt, const PubKey &key, const std::vector< double > &array, double mag, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:1836
long nativeDimension(long i) const
Definition: EncryptedArray.h:1946
void encodeUnitSelector(EncodedPtxt &eptxt, long i) const
Definition: EncryptedArray.h:1756
Inherits from Exception and std::logic_error.
Definition: exceptions.h:68
Auxiliary structure to support encoding/decoding slots.
Definition: PAlgebra.h:508
void restoreContextForG() const
Definition: PAlgebra.h:530
const RX & getG() const
Definition: PAlgebra.h:528
long getDegG() const
Definition: PAlgebra.h:529
Represents the set of long int's plus a distinguished value that can be used to denote "undefined"....
Definition: NumbTh.h:998
The structure of (Z/mZ)* /(p)
Definition: PAlgebra.h:77
long genToPow(long i, long j) const
the i'th generator to the power j mod m
Definition: PAlgebra.cpp:606
bool SameOrd(long i) const
Is ord(i'th generator) the same as its order in (Z/mZ)^*?
Definition: PAlgebra.h:224
long getNSlots() const
The number of plaintext slots = phi(m)/ord(p)
Definition: PAlgebra.h:188
long numOfGens() const
The prime-power factorization of m.
Definition: PAlgebra.h:203
long getM() const
Returns m.
Definition: PAlgebra.h:164
long OrderOf(long i) const
The order of i'th generator (if any)
Definition: PAlgebra.h:218
long addCoord(long i, long k, long offset) const
adds offset to index k in the i'th dimension
Definition: PAlgebra.h:274
long coordinate(long i, long k) const
Returns coordinate of index k along the i'th dimension.
Definition: PAlgebra.h:258
Definition: PAlgebra.h:770
const PAlgebra & getZMStar() const override
Returns reference to underlying PAlgebra object.
Definition: PAlgebra.h:789
long getR() const override
The value r.
Definition: PAlgebra.h:790
long getPPowR() const override
The value p^r.
Definition: PAlgebra.h:791
A concrete instantiation of the virtual class.
Definition: PAlgebra.h:568
virtual void restoreContext() const override
Restores the NTL context for p^r.
Definition: PAlgebra.h:637
virtual const PAlgebra & getZMStar() const override
Returns reference to underlying PAlgebra object.
Definition: PAlgebra.h:622
The structure of Z[X]/(Phi_m(X), p)
Definition: PAlgebra.h:816
Definition: EncryptedArray.h:1992
virtual void print(std::ostream &s) const =0
virtual ~PlaintextArrayBase()
Definition: EncryptedArray.h:1994
Definition: EncryptedArray.h:2000
virtual void print(std::ostream &s) const
Definition: EncryptedArray.h:2006
std::vector< RX > data
Definition: EncryptedArray.h:2004
Definition: EncryptedArray.h:2016
PlaintextArray(const PlaintextArray &other)
Definition: EncryptedArray.h:2041
const std::vector< typename type::RX > & getData() const
Definition: EncryptedArray.h:2055
PlaintextArray & operator=(const PlaintextArray &other)
Definition: EncryptedArray.h:2042
void print(std::ostream &s) const
Definition: EncryptedArray.h:2060
std::vector< typename type::RX > & getData()
Definition: EncryptedArray.h:2049
PlaintextArray(const EncryptedArray &ea)
Definition: EncryptedArray.h:2036
Definition: EncryptedArray.h:2167
void load(const NTL::Vec< NTL::zz_pX > &vec)
Definition: EncryptedArray.h:2347
PtxtArray & operator=(const T &t)
Definition: EncryptedArray.h:2211
void load(double val)
Definition: EncryptedArray.h:2318
long size() const
Definition: EncryptedArray.h:2220
void encrypt(Ctxt &ctxt, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:2233
void rawDecrypt(const Ctxt &ctxt, const SecKey &sKey)
Definition: EncryptedArray.h:2253
PtxtArray(const PtxtArray &)=default
void load(const NTL::ZZX &val)
Definition: EncryptedArray.h:2316
void load(NTL::zz_p scalar)
Definition: EncryptedArray.h:2369
const EncryptedArray & getEA() const
Definition: EncryptedArray.h:2218
void rawDecryptReal(const Ctxt &ctxt, const SecKey &sKey)
Definition: EncryptedArray.h:2277
void load(NTL::GF2 scalar)
Definition: EncryptedArray.h:2357
void load(int val)
Definition: EncryptedArray.h:2312
void negate()
Definition: EncryptedArray.h:2396
void load(const NTL::zz_pX &scalar)
Definition: EncryptedArray.h:2375
void store(std::vector< long > &array) const
Definition: EncryptedArray.h:2385
void store(std::vector< NTL::ZZX > &array) const
Definition: EncryptedArray.h:2387
PlaintextArray pa
Definition: EncryptedArray.h:2178
PtxtArray(const EncryptedArray &ea, const T &t)
Definition: EncryptedArray.h:2190
void rawDecryptComplex(const Ctxt &ctxt, const SecKey &sKey)
Definition: EncryptedArray.h:2265
void store(std::vector< double > &array) const
Definition: EncryptedArray.h:2391
void load(const NTL::Vec< NTL::GF2 > &vec)
Definition: EncryptedArray.h:2329
const EncryptedArray & getView() const
Definition: EncryptedArray.h:2217
void decrypt(const Ctxt &ctxt, const SecKey &sKey, OptLong prec=OptLong())
Definition: EncryptedArray.h:2245
void store(std::vector< cx_double > &array) const
Definition: EncryptedArray.h:2389
void load(const std::vector< cx_double > &array)
Definition: EncryptedArray.h:2305
void load(const std::vector< NTL::ZZX > &array)
Definition: EncryptedArray.h:2300
static constexpr std::string_view typeName
Class label to be added to JSON serialization as object type information.
Definition: EncryptedArray.h:2173
PtxtArray(const Context &context)
Definition: EncryptedArray.h:2182
void load(const NTL::GF2X &scalar)
Definition: EncryptedArray.h:2363
void load(const std::vector< int > &array)
Definition: EncryptedArray.h:2291
void readJSON(std::istream &is)
Definition: EncryptedArray.cpp:609
PtxtArray(const EncryptedArray &ea_)
Definition: EncryptedArray.h:2180
void encode(EncodedPtxt &eptxt, double mag=-1, OptLong prec=OptLong()) const
Definition: EncryptedArray.h:2223
JsonWrapper writeToJSON() const
Definition: EncryptedArray.cpp:559
PtxtArray & operator=(const PtxtArray &other)
Definition: EncryptedArray.h:2201
void random()
Definition: EncryptedArray.h:2286
void decryptComplex(const Ctxt &ctxt, const SecKey &sKey, OptLong prec=OptLong())
Definition: EncryptedArray.h:2258
const EncryptedArray & ea
Definition: EncryptedArray.h:2177
friend std::istream & operator>>(std::istream &is, PtxtArray &pa)
Definition: EncryptedArray.cpp:681
friend std::ostream & operator<<(std::ostream &os, const PtxtArray &pa)
Definition: EncryptedArray.cpp:687
void load(long val)
Definition: EncryptedArray.h:2314
void randomComplex()
Definition: EncryptedArray.h:2284
void load(const NTL::Vec< NTL::zz_p > &vec)
Definition: EncryptedArray.h:2341
void load(cx_double val)
Definition: EncryptedArray.h:2320
void randomReal()
Definition: EncryptedArray.h:2282
PtxtArray(const Context &context, const T &t)
Definition: EncryptedArray.h:2196
void load(const std::vector< double > &array)
Definition: EncryptedArray.h:2310
void load(const std::vector< long > &array)
Definition: EncryptedArray.h:2298
static PtxtArray readFromJSON(std::istream &is, const Context &context)
Definition: EncryptedArray.cpp:594
void decryptReal(const Ctxt &ctxt, const SecKey &sKey, OptLong prec=OptLong())
Definition: EncryptedArray.h:2270
void load(const NTL::Vec< NTL::GF2X > &vec)
Definition: EncryptedArray.h:2335
An object that mimics the functionality of the Ctxt object, and acts as a convenient entry point for ...
Definition: Ptxt.h:188
const std::vector< SlotType > & getSlotRepr() const
Get the data held in the slots as a std::vector<SlotType>.
Definition: Ptxt.cpp:190
Ptxt< Scheme > imag() const
Extract the imaginary part of a CKKS plaintext.
void setData(const std::vector< SlotType > &data)
Set the data.
Definition: Ptxt.cpp:107
Ptxt< Scheme > real() const
Extract the real part of a CKKS plaintext.
The public key.
Definition: keys.h:45
long Encrypt(Ctxt &ciphertxt, const NTL::ZZX &plaintxt, long ptxtSpace, bool highNoise) const
Definition: keys.cpp:351
void CKKSencrypt(Ctxt &ciphertxt, const NTL::ZZX &plaintxt, double ptxtSize=1.0, double scaling=0.0) const
Definition: keys.cpp:494
Inherits from Exception and std::runtime_error.
Definition: exceptions.h:105
The secret key.
Definition: keys.h:311
Definition: apiAttributes.h:21
void mul(const EncryptedArray &ea, PlaintextArray &pa, const PlaintextArray &other)
Definition: EncryptedArray.cpp:1612
double NextPow2(double x)
Compute next power of two in floating point NextPow2(x) returns 1 if x < 1, and otherwise returns 2^(...
Definition: NumbTh.cpp:1803
void applyLinPolyLL(Ctxt &ctxt, const std::vector< P > &encodedC, long d)
Definition: EncryptedArray.cpp:855
void shift(Ctxt &ctxt, long k)
Definition: EncryptedArray.h:1974
void sub(const EncryptedArray &ea, PlaintextArray &pa, const PlaintextArray &other)
Definition: EncryptedArray.cpp:1565
void project_and_round(std::vector< long > &out, const std::vector< std::complex< double >> &in)
Definition: NumbTh.h:484
void random(const EncryptedArray &ea, PlaintextArray &pa)
Definition: EncryptedArray.cpp:1256
void add(const EncryptedArray &ea, PlaintextArray &pa, const PlaintextArray &other)
Definition: EncryptedArray.cpp:1537
void mapTo01(const EncryptedArray &ea, Ctxt &ctxt)
Definition: eqtesting.cpp:35
NTL::Vec< long > zzX
Definition: zzX.h:24
void totalSums(const EncryptedArray &ea, PlaintextArray &pa)
Definition: EncryptedArray.cpp:1974
void extractImPart(Ctxt &c)
Definition: Ctxt.cpp:3100
void applyLinPoly1(const EncryptedArray &ea, Ctxt &ctxt, const std::vector< NTL::ZZX > &C)
Definition: EncryptedArray.cpp:802
void extractRealPart(Ctxt &c)
Definition: Ctxt.cpp:3092
general_range< long > range(long n)
Definition: range.h:57
PtxtArray & operator-=(PtxtArray &a, const PtxtArray &b)
Definition: EncryptedArray.h:2453
void Warning(const char *msg)
Function for logging a warning message.
Definition: log.h:114
void negate(Ctxt &ctxt)
negate: free function version of negate method
Definition: Ctxt.h:1551
std::complex< double > cx_double
Definition: EncryptedArray.h:34
void conjugate(Ctxt &ctxt)
conjugate: free function that is equivalent to frobeniusAutomorph(ctxt, 1)
Definition: Ctxt.h:1539
void decode(const EncryptedArray &ea, std::vector< long > &array, const PlaintextArray &pa)
Definition: EncryptedArray.cpp:1382
void convert(long &x1, const NTL::GF2X &x2)
Definition: NumbTh.h:368
bool operator==(const PtxtArray &a, const PtxtArray &b)
Definition: EncryptedArray.h:2426
bool equals(const EncryptedArray &ea, const PlaintextArray &pa, const PlaintextArray &other)
Definition: EncryptedArray.cpp:1489
EncryptedArrayDerived< PA_cx > EncryptedArrayCx
Definition: EncryptedArray.h:1530
void applyLinPolyMany(const EncryptedArray &ea, Ctxt &ctxt, const std::vector< std::vector< NTL::ZZX >> &Cvec)
Definition: EncryptedArray.cpp:826
double Distance(const EncryptedArray &ea, const PlaintextArray &pa, const PlaintextArray &other)
Definition: EncryptedArray.cpp:1943
void rotate1D(Ctxt &ctxt, long i, long k, bool dc=false)
Definition: EncryptedArray.h:1979
PA_tag
Definition: PAlgebra.h:299
@ PA_zz_p_tag
Definition: PAlgebra.h:301
@ PA_cx_tag
Definition: PAlgebra.h:302
@ PA_GF2_tag
Definition: PAlgebra.h:300
void randomComplex(const EncryptedArray &ea, PlaintextArray &pa)
Definition: EncryptedArray.cpp:1295
void incrementalZeroTest(Ctxt *res[], const EncryptedArray &ea, const Ctxt &ctxt, long n)
Definition: eqtesting.cpp:95
void rotate(Ctxt &ctxt, long k)
Definition: EncryptedArray.h:1969
void assertTrue(const T &value, const std::string &message)
Definition: assertions.h:61
void frobeniusAutomorph(Ctxt &ctxt, long j)
frobeniusAutomorph: free function version of frobeniusAutomorph method
Definition: Ctxt.h:1533
std::ostream & operator<<(std::ostream &os, const ContextBuilder< SCHEME > &cb)
ostream operator for serializing the ContextBuilder object.
void encode(const EncryptedArray &ea, PlaintextArray &pa, const std::vector< long > &array)
Definition: EncryptedArray.cpp:1116
EncryptedArrayBase * buildEncryptedArray(const Context &context, const PAlgebraMod &alMod, const NTL::ZZX &G=NTL::ZZX::zero())
A "factory" for building EncryptedArrays.
Definition: EncryptedArray.cpp:26
PtxtArray & operator+=(PtxtArray &a, const PtxtArray &b)
Definition: EncryptedArray.h:2438
void randomReal(const EncryptedArray &ea, PlaintextArray &pa)
Definition: EncryptedArray.cpp:1218
void power(Ctxt &ctxt, long e)
power: free function version of power method
Definition: Ctxt.h:1548
void clear(zzX &a)
Definition: zzX.h:28
void applyPerm(const EncryptedArray &ea, PlaintextArray &pa, const NTL::Vec< long > &pi)
Definition: EncryptedArray.cpp:1838
EncryptedArray View
Definition: EncryptedArray.h:79
long lsize(const std::vector< T > &v)
Size of STL vector as a long (rather than unsigned long)
Definition: NumbTh.h:701
void PolyRed(NTL::ZZX &out, const NTL::ZZX &in, long q, bool abs=false)
Reduce all the coefficients of a polynomial modulo q.
Definition: NumbTh.cpp:772
void assertEq(const T &a, const T &b, const std::string &message)
Definition: assertions.h:108
void plaintextAutomorph(RX &bb, const RX &a, long k, long m, const RXModulus &PhimX)
Definition: EncryptedArray.h:1534
void project(std::vector< double > &out, const std::vector< std::complex< double >> &in)
Definition: NumbTh.h:475
void rem(NTL::zz_pX &r, const NTL::zz_pX &a, const zz_pXModulus1 &ff)
Definition: NumbTh.cpp:1764
PtxtArray & operator*=(PtxtArray &a, const PtxtArray &b)
Definition: EncryptedArray.h:2468
bool operator!=(const PtxtArray &a, const PtxtArray &b)
Definition: EncryptedArray.h:2432
double Norm(const EncryptedArray &ea, const PlaintextArray &pa)
Definition: EncryptedArray.cpp:1936
void shift1D(Ctxt &ctxt, long i, long k)
Definition: EncryptedArray.h:1984
void runningSums(const EncryptedArray &ea, PlaintextArray &pa)
Definition: EncryptedArray.cpp:1996
Definition: io.h:50
Definition: JsonWrapper.h:9