HElib  1.0
Implementing Homomorphic Encryption
 All Classes Files Functions Variables Friends Pages
SingleCRT.h
Go to the documentation of this file.
1 /* Copyright (C) 2012,2013 IBM Corp.
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License along
13  * with this program; if not, write to the Free Software Foundation, Inc.,
14  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  */
20 #ifndef _SingleCRT_H_
21 #define _SingleCRT_H_
22 
37 #include <vector>
38 #include <iostream>
39 #include <NTL/ZZX.h>
40 
41 #include "FHEContext.h"
42 #include "IndexMap.h"
43 #include "DoubleCRT.h"
44 
45 class SingleCRT {
46  const FHEcontext& context;
47  IndexMap<ZZX> map; // the SingleCRT data
48 
49  friend class DoubleCRT;
50 
51  // a "sanity check" function, verifies consistency of polys with current
52  // moduli chain an error is raised if they are not consistent
53  void verify();
54 
55  // Generic operators, Fnc is either AddMod, SubMod, or MulMod. (This should
56  // have been a template, but gcc refuses to cooperate.)
57 
58  // The behavior when the *this and other have different index sets depends
59  // on the matchIndexSets flag. When it is set to true then the union of the
60  // two index sets is used; if false, then the index set of *this is used.
61  SingleCRT& Op(const SingleCRT &other,
62  void (*Fnc)(ZZ&, const ZZ&, const ZZ&, const ZZ&),
63  bool matchIndexSets=true);
64 
65  SingleCRT& Op(const ZZX &poly,
66  void (*Fnc)(ZZ&, const ZZ&, const ZZ&, const ZZ&));
67  SingleCRT& Op(const ZZ &num, void (*Fnc)(ZZX&, const ZZX&, const ZZ&));
68 
69 
70  public:
71 
72 
73  // Constructors and assignment operators
74 
75  // representing an integer polynomial as SingleCRT. If the index set
76  // is not specified, then all the primes from the context are used.
77  // If the coefficients of poly are larger than the product of
78  // the used moduli, they are effectively reduced modulo that product
79 
80  SingleCRT(const ZZX& poly, const FHEcontext& _context, const IndexSet& s);
81  SingleCRT(const ZZX& poly, const FHEcontext& _context);
82  SingleCRT(const ZZX& poly); // uses active context
83 
84 
85  // Without specifying a ZZX, we get the zero polynomial
86 
87  SingleCRT(const FHEcontext& _context, const IndexSet& s);
88  SingleCRT(const FHEcontext& _context);
89 
90  SingleCRT(); // uses the "active context", run-time error if it is NULL
91 
92  // Assignment operators
93 
94  SingleCRT& operator=(const SingleCRT& other);
95  SingleCRT& operator=(const DoubleCRT& dcrt);
96  SingleCRT& operator=(const ZZX& poly);
97  SingleCRT& operator=(const ZZ& num) { *this = to_ZZX(num); return *this; }
98  SingleCRT& operator=(const long num) { *this = to_ZZX(num); return *this; }
99 
100  bool operator==(const SingleCRT& other) const {
101  return &context == &other.context && map == other.map;
102  }
103 
104  bool operator!=(const SingleCRT& other) const {
105  return !(*this==other);
106  }
107 
108  // Set to zero, one
109 
110  SingleCRT& setZero() { *this = ZZX::zero(); return *this; }
111  SingleCRT& setOne() { *this = 1; return *this; }
112 
113 
114  // expand the index set by s1.
115  // it is assumed that s1 is disjoint from the current index set.
116  void addPrimes(const IndexSet& s1);
117 
118 
119  // remove s1 from the index set
120  void removePrimes(const IndexSet& s1) {
121  map.remove(s1);
122  }
123 
124  // Arithmetic operations. Only the "destructive" versions are used,
125  // i.e., a += b is implemented but not a + b.
126 
127  // Addition, negation, subtraction
128  SingleCRT& operator+=(const SingleCRT &other){ return Op(other,NTL::AddMod);}
129  SingleCRT& operator+=(const ZZX &poly) { return Op(poly, NTL::AddMod);}
130  SingleCRT& operator+=(const ZZ &num) { return Op(num, NTL::add); }
131  SingleCRT& operator+=(long num) { return Op(to_ZZ(num), NTL::add); }
132 
133  SingleCRT& operator-=(const SingleCRT &other){ return Op(other,NTL::SubMod);}
134  SingleCRT& operator-=(const ZZX &poly) { return Op(poly, NTL::SubMod); }
135  SingleCRT& operator-=(const ZZ &num) { return Op(num, NTL::sub); }
136  SingleCRT& operator-=(long num) { return Op(to_ZZ(num), NTL::sub); }
137 
138  // Procedural equivalents, supporting also the matchIndexSets flag
139  void Add(const SingleCRT &other, bool matchIndexSet=true)
140  { Op(other, NTL::AddMod, matchIndexSet); }
141  void Sub(const SingleCRT &other, bool matchIndexSet=true)
142  { Op(other, NTL::SubMod, matchIndexSet); }
143 
144  // These are the prefix versions, ++dcrt and --dcrt.
145  SingleCRT& operator++() { return (*this += 1); };
146  SingleCRT& operator--() { return (*this -= 1); };
147 
148  // Postfix version...no return value...just for style
149  void operator++(int) { *this += 1; };
150  void operator--(int) { *this -= 1; };
151 
152  // Multiplication by constant
153  SingleCRT& operator*=(const ZZ &num) { return Op(num,NTL::mul); }
154  SingleCRT& operator*=(long num) { return Op(to_ZZ(num),NTL::mul); }
155 
156  // Division by constant
157  SingleCRT& operator/=(const ZZ &num);
158  SingleCRT& operator/=(long num) { return (*this /= to_ZZ(num)); }
159 
160  // Recovering the polynomial in coefficient representation. This yields an
161  // integer polynomial with coefficients in [-P/2,P/2] (P is the product of
162  // all moduli used). The polynomial is reduced modulo the product of only
163  // the primes in the IndexSet parameter.
164 
165  void toPoly(ZZX& p, const IndexSet& s) const;
166  void toPoly(ZZX& p) const;
167 
168 #if 0
169  // I/O: ONLY the ZZX vector is outputted/recovered, not the moduli chain!! An
170  // error is raised on input if this is not consistent with the current chain
171 
172  friend ostream& operator<<(ostream &s, const SingleCRT &scrt)
173  { s << scrt.polys; return s; }
174 
175  friend istream& operator>> (istream &s, SingleCRT &scrt)
176  { s >> scrt.polys; scrt.verify(); return s; }
177 #endif
178 
179  // Access methods
180  const IndexMap<ZZX>& getMap() const { return map; }
181  const FHEcontext& getContext() const { return context; }
182 };
183 inline void conv(SingleCRT &s, const ZZX &p) { s=p; }
184 // Cannot implement to_SingleCRT(p), since modChain is not defined
185 
186 inline void conv(ZZX &p, const SingleCRT &s) { s.toPoly(p); }
187 inline ZZX to_ZZX(const SingleCRT &s) { ZZX p; s.toPoly(p); return p; }
188 
189 inline void conv(SingleCRT &s, const DoubleCRT &d) { s=d; }
190 #endif // #ifndef _SingleCRT_H_