PAlgebra.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_PALGEBRA_H
13 #define HELIB_PALGEBRA_H
18 #include <exception>
19 #include <utility>
20 #include <vector>
21 #include <complex>
22 
23 #include <helib/NumbTh.h>
24 #include <helib/zzX.h>
25 #include <helib/hypercube.h>
26 #include <helib/PGFFT.h>
27 #include <helib/ClonedPtr.h>
28 #include <helib/apiAttributes.h>
29 
30 namespace helib {
31 
32 struct half_FFT
33 {
35  std::vector<std::complex<double>> pow;
36 
37  half_FFT(long m);
38 };
39 
41 {
43  std::vector<std::complex<double>> pow1, pow2;
44 
45  quarter_FFT(long m);
46 };
47 
76 class PAlgebra
77 {
78  long m; // the integer m defines (Z/mZ)^*, Phi_m(X), etc.
79  long p; // the prime base of the plaintext space
80 
81  long phiM; // phi(m)
82  long ordP; // the order of p in (Z/mZ)^*
83  long nfactors; // number of distinct prime factors of m
84  long radm; // rad(m) = prod of distinct primes dividing m
85  double normBnd; // max-norm-on-pwfl-basis <= normBnd * max-norm-canon-embed
86  double polyNormBnd; // max-norm-on-poly-basis <= polyNormBnd *
87  // max-norm-canon-embed
88 
89  long pow2; // if m = 2^k, then pow2 == k; otherwise, pow2 == 0
90 
91  std::vector<long> gens; // Our generators for (Z/mZ)^* (other than p)
92 
93  // native[i] is true iff gens[i] has the same order in the quotient
94  // group as its order in Zm*.
95  NTL::Vec<bool> native;
96 
97  // frob_perturb[i] = j if gens[i] raised to its order equals p^j,
98  // otherwise -1
99  NTL::Vec<long> frob_perturb;
100 
101  CubeSignature cube; // the hypercube structure of Zm* /(p)
102 
103  NTL::ZZX PhimX; // Holds the integer polynomial Phi_m(X)
104 
105  double cM; // the "ring constant" c_m for Z[X]/Phi_m(X)
106  // NOTE: cM is related to the ratio between the l_infinity norm of
107  // a "random" ring element in different bases. For example, think of
108  // choosing the power-basis coefficients of x uniformly at random in
109  // [+-a/2] (for some parameter a), then the powerful basis norm of x
110  // should be bounded whp by cM*a.
111  //
112  // More precisely, for an element x whose coefficients are chosen
113  // uniformly in [+-a/2] (in either the powerful or the power basis)
114  // we have a high-probability bound |x|_canonical < A*a for some
115  // A = O(sqrt(phi(m)). Also for "random enough" x we have some bound
116  // |x|_powerful < |x|_canonical * B
117  // where we "hope" that B = O(1/sqrt(phi(m)). The cM value is
118  // supposed to be cM=A*B.
119  //
120  // The value cM is only used for bootstrapping, see more comments
121  // for the method RecryptData::setAE in recryption.cpp. Also see
122  // Appendix A of https://ia.cr/2014/873 (updated version from 2019)
123 
124  std::vector<long> T; // The representatives for the quotient group Zm* /(p)
125  std::vector<long> Tidx; // i=Tidx[t] is the index i s.t. T[i]=t.
126  // Tidx[t]==-1 if t notin T
127 
128  std::vector<long> zmsIdx; // if t is the i'th element in Zm* then zmsIdx[t]=i
129  // zmsIdx[t]==-1 if t notin Zm*
130 
131  std::vector<long> zmsRep; // inverse of zmsIdx
132 
133  std::shared_ptr<PGFFT> fftInfo; // info for computing m-point complex FFT's
134  // shard_ptr allows delayed initialization
135  // and lightweight copying
136 
137  std::shared_ptr<half_FFT> half_fftInfo;
138  // an optimization for FFT's with even m
139 
140  std::shared_ptr<quarter_FFT> quarter_fftInfo;
141  // an optimization for FFT's with m = 0 (mod 4)
142 
143 public:
144  PAlgebra& operator=(const PAlgebra&) = delete;
145 
146  PAlgebra(long mm,
147  long pp = 2,
148  const std::vector<long>& _gens = std::vector<long>(),
149  const std::vector<long>& _ords = std::vector<long>()); // constructor
150 
151  bool operator==(const PAlgebra& other) const;
152  bool operator!=(const PAlgebra& other) const { return !(*this == other); }
153  // comparison
154 
155  /* I/O methods */
156 
158  void printout(std::ostream& out = std::cout) const;
159  void printAll(std::ostream& out = std::cout) const; // print even more
160 
161  /* Access methods */
162 
164  long getM() const { return m; }
165 
167  long getP() const { return p; }
168 
170  long getPhiM() const { return phiM; }
171 
173  long getOrdP() const { return ordP; }
174 
176  long getNFactors() const { return nfactors; }
177 
179  long getRadM() const { return radm; }
180 
182  double getNormBnd() const { return normBnd; }
183 
185  double getPolyNormBnd() const { return polyNormBnd; }
186 
188  long getNSlots() const { return cube.getSize(); }
189 
191  long getPow2() const { return pow2; }
192 
194  const NTL::ZZX& getPhimX() const { return PhimX; }
195 
197  double get_cM() const { return cM; }
198 
200  // const std::vector<long> getMfactors() const { return mFactors; }
201 
203  long numOfGens() const { return gens.size(); }
204 
206  long ZmStarGen(long i) const { return (i < long(gens.size())) ? gens[i] : 0; }
207 
209  // VJS: I'm moving away from all of this unsigned stuff...
210  // Also, note that j really may be negative
211  // NOTE: i == -1 means Frobenius
212  long genToPow(long i, long j) const;
213 
214  // p to the power j mod m
215  long frobeniusPow(long j) const;
216 
218  long OrderOf(long i) const { return cube.getDim(i); }
219 
221  long ProdOrdsFrom(long i) const { return cube.getProd(i); }
222 
224  bool SameOrd(long i) const { return native[i]; }
225 
226  // FrobPerturb[i] = j if gens[i] raised to its order equals p^j,
227  // where j in [0..ordP), otherwise -1
228  long FrobPerturb(long i) const { return frob_perturb[i]; }
229 
231 
233  long ith_rep(long i) const { return (i < getNSlots()) ? T[i] : 0; }
234 
236  long indexOfRep(long t) const { return (t > 0 && t < m) ? Tidx[t] : -1; }
237 
239  bool isRep(long t) const { return (t > 0 && t < m && Tidx[t] > -1); }
240 
242  long indexInZmstar(long t) const { return (t > 0 && t < m) ? zmsIdx[t] : -1; }
243 
245  long indexInZmstar_unchecked(long t) const { return zmsIdx[t]; }
246 
248  long repInZmstar_unchecked(long idx) const { return zmsRep[idx]; }
249 
250  bool inZmStar(long t) const { return (t > 0 && t < m && zmsIdx[t] > -1); }
251 
254  long exponentiate(const std::vector<long>& exps,
255  bool onlySameOrd = false) const;
256 
258  long coordinate(long i, long k) const { return cube.getCoord(k, i); }
259 
262  std::pair<long, long> breakIndexByDim(long idx, long dim) const
263  {
264  return cube.breakIndexByDim(idx, dim);
265  }
266 
268  long assembleIndexByDim(std::pair<long, long> idx, long dim) const
269  {
270  return cube.assembleIndexByDim(idx, dim);
271  }
272 
274  long addCoord(long i, long k, long offset) const
275  {
276  return cube.addCoord(k, i, offset);
277  }
278 
279  /* Miscellaneous */
280 
284  bool nextExpVector(std::vector<long>& exps) const
285  {
286  return cube.incrementCoords(exps);
287  }
288 
290  long fftSizeNeeded() const { return NTL::NextPowerOfTwo(getM()) + 1; }
291  // TODO: should have a special case when m is power of two
292 
293  const PGFFT& getFFTInfo() const { return *fftInfo; }
294  const half_FFT& getHalfFFTInfo() const { return *half_fftInfo; }
295  const quarter_FFT& getQuarterFFTInfo() const { return *quarter_fftInfo; }
296 };
297 
298 enum PA_tag
299 {
302  PA_cx_tag
303 };
304 
333 class DummyBak
334 {
335  // placeholder class used in GF2X impl
336 
337 public:
338  void save() {}
339  void restore() const {}
340 };
341 
342 class DummyContext
343 {
344  // placeholder class used in GF2X impl
345 
346 public:
347  void save() {}
348  void restore() const {}
349  DummyContext() {}
350  DummyContext(long) {}
351 };
352 
353 class DummyModulus
354 {};
355 // placeholder class for CKKS
356 
357 // some stuff to help with template code
358 template <typename R>
359 struct GenericModulus
360 {};
361 
362 template <>
363 struct GenericModulus<NTL::zz_p>
364 {
365  static void init(long p) { NTL::zz_p::init(p); }
366 };
367 
368 template <>
369 struct GenericModulus<NTL::GF2>
370 {
371  static void init(long p)
372  {
373  assertEq<InvalidArgument>(p, 2l, "Cannot init NTL::GF2 with p not 2");
374  }
375 };
376 
377 class PA_GF2
378 {
379  // typedefs for algebraic structures built up from GF2
380 
381 public:
382  static const PA_tag tag = PA_GF2_tag;
383  typedef NTL::GF2 R;
384  typedef NTL::GF2X RX;
385  typedef NTL::vec_GF2X vec_RX;
386  typedef NTL::GF2XModulus RXModulus;
387  typedef DummyBak RBak;
388  typedef DummyContext RContext;
389  typedef NTL::GF2E RE;
390  typedef NTL::vec_GF2E vec_RE;
391  typedef NTL::mat_GF2E mat_RE;
392  typedef NTL::GF2EX REX;
393  typedef NTL::GF2EBak REBak;
394  typedef NTL::vec_GF2EX vec_REX;
395  typedef NTL::GF2EContext REContext;
396  typedef NTL::mat_GF2 mat_R;
397  typedef NTL::vec_GF2 vec_R;
398 };
399 
400 class PA_zz_p
401 {
402  // typedefs for algebraic structures built up from zz_p
403 
404 public:
405  static const PA_tag tag = PA_zz_p_tag;
406  typedef NTL::zz_p R;
407  typedef NTL::zz_pX RX;
408  typedef NTL::vec_zz_pX vec_RX;
409  typedef NTL::zz_pXModulus RXModulus;
410  typedef NTL::zz_pBak RBak;
411  typedef NTL::zz_pContext RContext;
412  typedef NTL::zz_pE RE;
413  typedef NTL::vec_zz_pE vec_RE;
414  typedef NTL::mat_zz_pE mat_RE;
415  typedef NTL::zz_pEX REX;
416  typedef NTL::zz_pEBak REBak;
417  typedef NTL::vec_zz_pEX vec_REX;
418  typedef NTL::zz_pEContext REContext;
419  typedef NTL::mat_zz_p mat_R;
420  typedef NTL::vec_zz_p vec_R;
421 };
422 
423 class PA_cx
424 {
425  // typedefs for algebraic structures built up from complex<double>
426 
427 public:
428  static const PA_tag tag = PA_cx_tag;
429  typedef double R;
430  typedef std::complex<double> RX;
431  typedef NTL::Vec<RX> vec_RX;
432  typedef DummyModulus RXModulus;
433  typedef DummyBak RBak;
434  typedef DummyContext RContext;
435 
436  // the other typedef's should not ever be used...they
437  // are all defined as void, so that PA_INJECT still works
438  typedef void RE;
439  typedef void vec_RE;
440  typedef void mat_RE;
441  typedef void REX;
442  typedef void REBak;
443  typedef void vec_REX;
444  typedef void REContext;
445  typedef void mat_R;
446  typedef void vec_R;
447 };
448 
450 
453 {
454 
455 public:
456  virtual ~PAlgebraModBase() {}
457  virtual PAlgebraModBase* clone() const = 0;
458 
460  virtual PA_tag getTag() const = 0;
461 
463  virtual const PAlgebra& getZMStar() const = 0;
464 
466  virtual const std::vector<NTL::ZZX>& getFactorsOverZZ() const = 0;
467 
469  virtual long getR() const = 0;
470 
472  virtual long getPPowR() const = 0;
473 
475  virtual void restoreContext() const = 0;
476 
477  virtual zzX getMask_zzX(long i, long j) const = 0;
478 };
479 
480 #ifndef DOXYGEN_IGNORE
481 #define PA_INJECT(typ) \
482  static const PA_tag tag = typ::tag; \
483  typedef typename typ::R R; \
484  typedef typename typ::RX RX; \
485  typedef typename typ::vec_RX vec_RX; \
486  typedef typename typ::RXModulus RXModulus; \
487  typedef typename typ::RBak RBak; \
488  typedef typename typ::RContext RContext; \
489  typedef typename typ::RE RE; \
490  typedef typename typ::vec_RE vec_RE; \
491  typedef typename typ::mat_RE mat_RE; \
492  typedef typename typ::REX REX; \
493  typedef typename typ::REBak REBak; \
494  typedef typename typ::vec_REX vec_REX; \
495  typedef typename typ::REContext REContext; \
496  typedef typename typ::mat_R mat_R; \
497  typedef typename typ::vec_R vec_R;
498 
499 #endif
500 
501 template <typename type>
502 class PAlgebraModDerived;
503 // forward declaration
504 
506 template <typename type>
508 {
509 
510 public:
511  PA_INJECT(type)
512 
513  friend class PAlgebraModDerived<type>;
514 
515 private:
516  RX G; // the polynomial defining the field extension
517  long degG; // the degree of the polynomial
518 
519  REContext contextForG;
520 
521  /* the remaining fields are visible only to PAlgebraModDerived */
522 
523  std::vector<RX> maps;
524  std::vector<mat_R> matrix_maps;
525  std::vector<REX> rmaps;
526 
527 public:
528  const RX& getG() const { return G; }
529  long getDegG() const { return degG; }
530  void restoreContextForG() const { contextForG.restore(); }
531 
532  // copy and assignment
533 };
534 
536 template <typename T>
537 class TNode
538 {
539 public:
540  std::shared_ptr<TNode<T>> left, right;
541  T data;
542 
543  TNode(std::shared_ptr<TNode<T>> _left,
544  std::shared_ptr<TNode<T>> _right,
545  const T& _data) :
546  left(_left), right(_right), data(_data)
547  {}
548 };
549 
550 template <typename T>
551 std::shared_ptr<TNode<T>> buildTNode(std::shared_ptr<TNode<T>> left,
552  std::shared_ptr<TNode<T>> right,
553  const T& data)
554 {
555  return std::shared_ptr<TNode<T>>(new TNode<T>(left, right, data));
556 }
557 
558 template <typename T>
559 std::shared_ptr<TNode<T>> nullTNode()
560 {
561  return std::shared_ptr<TNode<T>>();
562 }
564 
566 template <typename type>
568 {
569 public:
570  PA_INJECT(type)
571 
572 private:
573  const PAlgebra& zMStar;
574  long r;
575  long pPowR;
576  RContext pPowRContext;
577 
578  RXModulus PhimXMod;
579 
580  vec_RX factors;
581  std::vector<NTL::ZZX> factorsOverZZ;
582  vec_RX crtCoeffs;
583  std::vector<std::vector<RX>> maskTable;
584  std::vector<RX> crtTable;
585  std::shared_ptr<TNode<RX>> crtTree;
586 
587  void genMaskTable();
588  void genCrtTable();
589 
590 public:
592 
593  PAlgebraModDerived(const PAlgebra& zMStar, long r);
594 
595  PAlgebraModDerived(const PAlgebraModDerived& other) // copy constructor
596  :
597  zMStar(other.zMStar),
598  r(other.r),
599  pPowR(other.pPowR),
600  pPowRContext(other.pPowRContext)
601  {
602  RBak bak;
603  bak.save();
604  restoreContext();
605  PhimXMod = other.PhimXMod;
606  factors = other.factors;
607  maskTable = other.maskTable;
608  crtTable = other.crtTable;
609  crtTree = other.crtTree;
610  }
611 
613  virtual PAlgebraModBase* clone() const override
614  {
615  return new PAlgebraModDerived(*this);
616  }
617 
619  virtual PA_tag getTag() const override { return tag; }
620 
622  virtual const PAlgebra& getZMStar() const override { return zMStar; }
623 
625  virtual const std::vector<NTL::ZZX>& getFactorsOverZZ() const override
626  {
627  return factorsOverZZ;
628  }
629 
631  virtual long getR() const override { return r; }
632 
634  virtual long getPPowR() const override { return pPowR; }
635 
637  virtual void restoreContext() const override { pPowRContext.restore(); }
638 
639  /* In all of the following functions, it is expected that the caller
640  has already restored the relevant modulus (p^r), which
641  can be done by invoking the method restoreContext()
642  */
643 
645  const RXModulus& getPhimXMod() const { return PhimXMod; }
646 
648  const vec_RX& getFactors() const { return factors; }
649 
653  const vec_RX& getCrtCoeffs() const { return crtCoeffs; }
654 
667  // logically, but not really, const
668  const std::vector<std::vector<RX>>& getMaskTable() const { return maskTable; }
669 
670  zzX getMask_zzX(long i, long j) const override
671  {
672  RBak bak;
673  bak.save();
674  restoreContext();
675  return balanced_zzX(maskTable.at(i).at(j));
676  }
677 
684 
687  void CRT_decompose(std::vector<RX>& crt, const RX& H) const;
688 
691  void CRT_reconstruct(RX& H, std::vector<RX>& crt) const;
692 
696  void mapToSlots(MappingData<type>& mappingData, const RX& G) const;
697 
704  void embedInAllSlots(RX& H,
705  const RX& alpha,
706  const MappingData<type>& mappingData) const;
707 
714  void embedInSlots(RX& H,
715  const std::vector<RX>& alphas,
716  const MappingData<type>& mappingData) const;
717 
722  void decodePlaintext(std::vector<RX>& alphas,
723  const RX& ptxt,
724  const MappingData<type>& mappingData) const;
725 
734  void buildLinPolyCoeffs(std::vector<RX>& C,
735  const std::vector<RX>& L,
736  const MappingData<type>& mappingData) const;
738 private:
739  /* internal functions, not for public consumption */
740 
741  static void SetModulus(long p)
742  {
743  RContext context(p);
744  context.restore();
745  }
746 
748  void mapToF1(RX& w, const RX& G) const { mapToFt(w, G, 1); }
749 
752  void mapToFt(RX& w, const RX& G, long t, const RX* rF1 = nullptr) const;
753 
754  void buildTree(std::shared_ptr<TNode<RX>>& res,
755  long offset,
756  long extent) const;
757 
758  void evalTree(RX& res,
759  std::shared_ptr<TNode<RX>> tree,
760  const std::vector<RX>& crt1,
761  long offset,
762  long extent) const;
763 };
764 
768 template <>
769 class PAlgebraModDerived<PA_cx> : public PAlgebraModBase
770 {
771  const PAlgebra& zMStar;
772  long r; // counts bits of precision
773 
774 public:
775  PAlgebraModDerived(const PAlgebra& palg, long _r) : zMStar(palg), r(_r)
776  {
777  assertInRange<InvalidArgument>(r,
778  1l,
779  (long)NTL_SP_NBITS,
780  "Invalid bit precision r");
781  }
782 
783  PAlgebraModBase* clone() const override
784  {
785  return new PAlgebraModDerived(*this);
786  }
787  PA_tag getTag() const override { return PA_cx_tag; }
788 
789  const PAlgebra& getZMStar() const override { return zMStar; }
790  long getR() const override { return r; }
791  long getPPowR() const override { return 1L << r; }
792  void restoreContext() const override {}
793 
794  // These function make no sense for PAlgebraModCx
795  const std::vector<NTL::ZZX>& getFactorsOverZZ() const override
796  {
797  throw LogicError("PAlgebraModCx::getFactorsOverZZ undefined");
798  }
799  zzX getMask_zzX(UNUSED long i, UNUSED long j) const override
800  {
801  throw LogicError("PAlgebraModCx::getMask_zzX undefined");
802  }
803 };
804 
806 
808 PAlgebraModBase* buildPAlgebraMod(const PAlgebra& zMStar, long r);
809 
810 // A simple wrapper for a pointer to an object of type PAlgebraModBase.
811 //
812 // Direct access to the virtual methods of PAlgebraModBase is provided,
813 // along with a "downcast" operator to get a reference to the object
814 // as a derived type, and == and != operators.
816 {
817 
818 private:
820 
821 public:
822  // copy constructor: default
823  // assignment: deleted
824  // destructor: default
825  // NOTE: the use of ClonedPtr ensures that the default copy constructor
826  // and destructor will work correctly.
827 
828  PAlgebraMod& operator=(const PAlgebraMod&) = delete;
829 
830  explicit PAlgebraMod(const PAlgebra& zMStar, long r) :
831  rep(buildPAlgebraMod(zMStar, r))
832  {}
833  // constructor
834 
838  template <typename type>
840  {
841  return dynamic_cast<const PAlgebraModDerived<type>&>(*rep);
842  }
843  const PAlgebraModCx& getCx() const
844  {
845  return dynamic_cast<const PAlgebraModCx&>(*rep);
846  }
847 
848  bool operator==(const PAlgebraMod& other) const
849  {
850  return getZMStar() == other.getZMStar() && getR() == other.getR();
851  }
852  // comparison
853 
854  bool operator!=(const PAlgebraMod& other) const { return !(*this == other); }
855  // comparison
856 
857  /* direct access to the PAlgebraModBase methods */
858 
860  PA_tag getTag() const { return rep->getTag(); }
862  const PAlgebra& getZMStar() const { return rep->getZMStar(); }
864  const std::vector<NTL::ZZX>& getFactorsOverZZ() const
865  {
866  return rep->getFactorsOverZZ();
867  }
869  long getR() const { return rep->getR(); }
871  long getPPowR() const { return rep->getPPowR(); }
873  void restoreContext() const { rep->restoreContext(); }
874 
875  zzX getMask_zzX(long i, long j) const { return rep->getMask_zzX(i, j); }
876 };
877 
879 bool comparePAlgebra(const PAlgebra& palg,
880  unsigned long m,
881  unsigned long p,
882  unsigned long r,
883  const std::vector<long>& gens,
884  const std::vector<long>& ords);
885 
886 // for internal consumption only
887 double calcPolyNormBnd(long m);
888 
889 } // namespace helib
890 
891 #endif // #ifndef HELIB_PALGEBRA_H
A smart pointer that clones the object it holds when it is copied.
Definition: ClonedPtr.h:101
Holds a vector of dimensions for a hypercube and some additional data.
Definition: hypercube.h:28
bool incrementCoords(VecType &v) const
Definition: hypercube.h:138
long getDim(long d) const
size of dimension d
Definition: hypercube.h:92
long getProd(long d) const
product of sizes of dimensions d, d+1, ...
Definition: hypercube.h:95
long addCoord(long i, long d, long offset) const
add offset to coordinate in dimension d of index i
Definition: hypercube.h:115
std::pair< long, long > breakIndexByDim(long idx, long dim) const
Definition: hypercube.cpp:20
long getSize() const
total size of cube
Definition: hypercube.h:89
long assembleIndexByDim(std::pair< long, long > idx, long dim) const
The inverse of breakIndexByDim.
Definition: hypercube.cpp:29
long getCoord(long i, long d) const
get coordinate in dimension d of index i
Definition: hypercube.h:104
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
The structure of (Z/mZ)* /(p)
Definition: PAlgebra.h:77
long ProdOrdsFrom(long i) const
The product prod_{j=i}^{n-1} OrderOf(i)
Definition: PAlgebra.h:221
void printout(std::ostream &out=std::cout) const
Prints the structure in a readable form.
Definition: PAlgebra.cpp:107
long ith_rep(long i) const
Returns the i'th element in T.
Definition: PAlgebra.h:233
bool isRep(long t) const
Is t in T?
Definition: PAlgebra.h:239
long genToPow(long i, long j) const
the i'th generator to the power j mod m
Definition: PAlgebra.cpp:606
long exponentiate(const std::vector< long > &exps, bool onlySameOrd=false) const
Returns prod_i gi^{exps[i]} mod m. If onlySameOrd=true, use only generators that have the same order ...
Definition: PAlgebra.cpp:91
bool inZmStar(long t) const
Definition: PAlgebra.h:250
long assembleIndexByDim(std::pair< long, long > idx, long dim) const
The inverse of breakIndexByDim.
Definition: PAlgebra.h:268
const half_FFT & getHalfFFTInfo() const
Definition: PAlgebra.h:294
double get_cM() const
The "ring constant" cM.
Definition: PAlgebra.h:197
bool SameOrd(long i) const
Is ord(i'th generator) the same as its order in (Z/mZ)^*?
Definition: PAlgebra.h:224
long getPhiM() const
Returns phi(m)
Definition: PAlgebra.h:170
void printAll(std::ostream &out=std::cout) const
Definition: PAlgebra.cpp:149
const PGFFT & getFFTInfo() const
Definition: PAlgebra.h:293
long getP() const
Returns p.
Definition: PAlgebra.h:167
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 FrobPerturb(long i) const
Definition: PAlgebra.h:228
long getM() const
Returns m.
Definition: PAlgebra.h:164
long frobeniusPow(long j) const
Definition: PAlgebra.cpp:600
bool operator==(const PAlgebra &other) const
Definition: PAlgebra.cpp:81
bool operator!=(const PAlgebra &other) const
Definition: PAlgebra.h:152
long indexOfRep(long t) const
Returns the index of t in T.
Definition: PAlgebra.h:236
long indexInZmstar(long t) const
Returns the index of t in (Z/mZ)*.
Definition: PAlgebra.h:242
bool nextExpVector(std::vector< long > &exps) const
Definition: PAlgebra.h:284
PAlgebra & operator=(const PAlgebra &)=delete
long ZmStarGen(long i) const
the i'th generator in (Z/mZ)^* /(p) (if any)
Definition: PAlgebra.h:206
double getNormBnd() const
max-norm-on-pwfl-basis <= normBnd * max-norm-canon-embed
Definition: PAlgebra.h:182
const NTL::ZZX & getPhimX() const
The cyclotomix polynomial Phi_m(X)
Definition: PAlgebra.h:194
long OrderOf(long i) const
The order of i'th generator (if any)
Definition: PAlgebra.h:218
long repInZmstar_unchecked(long idx) const
Returns rep whose index is i.
Definition: PAlgebra.h:248
const quarter_FFT & getQuarterFFTInfo() const
Definition: PAlgebra.h:295
long getOrdP() const
The order of p in (Z/mZ)^*.
Definition: PAlgebra.h:173
PAlgebra(long mm, long pp=2, const std::vector< long > &_gens=std::vector< long >(), const std::vector< long > &_ords=std::vector< long >())
Definition: PAlgebra.cpp:431
long getRadM() const
getRadM() = prod of distinct prime factors of m
Definition: PAlgebra.h:179
double getPolyNormBnd() const
max-norm-on-pwfl-basis <= polyNormBnd * max-norm-canon-embed
Definition: PAlgebra.h:185
long indexInZmstar_unchecked(long t) const
Returns the index of t in (Z/mZ)* – no range checking.
Definition: PAlgebra.h:245
long addCoord(long i, long k, long offset) const
adds offset to index k in the i'th dimension
Definition: PAlgebra.h:274
long fftSizeNeeded() const
The largest FFT we need to handle degree-m polynomials.
Definition: PAlgebra.h:290
std::pair< long, long > breakIndexByDim(long idx, long dim) const
Definition: PAlgebra.h:262
long coordinate(long i, long k) const
Returns coordinate of index k along the i'th dimension.
Definition: PAlgebra.h:258
long getNFactors() const
The number of distinct prime factors of m.
Definition: PAlgebra.h:176
long getPow2() const
if m = 2^k, then pow2 == k; otherwise, pow2 == 0
Definition: PAlgebra.h:191
Virtual base class for PAlgebraMod.
Definition: PAlgebra.h:453
virtual PAlgebraModBase * clone() const =0
virtual zzX getMask_zzX(long i, long j) const =0
virtual const PAlgebra & getZMStar() const =0
Returns reference to underlying PAlgebra object.
virtual void restoreContext() const =0
Restores the NTL context for p^r.
virtual PA_tag getTag() const =0
Returns the type tag: PA_GF2_tag or PA_zz_p_tag.
virtual long getPPowR() const =0
The value p^r.
virtual ~PAlgebraModBase()
Definition: PAlgebra.h:456
virtual long getR() const =0
The value r.
virtual const std::vector< NTL::ZZX > & getFactorsOverZZ() const =0
Returns reference to the factorization of Phi_m(X) mod p^r, but as ZZX's.
Definition: PAlgebra.h:770
const PAlgebra & getZMStar() const override
Returns reference to underlying PAlgebra object.
Definition: PAlgebra.h:789
void restoreContext() const override
Restores the NTL context for p^r.
Definition: PAlgebra.h:792
PAlgebraModBase * clone() const override
Definition: PAlgebra.h:783
zzX getMask_zzX(UNUSED long i, UNUSED long j) const override
Definition: PAlgebra.h:799
long getR() const override
The value r.
Definition: PAlgebra.h:790
const std::vector< NTL::ZZX > & getFactorsOverZZ() const override
Returns reference to the factorization of Phi_m(X) mod p^r, but as ZZX's.
Definition: PAlgebra.h:795
PAlgebraModDerived(const PAlgebra &palg, long _r)
Definition: PAlgebra.h:775
PA_tag getTag() const override
Returns the type tag: PA_GF2_tag or PA_zz_p_tag.
Definition: PAlgebra.h:787
long getPPowR() const override
The value p^r.
Definition: PAlgebra.h:791
A concrete instantiation of the virtual class.
Definition: PAlgebra.h:568
virtual const std::vector< NTL::ZZX > & getFactorsOverZZ() const override
Returns reference to the factorization of Phi_m(X) mod p^r, but as ZZX's.
Definition: PAlgebra.h:625
virtual long getR() const override
The value r.
Definition: PAlgebra.h:631
virtual long getPPowR() const override
The value p^r.
Definition: PAlgebra.h:634
void embedInSlots(RX &H, const std::vector< RX > &alphas, const MappingData< type > &mappingData) const
Returns H in R[X]/Phi_m(X) s.t. for every t in T, the element Ht = (H mod Ft) in R[X]/Ft(X) represent...
Definition: PAlgebra.cpp:925
void CRT_decompose(std::vector< RX > &crt, const RX &H) const
Returns a std::vector crt[] such that crt[i] = H mod Ft (with t = T[i])
Definition: PAlgebra.cpp:872
virtual void restoreContext() const override
Restores the NTL context for p^r.
Definition: PAlgebra.h:637
zzX getMask_zzX(long i, long j) const override
Definition: PAlgebra.h:670
virtual PA_tag getTag() const override
Returns the type tag: PA_GF2_tag or PA_zz_p_tag.
Definition: PAlgebra.h:619
virtual PAlgebraModBase * clone() const override
Returns a pointer to a "clone".
Definition: PAlgebra.h:613
PAlgebraModDerived(const PAlgebraModDerived &other)
Definition: PAlgebra.h:595
const std::vector< std::vector< RX > > & getMaskTable() const
Returns ref to maskTable, which is used to implement rotations (in the EncryptedArray module).
Definition: PAlgebra.h:668
void decodePlaintext(std::vector< RX > &alphas, const RX &ptxt, const MappingData< type > &mappingData) const
Return an array such that alphas[i] in R[X]/G(X) represent the same element as rt = (H mod Ft) in R[X...
Definition: PAlgebra.cpp:1230
PAlgebraModDerived & operator=(const PAlgebraModDerived &)=delete
const vec_RX & getCrtCoeffs() const
Returns the CRT coefficients: element i contains (prod_{j!=i} F_j)^{-1} mod F_i, where F_0 F_1 ....
Definition: PAlgebra.h:653
void mapToSlots(MappingData< type > &mappingData, const RX &G) const
Compute the maps for all the slots. In the current implementation, we if r > 1, then we must have eit...
Definition: PAlgebra.cpp:1103
const RXModulus & getPhimXMod() const
Returns reference to an RXModulus representing Phi_m(X) (mod p^r)
Definition: PAlgebra.h:645
void CRT_reconstruct(RX &H, std::vector< RX > &crt) const
Returns H in R[X]/Phi_m(X) s.t. for every i<nSlots and t=T[i], we have H == crt[i] (mod Ft)
Definition: PAlgebra.cpp:994
virtual const PAlgebra & getZMStar() const override
Returns reference to underlying PAlgebra object.
Definition: PAlgebra.h:622
PAlgebraModDerived(const PAlgebra &zMStar, long r)
Definition: PAlgebra.cpp:668
void embedInAllSlots(RX &H, const RX &alpha, const MappingData< type > &mappingData) const
Returns H in R[X]/Phi_m(X) s.t. for every t in T, the element Ht = (H mod Ft) in R[X]/Ft(X) represent...
Definition: PAlgebra.cpp:887
const vec_RX & getFactors() const
Returns reference to the factors of Phim_m(X) modulo p^r.
Definition: PAlgebra.h:648
void buildLinPolyCoeffs(std::vector< RX > &C, const std::vector< RX > &L, const MappingData< type > &mappingData) const
Returns a coefficient std::vector C for the linearized polynomial representing M.
Definition: PAlgebra.cpp:1268
The structure of Z[X]/(Phi_m(X), p)
Definition: PAlgebra.h:816
PAlgebraMod(const PAlgebra &zMStar, long r)
Definition: PAlgebra.h:830
PA_tag getTag() const
Returns the type tag: PA_GF2_tag or PA_zz_p_tag.
Definition: PAlgebra.h:860
long getR() const
The value r.
Definition: PAlgebra.h:869
bool operator==(const PAlgebraMod &other) const
Definition: PAlgebra.h:848
void restoreContext() const
Restores the NTL context for p^r.
Definition: PAlgebra.h:873
const PAlgebraModDerived< type > & getDerived(type) const
Definition: PAlgebra.h:839
long getPPowR() const
The value p^r.
Definition: PAlgebra.h:871
const PAlgebraModCx & getCx() const
Definition: PAlgebra.h:843
zzX getMask_zzX(long i, long j) const
Definition: PAlgebra.h:875
const std::vector< NTL::ZZX > & getFactorsOverZZ() const
Returns reference to the factorization of Phi_m(X) mod p^r, but as ZZX's.
Definition: PAlgebra.h:864
const PAlgebra & getZMStar() const
Returns reference to underlying PAlgebra object.
Definition: PAlgebra.h:862
PAlgebraMod & operator=(const PAlgebraMod &)=delete
bool operator!=(const PAlgebraMod &other) const
Definition: PAlgebra.h:854
Definition: PGFFT.h:30
Definition: io.cpp:18
Definition: apiAttributes.h:21
NTL::Vec< long > zzX
Definition: zzX.h:24
double calcPolyNormBnd(long m)
Definition: PAlgebra.cpp:213
zzX balanced_zzX(const NTL::zz_pX &f)
Definition: zzX.cpp:122
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
PAlgebraModDerived< PA_cx > PAlgebraModCx
Definition: PAlgebra.h:805
bool comparePAlgebra(const PAlgebra &palg, unsigned long m, unsigned long p, unsigned long r, const std::vector< long > &gens, const std::vector< long > &ords)
returns true if the palg parameters match the rest, false otherwise
PAlgebraModBase * buildPAlgebraMod(const PAlgebra &zMStar, long r)
Builds a table, of type PA_GF2 if p == 2 and r == 1, and PA_zz_p otherwise.
Definition: PAlgebra.cpp:632
Definition: PAlgebra.h:33
half_FFT(long m)
Definition: PAlgebra.cpp:170
PGFFT fft
Definition: PAlgebra.h:34
std::vector< std::complex< double > > pow
Definition: PAlgebra.h:35
Definition: PAlgebra.h:41
PGFFT fft
Definition: PAlgebra.h:42
quarter_FFT(long m)
Definition: PAlgebra.cpp:183
std::vector< std::complex< double > > pow2
Definition: PAlgebra.h:43
std::vector< std::complex< double > > pow1
Definition: PAlgebra.h:43