16 #ifndef _EncryptedArray_H_
17 #define _EncryptedArray_H_
23 #include <NTL/ZZ_pX.h>
69 virtual const FHEcontext& getContext()
const = 0;
70 virtual const long getDegree()
const = 0;
73 virtual void rotate(
Ctxt& ctxt,
long k)
const = 0;
76 virtual void shift(
Ctxt& ctxt,
long k)
const = 0;
82 virtual void rotate1D(
Ctxt& ctxt,
long i,
long k,
bool dc=
false)
const = 0;
85 virtual void shift1D(
Ctxt& ctxt,
long i,
long k)
const = 0;
90 virtual void encode(ZZX& ptxt,
const vector< long >& array)
const = 0;
91 virtual void encode(ZZX& ptxt,
const vector< ZZX >& array)
const = 0;
92 virtual void encode(ZZX& ptxt,
const PlaintextArray& array)
const = 0;
93 virtual void decode(vector< long >& array,
const ZZX& ptxt)
const = 0;
94 virtual void decode(vector< ZZX >& array,
const ZZX& ptxt)
const = 0;
95 virtual void decode(
PlaintextArray& array,
const ZZX& ptxt)
const = 0;
103 virtual void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< long >& ptxt)
const = 0;
104 virtual void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< ZZX >& ptxt)
const = 0;
106 virtual void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< long >& ptxt)
const = 0;
107 virtual void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< ZZX >& ptxt)
const = 0;
113 virtual void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< long >& selector)
const = 0;
114 virtual void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< ZZX >& selector)
const = 0;
162 : context(other.context)
165 mappingData = other.mappingData;
170 if (
this == &other)
return *
this;
171 assert(&context == &other.context);
174 mappingData = other.mappingData;
180 const RX& getG()
const {
return mappingData.getG(); }
182 virtual const FHEcontext& getContext()
const {
return context; }
183 virtual const long getDegree()
const {
return mappingData.getDegG(); }
187 virtual void rotate(
Ctxt& ctxt,
long k)
const;
188 virtual void shift(
Ctxt& ctxt,
long k)
const;
189 virtual void rotate1D(
Ctxt& ctxt,
long i,
long k,
bool dc=
false)
const;
190 virtual void shift1D(
Ctxt& ctxt,
long i,
long k)
const;
192 virtual void encode(ZZX& ptxt,
const vector< long >& array)
const
193 { genericEncode(ptxt, array); }
195 virtual void encode(ZZX& ptxt,
const vector< ZZX >& array)
const
196 { genericEncode(ptxt, array); }
198 virtual void encode(ZZX& ptxt,
const PlaintextArray& array)
const;
202 virtual void decode(vector< long >& array,
const ZZX& ptxt)
const
203 { genericDecode(array, ptxt); }
205 virtual void decode(vector< ZZX >& array,
const ZZX& ptxt)
const
206 { genericDecode(array, ptxt); }
208 virtual void decode(
PlaintextArray& array,
const ZZX& ptxt)
const;
210 virtual void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< long >& ptxt)
const
211 { genericEncrypt(ctxt, pKey, ptxt); }
213 virtual void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< ZZX >& ptxt)
const
214 { genericEncrypt(ctxt, pKey, ptxt); }
217 { genericEncrypt(ctxt, pKey, ptxt); }
219 virtual void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< long >& ptxt)
const
220 { genericDecrypt(ctxt, sKey, ptxt); }
222 virtual void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< ZZX >& ptxt)
const
223 { genericDecrypt(ctxt, sKey, ptxt); }
226 { genericDecrypt(ctxt, sKey, ptxt); }
228 virtual void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< long >& selector)
const
229 { genericSelect(ctxt1, ctxt2, selector); }
231 virtual void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< ZZX >& selector)
const
232 { genericSelect(ctxt1, ctxt2, selector); }
235 { genericSelect(ctxt1, ctxt2, selector); }
241 void encode(ZZX& ptxt,
const vector< RX >& array)
const;
242 void decode(vector< RX >& array,
const ZZX& ptxt)
const;
244 void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< RX >& ptxt)
const
245 { genericEncrypt(ctxt, pKey, ptxt); }
247 void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< RX >& ptxt)
const
248 { genericDecrypt(ctxt, sKey, ptxt); }
258 void genericEncode(ZZX& ptxt,
const T& array)
const
263 convert(array1, array);
264 encode(ptxt, array1);
268 void genericDecode(T& array,
const ZZX& ptxt)
const
273 decode(array1, ptxt);
274 convert(array, array1);
279 const T& array)
const
281 assert(&context == &ctxt.getContext());
291 assert(&context == &ctxt.getContext());
293 sKey.Decrypt(pp, ctxt);
298 void genericSelect(
Ctxt& ctxt1,
const Ctxt& ctxt2,
299 const T& selector)
const
301 if (&ctxt1 == &ctxt2)
return;
303 assert(&context == &ctxt1.getContext() && &context == &ctxt2.getContext());
305 encode(poly,selector);
306 DoubleCRT dcrt(poly, context, ctxt1.getPrimeSet());
308 ctxt1.multByConstant(dcrt);
312 tmp.multByConstant(dcrt);
327 cloned_ptr<EncryptedArrayBase> rep;
333 : rep(buildEncryptedArray(context, G))
349 const FHEcontext& getContext()
const {
return rep->getContext(); }
350 const long getDegree()
const {
return rep->getDegree(); }
351 void rotate(
Ctxt& ctxt,
long k)
const { rep->rotate(ctxt, k); }
352 void shift(
Ctxt& ctxt,
long k)
const { rep->shift(ctxt, k); }
353 void rotate1D(
Ctxt& ctxt,
long i,
long k,
bool dc=
false)
const { rep->rotate1D(ctxt, i, k, dc); }
354 void shift1D(
Ctxt& ctxt,
long i,
long k)
const { rep->shift1D(ctxt, i, k); }
357 void encode(ZZX& ptxt,
const vector< long >& array)
const
358 { rep->encode(ptxt, array); }
359 void encode(ZZX& ptxt,
const vector< ZZX >& array)
const
360 { rep->encode(ptxt, array); }
362 { rep->encode(ptxt, array); }
364 void encodeUnitSelector(ZZX& ptxt,
long i)
const
365 { rep->encodeUnitSelector(ptxt, i); }
367 void decode(vector< long >& array,
const ZZX& ptxt)
const
368 { rep->decode(array, ptxt); }
369 void decode(vector< ZZX >& array,
const ZZX& ptxt)
const
370 { rep->decode(array, ptxt); }
372 { rep->decode(array, ptxt); }
374 void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< long >& ptxt)
const
375 { rep->encrypt(ctxt, pKey, ptxt); }
376 void encrypt(
Ctxt& ctxt,
const FHEPubKey& pKey,
const vector< ZZX >& ptxt)
const
377 { rep->encrypt(ctxt, pKey, ptxt); }
379 { rep->encrypt(ctxt, pKey, ptxt); }
382 void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< long >& ptxt)
const
383 { rep->decrypt(ctxt, sKey, ptxt); }
384 void decrypt(
const Ctxt& ctxt,
const FHESecKey& sKey, vector< ZZX >& ptxt)
const
385 { rep->decrypt(ctxt, sKey, ptxt); }
387 { rep->decrypt(ctxt, sKey, ptxt); }
390 void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< long >& selector)
const
391 { rep->select(ctxt1, ctxt2, selector); }
392 void select(
Ctxt& ctxt1,
const Ctxt& ctxt2,
const vector< ZZX >& selector)
const
393 { rep->select(ctxt1, ctxt2, selector); }
395 { rep->select(ctxt1, ctxt2, selector); }
397 void buildLinPolyCoeffs(vector<ZZX>& C,
const vector<ZZX>& L)
const
398 { rep->buildLinPolyCoeffs(C, L); }
400 long size()
const {
return rep->size(); }
401 long dimension()
const {
return rep->dimension(); }
402 long sizeOfDimension(
long i)
const {
return rep->sizeOfDimension(i); }
403 long nativeDimension(
long i)
const {
return rep->nativeDimension(i); }
404 long coordinate(
long i,
long k)
const {
return rep->coordinate(i, k); }
443 virtual void rotate(
long k) = 0;
446 virtual void shift(
long k) = 0;
449 virtual void encode(
const vector< long >& array) = 0;
450 virtual void encode(
const vector< ZZX >& array) = 0;
451 virtual void decode(vector< long >& array)
const = 0;
452 virtual void decode(vector< ZZX >& array)
const = 0;
455 virtual void encode(
long val) = 0;
456 virtual void encode(
const ZZX& val) = 0;
459 virtual void random() = 0;
463 virtual bool equals(
const vector<long>& other)
const = 0;
464 virtual bool equals(
const vector<ZZX>& other)
const = 0;
470 virtual void negate() = 0;
476 virtual void print(ostream& s)
const = 0;
505 tab( ea.getContext().alMod.getDerived(type()) ),
506 G( ea.getDerived(type()).getG() )
508 RBak bak; bak.save(); tab.restoreContext();
516 : ea(other.ea), tab(other.tab), G(other.G), degG(other.degG), n(other.n)
518 RBak bak; bak.save(); tab.restoreContext();
525 if (
this == &other)
return *
this;
526 assert(&ea == &other.ea);
527 RBak bak; bak.save(); tab.restoreContext();
534 RBak bak; bak.save(); tab.restoreContext();
538 for (
long i = 0; i < n; i++)
539 tmp[((i+k)%n + n)%n] = data[i];
546 RBak bak; bak.save(); tab.restoreContext();
548 for (
long i = 0; i < n; i++)
549 if (i + k >= n || i + k < 0)
555 virtual void encode(
const vector< long >& array)
557 assert(
lsize(array) == n);
558 RBak bak; bak.save(); tab.restoreContext();
559 convert(data, array);
562 virtual void encode(
const vector< ZZX >& array)
564 assert(
lsize(array) == n);
565 RBak bak; bak.save(); tab.restoreContext();
566 convert(data, array);
567 for (
long i = 0; i <
lsize(array); i++) assert(deg(data[i]) < degG);
570 virtual void decode(vector< long >& array)
const
572 RBak bak; bak.save(); tab.restoreContext();
573 convert(array, data);
576 virtual void decode(vector< ZZX >& array)
const
578 RBak bak; bak.save(); tab.restoreContext();
579 convert(array, data);
586 for (
long i = 0; i < n; i++) array[i] = val;
590 virtual void encode(
const ZZX& val)
594 for (
long i = 0; i < n; i++) array[i] = val;
600 RBak bak; bak.save(); tab.restoreContext();
601 for (
long i = 0; i < n; i++)
602 NTL::random(data[i], degG);
607 RBak bak; bak.save(); tab.restoreContext();
610 assert(&ea == &other1.ea);
612 return data == other1.data;
615 virtual bool equals(
const vector<long>& other)
const
617 RBak bak; bak.save(); tab.restoreContext();
623 virtual bool equals(
const vector<ZZX>& other)
const
625 RBak bak; bak.save(); tab.restoreContext();
633 RBak bak; bak.save(); tab.restoreContext();
637 assert(&ea == &other1.ea);
639 for (
long i = 0; i < n; i++)
640 data[i] += other1.data[i];
645 RBak bak; bak.save(); tab.restoreContext();
649 assert(&ea == &other1.ea);
651 for (
long i = 0; i < n; i++)
652 data[i] -= other1.data[i];
658 RBak bak; bak.save(); tab.restoreContext();
662 assert(&ea == &other1.ea);
664 for (
long i = 0; i < n; i++)
665 MulMod(data[i], data[i], other1.data[i], G);
669 virtual void negate()
671 RBak bak; bak.save(); tab.restoreContext();
672 for (
long i = 0; i < n; i++)
673 NTL::negate(data[i], data[i]);
678 RBak bak; bak.save(); tab.restoreContext();
680 assert(i >= 0 && i < n);
681 for (
long j = 0; j < n; j++) {
682 if (j != i) data[j] = data[i];
686 virtual void print(ostream& s)
const
692 for (
long i = 1; i <
lsize(data); i++)
702 const vector<RX>& getData()
const {
return data; }
704 void setData(
const vector<RX>& _data)
706 assert(
lsize(_data) == n);
723 cloned_ptr<PlaintextArrayBase> rep;
728 : rep(buildPlaintextArray(ea))
757 void shift(
long k) { rep->shift(k); }
760 void encode(
const vector< long >& array) { rep->encode(array); }
761 void encode(
const vector< ZZX >& array) { rep->encode(array); }
762 void decode(vector< long >& array) { rep->decode(array); }
763 void decode(vector< ZZX >& array) { rep->decode(array); }
766 void encode(
long val) { rep->encode(val); }
767 void encode(
const ZZX& val) { rep->encode(val); }
774 bool equals(
const vector<long>& other)
const {
return rep->equals(other); }
775 bool equals(
const vector<ZZX>& other)
const {
return rep->equals(other); }
780 void negate() { rep->negate(); }
785 void print(ostream& s)
const { rep->print(s); }