PALISADE Lattice Crypto Library  1.11.9
A lattice crypto library for software engineers by software engineers.
mubintvecntl.h
1 // @file mubintvecntl.h This file contains mgmpintvec, a <vector> of gmpint,
2 // with associated math operators
3 // @author TPOC: contact@palisade-crypto.org
4 //
5 // @copyright Copyright (c) 2019, New Jersey Institute of Technology (NJIT)
6 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 // 1. Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution. THIS SOFTWARE IS
14 // PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 /*
25  * This file contains mgmpintvec, a <vector> of gmpint, with associated
26  * math operators.
27  * NOTE: this has been refactored so that implied modulo (ring)
28  * aritmetic is in mbintvec
29  *
30  */
31 
32 #ifndef LBCRYPTO_MATH_BIGINTNTL_MUBINTVECNTL_H
33 #define LBCRYPTO_MATH_BIGINTNTL_MUBINTVECNTL_H
34 
35 #include "config_core.h"
36 #ifdef WITH_NTL
37 
38 #include <NTL/SmartPtr.h>
39 #include <NTL/vec_ZZ.h>
40 #include <NTL/vector.h>
41 
42 #include <initializer_list>
43 #include <iostream>
44 #include <string>
45 #include <vector>
46 
47 #include "math/bigintntl/ubintntl.h"
48 #include "utils/exception.h"
49 #include "utils/inttypes.h"
50 #include "utils/serializable.h"
51 
52 // defining this forces modulo when you write to the vector (except with at())
53 // this is becuase NTL required inputs to modmath to be < modulus but BU does
54 // not play with this and you will see different tests in pke pass and fail.
55 // I think this will go away soon
56 // #define FORCE_NORMALIZATION
57 
58 // defining this enables a run time warning when a vector with uninitialized
59 // modulus is used in math operations (A very bad thing)
60 // #define WARN_BAD_MODULUS
61 
66 namespace NTL {
72 template <typename myT>
73 class myVecP : public NTL::Vec<myT>,
74  public lbcrypto::BigVectorInterface<myVecP<myT>, myT>,
75  public lbcrypto::Serializable {
76  public:
77  // CONSTRUCTORS
78 
79  myVecP() : Vec<myT>() { m_modulus_state = GARBAGE; }
80 
81  static inline myVecP Single(const myT &val, const myT &modulus) {
82  myVecP vec(1);
83  vec.SetModulus(modulus);
84  vec[0] = val;
85  return vec;
86  }
87 
88  explicit myVecP(const size_t length) : Vec<myT>(INIT_SIZE, length) {
89  m_modulus_state = GARBAGE;
90  }
91 
92  myVecP(INIT_SIZE_TYPE, const long length) : Vec<myT>(INIT_SIZE, length) {
93  m_modulus_state = GARBAGE;
94  }
95 
96  explicit myVecP(const myVecP<myT> &a);
97 
98  myVecP(myVecP<myT> &&a);
99 
100  myVecP(const long n, const myT &q);
101 
102  myVecP(const long n, const myT &q, std::initializer_list<std::string> rhs);
103  myVecP(const long n, const myT &q, std::initializer_list<uint64_t> rhs);
104 
105  myVecP(const myVecP<myT> &a, const myT &q);
106 
107  myVecP(size_t n, const std::string &sq);
108 
109  myVecP(const myVecP<myT> &a, const std::string &sq);
110 
111  myVecP(size_t n, uint64_t q);
112 
113  myVecP(const myVecP<myT> &a, const uint64_t q);
114 
115  explicit myVecP(std::vector<std::string> &s); // without modulus
116  myVecP(std::vector<std::string> &s, const myT &q); // with modulus
117  myVecP(std::vector<std::string> &s, const char *sq); // with modulus
118  myVecP(std::vector<std::string> &s, const uint64_t q); // with modulusu
119 
120  void clear(myVecP &x); // why isn't this inhereted?
121 
122  ~myVecP() {}
123 
124  // ASSIGNMENT OPERATORS
125 
126  const myVecP &operator=(const myVecP &a);
127  const myVecP &operator=(myVecP &&a);
128 
129  const myVecP &operator=(std::initializer_list<uint64_t> rhs);
130  const myVecP &operator=(std::initializer_list<int32_t> rhs);
131  const myVecP &operator=(std::initializer_list<std::string> rhs);
132  const myVecP &operator=(uint64_t rhs);
133 
134  // ACCESSORS
135 
136  // NOTE the underlying Vec does not have a no-bounds-checking operator[]
137  myT &at(size_t i) { return this->NTL::Vec<myT>::at(i); }
138 
139  const myT &at(size_t i) const { return this->NTL::Vec<myT>::at(i); }
140 
141  myT &operator[](size_t idx) { return this->at(idx); }
142 
143  const myT &operator[](size_t idx) const { return this->at(idx); }
144 
145  inline void push_back(const myT &a) { this->append(a); }
146 
147  void SwitchModulus(const myT &newModulus);
148 
149  // public modulus accessors
150  inline bool isModulusSet(void) const {
151  return (this->m_modulus_state == INITIALIZED);
152  }
153 
154  // return true if both myVecP have same modulus
155  inline bool SameModulus(const myVecP &a) const {
156  return ((this->m_modulus_state == a.m_modulus_state) &&
157  (this->m_modulus == a.m_modulus));
158  }
159 
160  // sets modulus and the NTL init function uint64_t argument
161  inline void SetModulus(const uint64_t &value) {
162  if (value == 0) {
163  PALISADE_THROW(lbcrypto::math_error,
164  "SetModulus(uint64_t) cannot be zero");
165  }
166  this->m_modulus = myT(value);
167  this->m_modulus_state = INITIALIZED;
168  }
169 
170  // sets modulus and the NTL init function myT argument
171  void SetModulus(const myT &value) {
172  if (value == myT(0)) {
173  PALISADE_THROW(lbcrypto::math_error, "SetModulus(myT) cannot be zero");
174  }
175  this->m_modulus = value;
176  this->m_modulus_state = INITIALIZED;
177  }
178 
179  // sets modulus and the NTL init function string argument
180  inline void SetModulus(const std::string &value) {
181  this->m_modulus = myT(value);
182  if (this->m_modulus == myT(0)) {
183  PALISADE_THROW(lbcrypto::math_error, "SetModulus(string) cannot be zero");
184  }
185  this->m_modulus_state = INITIALIZED;
186  }
187 
188  // sets modulus and the NTL init function uses same modulus
189  inline void SetModulus(const myVecP &value) {
190  this->m_modulus = value.GetModulus();
191  if (this->m_modulus == myT(0)) {
192  PALISADE_THROW(lbcrypto::math_error, "SetModulus(myVecP) cannot be zero");
193  }
194  this->m_modulus_state = INITIALIZED;
195  }
196 
197  const myT &GetModulus() const {
198  if (this->isModulusSet()) {
199  return (this->m_modulus);
200  } else {
201  PALISADE_THROW(lbcrypto::config_error, "modulus not set");
202  }
203  }
204 
205  inline int CopyModulus(const myVecP &rhs) {
206  this->m_modulus = rhs.m_modulus;
207  this->m_modulus_state = rhs.m_modulus_state;
208  if (isModulusSet()) {
209  return (0);
210  } else {
211  this->m_modulus_state = GARBAGE;
212  return (-1);
213  }
214  }
215 
216  size_t GetLength(void) const { return this->length(); }
217 
218  void resize(size_t n) {
219  // resize is the STL::vector standard call for this functionality
220  this->SetLength(n); // SetLength() is an NTL call
221  }
222 
223  // MODULUS ARITHMETIC OPERATIONS
224 
231  myVecP Mod(const myT &b) const;
232 
239  const myVecP &ModEq(const myT &b);
240 
247  myVecP ModAdd(const myT &b) const {
248  ModulusCheck("Warning: myVecP::ModAdd");
249  myVecP ans(*this);
250  ans.ModAddEq(b);
251  return ans;
252  }
253 
260  const myVecP &ModAddEq(const myT &b) {
261  ModulusCheck("Warning: myVecP::ModAdd");
262  for (usint i = 0; i < this->GetLength(); i++) {
263  this->operator[](i).ModAddEq(b, this->m_modulus);
264  }
265  return *this;
266  }
267 
275  myVecP ModAddAtIndex(size_t i, const myT &b) const;
276 
284  const myVecP &ModAddAtIndexEq(size_t i, const myT &b);
285 
292  myVecP ModAdd(const myVecP &b) const {
293  ArgCheckVector(b, "myVecP ModAdd()");
294  myVecP ans(*this);
295  ans.ModAddEq(b);
296  return ans;
297  }
298 
305  const myVecP &ModAddEq(const myVecP &b) {
306  ArgCheckVector(b, "myVecP ModAddEq()");
307  for (usint i = 0; i < this->GetLength(); i++) {
308  this->operator[](i).ModAddEq(b[i], this->m_modulus);
309  }
310  return *this;
311  }
312 
315  void modadd_p(myVecP &x, const myVecP &a, const myVecP &b) const;
316 
323  myVecP ModSub(const myT &b) const {
324  ModulusCheck("Warning: myVecP::ModSub");
325  myVecP ans(*this);
326  ans.ModSubEq(b);
327  return ans;
328  }
329 
336  const myVecP &ModSubEq(const myT &b) {
337  ModulusCheck("Warning: myVecP::ModSubEq");
338  for (usint i = 0; i < this->GetLength(); i++) {
339  this->operator[](i).ModSubEq(b, this->m_modulus);
340  }
341  return (*this);
342  }
343 
350  myVecP ModSub(const myVecP &b) const {
351  ArgCheckVector(b, "myVecP ModSub()");
352  myVecP ans(*this);
353  ans.ModSubEq(b);
354  return ans;
355  }
356 
363  const myVecP &ModSubEq(const myVecP &b) {
364  ArgCheckVector(b, "myVecP ModSubEq()");
365  for (usint i = 0; i < this->GetLength(); i++) {
366  this->operator[](i).ModSubEq(b[i], this->m_modulus);
367  }
368  return (*this);
369  }
370 
373  void modsub_p(myVecP &x, const myVecP &a, const myVecP &b) const;
374 
381  myVecP ModMul(const myT &b) const {
382  ModulusCheck("Warning: myVecP::ModMul");
383  myVecP ans(*this);
384  ans.ModMulEq(b);
385  return ans;
386  }
387 
394  const myVecP &ModMulEq(const myT &b) {
395  ModulusCheck("Warning: myVecP::ModMul");
396  for (usint i = 0; i < this->GetLength(); i++) {
397  this->operator[](i).ModMulEq(b, this->m_modulus);
398  }
399  return (*this);
400  }
401 
409  myVecP ModMul(const myVecP &b) const {
410  ArgCheckVector(b, "myVecP Mul()");
411  myVecP ans(*this);
412  ans.ModMulEq(b);
413  return ans;
414  }
415 
423  const myVecP &ModMulEq(const myVecP &b) {
424  ArgCheckVector(b, "myVecP Mul()");
425  for (usint i = 0; i < this->GetLength(); i++) {
426  this->operator[](i).ModMulEq(b[i], this->m_modulus);
427  }
428  return (*this);
429  }
430 
433  void modmul_p(myVecP &x, const myVecP &a, const myVecP &b) const;
434 
441  myVecP ModExp(const myT &b) const;
442 
449  const myVecP &ModExpEq(const myT &b);
450 
456  myVecP ModInverse() const;
457 
463  const myVecP &ModInverseEq();
464 
471  myVecP ModByTwo() const;
472 
479  const myVecP &ModByTwoEq();
480 
489  myVecP MultiplyAndRound(const myT &p, const myT &q) const;
490 
499  const myVecP &MultiplyAndRoundEq(const myT &p, const myT &q);
500 
508  myVecP DivideAndRound(const myT &q) const;
509 
517  const myVecP &DivideAndRoundEq(const myT &q);
518 
519  // OTHER FUNCTIONS
520 
538  myVecP GetDigitAtIndexForBase(size_t index, usint base) const;
539 
540  // STRINGS & STREAMS
541 
549  friend std::ostream &operator<<(std::ostream &os,
550  const myVecP<myT> &ptr_obj) {
551  auto len = ptr_obj.GetLength();
552  os << "[";
553  for (size_t i = 0; i < len; i++) {
554  os << ptr_obj.at(i);
555  os << ((i == (len - 1)) ? "]" : " ");
556  }
557  os << " modulus: " << ptr_obj.m_modulus;
558  return os;
559  }
560 
561  // SERIALIZATION
562 
563  template <class Archive>
564  typename std::enable_if<!cereal::traits::is_text_archive<Archive>::value,
565  void>::type
566  save(Archive &ar, std::uint32_t const version) const {
567  // YSP. This was seg-faulting in MINGW
568  // ar( m_modulus.ToString() );
569  // ar( m_modulus_state );
570  // ar( this->GetLength() );
571  // for(size_t i=0; i<this->GetLength(); i++ )
572  // ar( (*this)[i] );
573  ar(::cereal::make_nvp("m", m_modulus.ToString()));
574  ar(::cereal::make_nvp("ms", m_modulus_state));
575  ar(::cereal::make_nvp("l", this->GetLength()));
576  for (size_t i = 0; i < this->GetLength(); i++) {
577  ar(::cereal::make_nvp("v", (*this)[i].ToString()));
578  }
579  }
580 
581  template <class Archive>
582  typename std::enable_if<cereal::traits::is_text_archive<Archive>::value,
583  void>::type
584  save(Archive &ar, std::uint32_t const version) const {
585  ar(::cereal::make_nvp("m", m_modulus.ToString()));
586  ar(::cereal::make_nvp("ms", m_modulus_state));
587  ar(::cereal::make_nvp("l", this->GetLength()));
588  for (size_t i = 0; i < this->GetLength(); i++) {
589  ar(::cereal::make_nvp("v", (*this)[i].ToString()));
590  }
591  }
592 
593  template <class Archive>
594  typename std::enable_if<!cereal::traits::is_text_archive<Archive>::value,
595  void>::type
596  load(Archive &ar, std::uint32_t const version) {
597  if (version > SerializedVersion()) {
598  PALISADE_THROW(lbcrypto::deserialize_error,
599  "serialized object version " + std::to_string(version) +
600  " is from a later version of the library");
601  }
602  // YSP. This was seg-faulting in MINGW
603  // std::string m;
604  // ar( m );
605  // m_modulus = m;
606  // ar( m_modulus_state );
607  // cereal::size_type len;
608  // ar( len );
609  // this->SetLength(len);
610  // for(size_t i=0; i<len; i++ )
611  // ar( (*this)[i] );
612 
613  std::string m;
614  ar(::cereal::make_nvp("m", m));
615  m_modulus = m;
616  ar(::cereal::make_nvp("ms", m_modulus_state));
617  cereal::size_type len;
618  ar(::cereal::make_nvp("l", len));
619  this->resize(len);
620  for (size_t i = 0; i < len; i++) {
621  std::string s;
622  ar(::cereal::make_nvp("v", s));
623  (*this)[i] = s;
624  }
625  }
626 
627  template <class Archive>
628  typename std::enable_if<cereal::traits::is_text_archive<Archive>::value,
629  void>::type
630  load(Archive &ar, std::uint32_t const version) {
631  if (version > SerializedVersion()) {
632  PALISADE_THROW(lbcrypto::deserialize_error,
633  "serialized object version " + std::to_string(version) +
634  " is from a later version of the library");
635  }
636  std::string m;
637  ar(::cereal::make_nvp("m", m));
638  m_modulus = m;
639  ar(::cereal::make_nvp("ms", m_modulus_state));
640  cereal::size_type len;
641  ar(::cereal::make_nvp("l", len));
642  this->resize(len);
643  for (size_t i = 0; i < len; i++) {
644  std::string s;
645  ar(::cereal::make_nvp("v", s));
646  (*this)[i] = s;
647  }
648  }
649 
650  std::string SerializedObjectName() const { return "NTLVector"; }
651 
652  static uint32_t SerializedVersion() { return 1; }
653 
654  private:
655  // utility function to warn if modulus is no good
656  // use when argument to function is myT
657  void ModulusCheck(std::string msg) const {
658  if (!isModulusSet()) {
659  PALISADE_THROW(lbcrypto::config_error,
660  msg + " uninitialized this->modulus");
661  }
662  }
663 
664  // utility function to check argument consistency for vector vector fns
665  // use when argument to function is myVecP
666  void ArgCheckVector(const myVecP &b, std::string fname) const {
667  if (this->m_modulus != b.m_modulus) {
668  PALISADE_THROW(
670  fname + " modulus vector modulus vector op of different moduli");
671  } else if (!isModulusSet()) {
672  PALISADE_THROW(
674  fname + " modulus vector modulus vector op GARBAGE moduli");
675  } else if (this->GetLength() != b.GetLength()) {
676  PALISADE_THROW(lbcrypto::math_error,
677  fname + " vectors of different lengths");
678  }
679  }
680 
681  // used to make sure all entries in this are <=current modulus
682  void Renormalize(void) {
683  for (size_t i = 0; i < this->GetLength(); ++i) {
684  (*this)[i] %= m_modulus;
685  }
686  }
687 
688  myT m_modulus;
689  // TODO: BE 2 has gotten rid of this, we may too.
690  enum ModulusState {
691  GARBAGE,
692  INITIALIZED // note different order, GARBAGE is the default
693  // state
694  };
695  // enum to store the state of the
696  ModulusState m_modulus_state;
697 
698  protected:
699  bool IndexCheck(size_t index) const {
700  if (index >= this->GetLength()) {
701  return false;
702  }
703  return true;
704  }
705 };
706 // template class ends
707 
708 } // namespace NTL
709 
710 #endif
711 
712 #endif // LBCRYPTO_MATH_BIGINTNTL_MUBINTVECNTL_H
myVecP ModExp(const myT &b) const
Definition: mubintvecntl.cpp:492
const myVecP & ModSubEq(const myVecP &b)
Definition: mubintvecntl.h:363
myVecP MultiplyAndRound(const myT &p, const myT &q) const
Definition: mubintvecntl.cpp:559
Base class for PALISADE serialization.
Definition: serializable.h:76
void modadd_p(myVecP &x, const myVecP &a, const myVecP &b) const
Definition: mubintvecntl.cpp:437
The class for representing vectors of ubint with associated modulo math.
Definition: mubintvecntl.h:73
const myVecP & ModAddEq(const myT &b)
Definition: mubintvecntl.h:260
void modmul_p(myVecP &x, const myVecP &a, const myVecP &b) const
Definition: mubintvecntl.cpp:474
const myVecP & ModByTwoEq()
Definition: mubintvecntl.cpp:538
myVecP ModSub(const myT &b) const
Definition: mubintvecntl.h:323
const myVecP & ModInverseEq()
Definition: mubintvecntl.cpp:521
void modsub_p(myVecP &x, const myVecP &a, const myVecP &b) const
Definition: mubintvecntl.cpp:457
Definition: interface.h:588
const myVecP & DivideAndRoundEq(const myT &q)
Definition: mubintvecntl.cpp:606
const myVecP & ModMulEq(const myT &b)
Definition: mubintvecntl.h:394
Definition: exception.h:147
myVecP ModAdd(const myVecP &b) const
Definition: mubintvecntl.h:292
Definition: exception.h:113
const myVecP & ModAddEq(const myVecP &b)
Definition: mubintvecntl.h:305
friend std::ostream & operator<<(std::ostream &os, const myVecP< myT > &ptr_obj)
Definition: mubintvecntl.h:549
myVecP Mod(const myT &b) const
Definition: mubintvecntl.cpp:372
myVecP ModAdd(const myT &b) const
Definition: mubintvecntl.h:247
const myVecP & ModAddAtIndexEq(size_t i, const myT &b)
Definition: mubintvecntl.cpp:423
const myVecP & ModEq(const myT &b)
Definition: mubintvecntl.cpp:391
myVecP ModByTwo() const
Definition: mubintvecntl.cpp:530
const myVecP & ModSubEq(const myT &b)
Definition: mubintvecntl.h:336
myVecP ModMul(const myT &b) const
Definition: mubintvecntl.h:381
const myVecP & ModExpEq(const myT &b)
Definition: mubintvecntl.cpp:502
const myVecP & MultiplyAndRoundEq(const myT &p, const myT &q)
Definition: mubintvecntl.cpp:575
myVecP ModMul(const myVecP &b) const
Definition: mubintvecntl.h:409
const myVecP & ModMulEq(const myVecP &b)
Definition: mubintvecntl.h:423
myVecP ModAddAtIndex(size_t i, const myT &b) const
Definition: mubintvecntl.cpp:410
myVecP GetDigitAtIndexForBase(size_t index, usint base) const
Definition: mubintvecntl.cpp:624
myVecP ModInverse() const
Definition: mubintvecntl.cpp:511
myVecP DivideAndRound(const myT &q) const
Definition: mubintvecntl.cpp:590
myVecP ModSub(const myVecP &b) const
Definition: mubintvecntl.h:350
Definition: exception.h:107