PALISADE Lattice Crypto Library  1.11.9
A lattice crypto library for software engineers by software engineers.
ildcrtparams.h
1 // @file ildcrtparams.h Wraps parameters for integer lattice operations using
2 // double-CRT representation. Inherits from ElemParams.
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 #ifndef LBCRYPTO_LATTICE_ILDCRTELEMENT_H
26 #define LBCRYPTO_LATTICE_ILDCRTELEMENT_H
27 
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 #include "lattice/elemparams.h"
33 #include "lattice/ilparams.h"
34 #include "math/backend.h"
35 #include "math/nbtheory.h"
36 #include "utils/inttypes.h"
37 
38 namespace lbcrypto {
39 
52 template <typename IntType>
53 class ILDCRTParams : public ElemParams<IntType> {
54  public:
55  static const usint DEFAULT_NBITS = 20;
56 
57  typedef IntType Integer;
58  using ILNativeParams = ILParamsImpl<NativeInteger>;
59 
67  explicit ILDCRTParams(usint order = 0, usint depth = 1,
68  usint bits = DEFAULT_NBITS);
69 
77  ILDCRTParams(const usint cyclotomic_order, const IntType &modulus,
78  const IntType &rootOfUnity)
79  : ElemParams<IntType>(cyclotomic_order, modulus, 0, 0, 0) {
80  // NOTE parms generation uses this constructor to make an empty parms that
81  // it will later populate during the gen process. For that special case...
82  // we don't populate, and we just return
83 
84  if (cyclotomic_order == 0) return;
85 
86  DEBUG_FLAG(false);
87  DEBUG(
88  "in ILDCRTParams(const usint cyclotomic_order, const IntType &modulus, "
89  "const IntType& rootOfUnity");
90  DEBUGEXP(cyclotomic_order);
91  DEBUGEXP(modulus);
92  DEBUGEXP(rootOfUnity);
93  usint numOfTower = 1;
94  std::vector<NativeInteger> moduli;
95  std::vector<NativeInteger> rootsOfUnity;
96 
97  NativeInteger q =
98  FirstPrime<NativeInteger>(DEFAULT_NBITS, cyclotomic_order);
99  IntType compositeModulus(1);
100 
101  for (;;) {
102  moduli.push_back(q);
103  rootsOfUnity.push_back(RootOfUnity(cyclotomic_order, q));
104  compositeModulus = compositeModulus * IntType(q.ConvertToInt());
105  if (compositeModulus >= modulus) break;
106 
107  q = NextPrime(q, cyclotomic_order);
108  numOfTower++;
109  }
110  originalModulus = modulus;
111  DEBUGEXP(compositeModulus);
112  DEBUGEXP(moduli);
113  DEBUGEXP(rootsOfUnity);
114  DEBUGEXP(m_parms.size());
115  for (size_t i = 0; i < moduli.size(); i++) {
116  m_parms.push_back(std::make_shared<ILNativeParams>(
117  cyclotomic_order, moduli[i], rootsOfUnity[i]));
118  }
119 
121  DEBUGEXP(m_parms.size());
122  }
123 
136  ILDCRTParams(const usint cyclotomic_order,
137  const std::vector<NativeInteger> &moduli,
138  const std::vector<NativeInteger> &rootsOfUnity,
139  const std::vector<NativeInteger> &moduliBig = {},
140  const std::vector<NativeInteger> &rootsOfUnityBig = {},
141  const IntType &inputOriginalModulus = IntType(0))
142  : ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0) {
143  this->originalModulus = inputOriginalModulus;
144  if (moduli.size() != rootsOfUnity.size()) {
145  PALISADE_THROW(math_error,
146  "sizes of moduli and roots of unity do not match");
147  }
148 
149  if (moduliBig.size() == moduli.size()) {
150  for (size_t i = 0; i < moduli.size(); i++) {
151  m_parms.push_back(std::make_shared<ILNativeParams>(
152  cyclotomic_order, moduli[i], rootsOfUnity[i], moduliBig[i],
153  rootsOfUnityBig[i]));
154  }
156  } else {
157  for (size_t i = 0; i < moduli.size(); i++) {
158  m_parms.push_back(std::make_shared<ILNativeParams>(
159  cyclotomic_order, moduli[i], rootsOfUnity[i]));
160  }
161  }
163  }
164 
173  ILDCRTParams(const usint cyclotomic_order,
174  const std::vector<NativeInteger> &moduli,
175  const IntType &inputOriginalModulus = IntType(0))
176  : ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0) {
177  this->originalModulus = inputOriginalModulus;
178 
179  for (size_t i = 0; i < moduli.size(); i++) {
180  m_parms.push_back(std::make_shared<ILNativeParams>(cyclotomic_order,
181  moduli[i], 0, 0, 0));
182  }
184  }
185 
194  ILDCRTParams(const usint cyclotomic_order,
195  std::vector<std::shared_ptr<ILNativeParams>> &parms,
196  const IntType &inputOriginalModulus = IntType(0))
197  : ElemParams<IntType>(cyclotomic_order, 0, 0, 0, 0), m_parms(parms) {
198  this->originalModulus = inputOriginalModulus;
199 
201  }
202 
209  const ILDCRTParams &operator=(const ILDCRTParams &rhs) {
211  originalModulus = rhs.originalModulus;
212 
213  m_parms = rhs.m_parms;
214 
215  return *this;
216  }
217 
218  // ACCESSORS
223  const std::vector<std::shared_ptr<ILNativeParams>> &GetParams() const {
224  return m_parms;
225  }
226 
234  std::vector<std::shared_ptr<ILNativeParams>> GetParamPartition(
235  uint32_t start, uint32_t end) const {
236  if (end < start || end > this->GetParams().size()) {
237  PALISADE_THROW(math_error,
238  "Incorrect parameters for GetParamPartition - (start: " +
239  std::to_string(start) +
240  ", end:" + std::to_string(end) + ")");
241  }
242 
243  std::vector<std::shared_ptr<ILNativeParams>> resParams =
244  std::vector<std::shared_ptr<ILNativeParams>>(end - start + 1);
245 
246  IntType q = IntType(1);
247  for (uint32_t i = 0; i <= (end - start); i++) {
248  resParams[i] = this->GetParams()[i + start];
249  q = q.Mul(IntType(this->GetParams()[i + start]->GetModulus()));
250  }
251 
252  return resParams;
253  }
254 
260  const IntType &GetOriginalModulus() const { return originalModulus; }
266  void SetOriginalModulus(const IntType &inputOriginalModulus) {
267  originalModulus = inputOriginalModulus;
268  }
275  std::shared_ptr<ILNativeParams> &operator[](const usint i) {
276  return m_parms[i];
277  }
278 
283  void PopLastParam() {
284  this->ciphertextModulus /=
285  IntType(m_parms.back()->GetModulus().ConvertToInt());
286  m_parms.pop_back();
287  }
288 
293 
300  bool operator==(const ElemParams<IntType> &other) const {
301  const auto *dcrtParams = dynamic_cast<const ILDCRTParams *>(&other);
302 
303  if (dcrtParams == nullptr) return false;
304 
305  if (ElemParams<IntType>::operator==(other) == false) return false;
306 
307  if (m_parms.size() != dcrtParams->m_parms.size()) return false;
308 
309  for (size_t i = 0; i < m_parms.size(); i++) {
310  if (*m_parms[i] != *dcrtParams->m_parms[i]) return false;
311  }
312 
313  // if (originalModulus != dcrtParams->originalModulus)
314  // return false;
315 
316  return true;
317  }
318 
324  this->ciphertextModulus = 1;
325 
326  for (usint i = 0; i < m_parms.size(); i++) {
327  this->ciphertextModulus =
328  this->ciphertextModulus *
329  IntType(m_parms[i]->GetModulus().ConvertToInt());
330  }
331  }
332 
338  this->bigCiphertextModulus = 1;
339 
340  for (usint i = 0; i < m_parms.size(); i++) {
341  this->bigCiphertextModulus =
342  this->bigCiphertextModulus *
343  IntType(m_parms[i]->GetBigModulus().ConvertToInt());
344  }
345  }
346 
347  template <class Archive>
348  void save(Archive &ar, std::uint32_t const version) const {
349  ar(::cereal::base_class<ElemParams<IntType>>(this));
350  ar(::cereal::make_nvp("p", m_parms));
351  ar(::cereal::make_nvp("m", originalModulus));
352  }
353 
354  template <class Archive>
355  void load(Archive &ar, std::uint32_t const version) {
356  if (version > SerializedVersion()) {
357  PALISADE_THROW(deserialize_error,
358  "serialized object version " + std::to_string(version) +
359  " is from a later version of the library");
360  }
361  ar(::cereal::base_class<ElemParams<IntType>>(this));
362  ar(::cereal::make_nvp("p", m_parms));
363  ar(::cereal::make_nvp("m", originalModulus));
364  }
365 
366  std::string SerializedObjectName() const { return "DCRTParams"; }
367  static uint32_t SerializedVersion() { return 1; }
368 
369  private:
370  std::ostream &doprint(std::ostream &out) const {
371  out << "ILDCRTParams ";
373  out << std::endl << " Parms:" << std::endl;
374  for (size_t i = 0; i < m_parms.size(); i++) {
375  out << " " << i << ":" << *m_parms[i] << std::endl;
376  }
377  out << "OriginalModulus " << originalModulus << std::endl;
378  return out;
379  }
380 
381  // array of smaller ILParams
382  std::vector<std::shared_ptr<ILNativeParams>> m_parms;
383 
384  // original modulus when being constructed from a Poly or when
385  // ctor is passed that parameter
386  // note orignalModulus will be <= composite modules
387  // i.e. \Prod_i=0^k-1 m_params[i]->GetModulus()
388  // note not using ElemParams::ciphertextModulus due to object stripping
389  Integer originalModulus;
390 };
391 
392 } // namespace lbcrypto
393 
394 #endif
bool operator==(const ElemParams< IntType > &other) const
Equality operator checks if the ElemParams are the same.
Definition: ildcrtparams.h:300
void SetOriginalModulus(const IntType &inputOriginalModulus)
Simple setter method for the original modulus, not the ciphertex modulus.
Definition: ildcrtparams.h:266
void RecalculateModulus()
Method to recalculate the composite modulus from the component moduli.
Definition: ildcrtparams.h:323
Definition: elemparams.h:43
ILDCRTParams(const usint cyclotomic_order, const std::vector< NativeInteger > &moduli, const std::vector< NativeInteger > &rootsOfUnity, const std::vector< NativeInteger > &moduliBig={}, const std::vector< NativeInteger > &rootsOfUnityBig={}, const IntType &inputOriginalModulus=IntType(0))
Constructor with some pre-computed parameters provided as input.
Definition: ildcrtparams.h:136
const ElemParams & operator=(const ElemParams &rhs)
Assignment operator using assignment operations of wrapped elements.
Definition: elemparams.h:103
std::shared_ptr< ILNativeParams > & operator[](const usint i)
Getter method for the component parameters of a specific index.
Definition: ildcrtparams.h:275
Definition: exception.h:147
Definition: exception.h:113
IntType NextPrime(const IntType &q, uint64_t cyclotomicOrder)
Definition: nbtheory.cpp:537
ILDCRTParams(const usint cyclotomic_order, std::vector< std::shared_ptr< ILNativeParams >> &parms, const IntType &inputOriginalModulus=IntType(0))
Constructor that takes in the cyclotomic order and the component parameters of the component moduli...
Definition: ildcrtparams.h:194
Wrapper class to hold the parameters for Element types and their inheritors.
const IntType & GetModulus() const
Simple getter method for the ciphertext modulus, not the big ciphertext modulus.
Definition: elemparams.h:146
~ILDCRTParams()
Definition: ildcrtparams.h:292
const std::vector< std::shared_ptr< ILNativeParams > > & GetParams() const
Getter method for the component parameters.
Definition: ildcrtparams.h:223
virtual std::ostream & doprint(std::ostream &out) const
Pretty print operator for the ElemParams type.
Definition: elemparams.h:246
void PopLastParam()
Removes the last parameter set and adjust the multiplied moduli.
Definition: ildcrtparams.h:283
const IntType & GetBigModulus() const
Simpler getter method for the big ciphertext modulus. This is not relevant for all applications...
Definition: elemparams.h:153
OutputType ConvertToInt() const
Definition: ubintnat.h:1886
const IntType & GetOriginalModulus() const
Simple getter method for the original modulus, not the ciphertex modulus.
Definition: ildcrtparams.h:260
std::vector< std::shared_ptr< ILNativeParams > > GetParamPartition(uint32_t start, uint32_t end) const
Getter method that returns a subset of the component parameters.
Definition: ildcrtparams.h:234
ILDCRTParams(const usint cyclotomic_order, const std::vector< NativeInteger > &moduli, const IntType &inputOriginalModulus=IntType(0))
Constructor with only cylotomic order and chain of moduli. Multiplied values of the chain of moduli i...
Definition: ildcrtparams.h:173
ILDCRTParams(const usint cyclotomic_order, const IntType &modulus, const IntType &rootOfUnity)
Constructor with basic parameters.
Definition: ildcrtparams.h:77
void RecalculateBigModulus()
Method to recalculate the big composite modulus from the component moduli.
Definition: ildcrtparams.h:337
IntType RootOfUnity(usint m, const IntType &modulo)
Definition: nbtheory.cpp:270
Definition: binfhecontext.h:36
Wrapper class to hold the parameters for integer lattice operations and their inheritors.
ILDCRTParams(usint order=0, usint depth=1, usint bits=DEFAULT_NBITS)
Constructor with basic parameter set. q is selected as FirstPrime(bits, order)
Definition: ildcrtparams.cpp:29
Main class for big integers represented as an array of native (primitive) unsigned integers...
Definition: backend.h:60
Parameters for array of ideal lattices (used for Double-CRT).
Definition: backend.h:71
const ILDCRTParams & operator=(const ILDCRTParams &rhs)
Definition: ildcrtparams.h:209