PALISADE Lattice Crypto Library  1.11.9
A lattice crypto library for software engineers by software engineers.
bfvrns.h
1 // @file bfvrns.h -- Operations for the HPS RNS variant of the BFV cryptoscheme.
2 // @author TPOC: contact@palisade-crypto.org
3 //
4 // @copyright Copyright (c) 2019, New Jersey Institute of Technology (NJIT)
5 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution. THIS SOFTWARE IS
13 // PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
14 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16 // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 
24 /*
25  *
26  * This code implements a RNS variant of the Brakerski-Fan-Vercauteren (BFV)
27  *homomorphic encryption scheme. This scheme is also referred to as the FV
28  *scheme.
29  *
30  * The BFV scheme is introduced in the following papers:
31  * - Zvika Brakerski (2012). Fully Homomorphic Encryption without Modulus
32  *Switching from Classical GapSVP. Cryptology ePrint Archive, Report 2012/078.
33  *(https://eprint.iacr.org/2012/078)
34  * - Junfeng Fan and Frederik Vercauteren (2012). Somewhat Practical Fully
35  *Homomorphic Encryption. Cryptology ePrint Archive, Report 2012/144.
36  *(https://eprint.iacr.org/2012/144.pdf)
37  *
38  * Our implementation builds from the designs here:
39  * - Halevi S., Polyakov Y., and Shoup V. An Improved RNS Variant of the BFV
40  *Homomorphic Encryption Scheme. Cryptology ePrint Archive, Report 2018/117.
41  *(https://eprint.iacr.org/2018/117)
42  * - Lepoint T., Naehrig M. (2014) A Comparison of the Homomorphic Encryption
43  *Schemes FV and YASHE. In: Pointcheval D., Vergnaud D. (eds) Progress in
44  *Cryptology – AFRICACRYPT 2014. AFRICACRYPT 2014. Lecture Notes in Computer
45  *Science, vol 8469. Springer, Cham. (https://eprint.iacr.org/2014/062.pdf)
46  * - Jean-Claude Bajard and Julien Eynard and Anwar Hasan and Vincent
47  *Zucca (2016). A Full RNS Variant of FV like Somewhat Homomorphic Encryption
48  *Schemes. Cryptology ePrint Archive, Report 2016/510.
49  *(https://eprint.iacr.org/2016/510)
50  * - Ahmad Al Badawi and Yuriy Polyakov and Khin Mi Mi Aung and Bharadwaj
51  *Veeravalli and Kurt Rohloff (2018). Implementation and Performance Evaluation
52  *of RNS Variants of the BFV Homomorphic Encryption Scheme. Cryptology ePrint
53  *Archive, Report 2018/589. {https://eprint.iacr.org/2018/589}
54  */
55 
56 #ifndef LBCRYPTO_CRYPTO_BFVRNS_H
57 #define LBCRYPTO_CRYPTO_BFVRNS_H
58 
59 #include <memory>
60 #include <string>
61 #include <vector>
62 
63 #include "palisade.h"
64 
65 namespace lbcrypto {
66 
73 template <class Element>
75  using IntType = typename Element::Integer;
76  using ParmType = typename Element::Params;
77  using DggType = typename Element::DggType;
78  using DugType = typename Element::DugType;
79  using TugType = typename Element::TugType;
80 
81  public:
86 
128  LPCryptoParametersBFVrns(shared_ptr<ParmType> params,
129  const PlaintextModulus& plaintextModulus,
130  float distributionParameter, float assuranceMeasure,
131  float securityLevel, usint relinWindow,
132  MODE mode = RLWE, int depth = 1, int maxDepth = 2);
133 
149  LPCryptoParametersBFVrns(shared_ptr<ParmType> params,
150  EncodingParams encodingParams,
151  float distributionParameter, float assuranceMeasure,
152  float securityLevel, usint relinWindow,
153  MODE mode = RLWE, int depth = 1, int maxDepth = 2);
154 
170  LPCryptoParametersBFVrns(shared_ptr<ParmType> params,
171  EncodingParams encodingParams,
172  float distributionParameter, float assuranceMeasure,
173  SecurityLevel securityLevel, usint relinWindow,
174  MODE mode = RLWE, int depth = 1, int maxDepth = 2);
175 
180 
186  bool PrecomputeCRTTables();
187 
194  const shared_ptr<ILDCRTParams<BigInteger>> GetParamsP() const {
195  return m_paramsP;
196  }
197 
204  const shared_ptr<ILDCRTParams<BigInteger>> GetParamsQP() const {
205  return m_paramsQP;
206  }
207 
213  std::vector<double> const& GetqInv() const { return m_qInv; }
214 
220  std::vector<double> const& GetpInv() const { return m_pInv; }
221 
227  std::vector<DoubleNativeInt> const& GetModqBarrettMu() const {
228  return m_modqBarrettMu;
229  }
230 
236  std::vector<DoubleNativeInt> const& GetModpBarrettMu() const {
237  return m_modpBarrettMu;
238  }
239 
245  const std::vector<double>& GettQHatInvModqDivqFrac() const {
246  return m_tQHatInvModqDivqFrac;
247  }
248 
255  const std::vector<double>& GettQHatInvModqBDivqFrac() const {
256  return m_tQHatInvModqBDivqFrac;
257  }
258 
264  const std::vector<NativeInteger>& GettQHatInvModqDivqModt() const {
265  return m_tQHatInvModqDivqModt;
266  }
267 
273  const std::vector<NativeInteger>& GettQHatInvModqDivqModtPrecon() const {
274  return m_tQHatInvModqDivqModtPrecon;
275  }
276 
283  const std::vector<NativeInteger>& GettQHatInvModqBDivqModt() const {
284  return m_tQHatInvModqBDivqModt;
285  }
286 
293  const std::vector<NativeInteger>& GettQHatInvModqBDivqModtPrecon() const {
294  return m_tQHatInvModqBDivqModtPrecon;
295  }
296 
302  const std::vector<NativeInteger>& GetDelta() const { return m_QDivtModq; }
303 
309  const std::vector<NativeInteger>& GetQHatInvModq() const {
310  return m_QHatInvModq;
311  }
312 
318  const std::vector<NativeInteger>& GetQHatInvModqPrecon() const {
319  return m_QHatInvModqPrecon;
320  }
321 
327  const std::vector<std::vector<NativeInteger>>& GetQHatModp() const {
328  return m_QHatModp;
329  }
330 
336  const std::vector<std::vector<NativeInteger>>& GetalphaQModp() const {
337  return m_alphaQModp;
338  }
339 
346  const std::vector<double>& GettPSHatInvModsDivsFrac() const {
347  return m_tPSHatInvModsDivsFrac;
348  }
349 
356  const std::vector<std::vector<NativeInteger>>& GettPSHatInvModsDivsModp()
357  const {
358  return m_tPSHatInvModsDivsModp;
359  }
360 
366  const std::vector<NativeInteger>& GetPHatInvModp() const {
367  return m_PHatInvModp;
368  }
369 
375  const std::vector<NativeInteger>& GetPHatInvModpPrecon() const {
376  return m_PHatInvModpPrecon;
377  }
378 
384  const std::vector<std::vector<NativeInteger>>& GetPHatModq() const {
385  return m_PHatModq;
386  }
387 
393  const std::vector<std::vector<NativeInteger>>& GetalphaPModq() const {
394  return m_alphaPModq;
395  }
396 
402  bool operator==(const LPCryptoParameters<Element>& rhs) const {
403  const auto* el =
404  dynamic_cast<const LPCryptoParametersBFVrns<Element>*>(&rhs);
405 
406  if (el == nullptr) return false;
407 
409  }
410 
411  void PrintParameters(std::ostream& os) const {
413  }
414 
415  // NOTE that we do not serialize any of the members declared in this class.
416  // they are all cached computations, and get recomputed in any implementation
417  // that does a deserialization
418  template <class Archive>
419  void save(Archive& ar, std::uint32_t const version) const {
420  ar(::cereal::base_class<LPCryptoParametersRLWE<Element>>(this));
421  }
422 
423  template <class Archive>
424  void load(Archive& ar, std::uint32_t const version) {
425  if (version > SerializedVersion()) {
426  PALISADE_THROW(deserialize_error,
427  "serialized object version " + std::to_string(version) +
428  " is from a later version of the library");
429  }
430  ar(::cereal::base_class<LPCryptoParametersRLWE<Element>>(this));
431  if (SERIALIZE_PRECOMPUTE) {
433  }
434  }
435 
436  std::string SerializedObjectName() const { return "BFVrnsSchemeParameters"; }
437  static uint32_t SerializedVersion() { return 1; }
438 
439  private:
440  // Auxiliary CRT basis {P} = {p_j}
441  // used in homomorphic multiplication
442  shared_ptr<ILDCRTParams<BigInteger>> m_paramsP;
443 
444  // Auxiliary expanded CRT basis Q*P = {s_k}
445  // used in homomorphic multiplication
446  shared_ptr<ILDCRTParams<BigInteger>> m_paramsQP;
447 
448  // Stores \frac{1/q_i}
449  std::vector<double> m_qInv;
450 
451  // Stores \frac{1/p_j}
452  std::vector<double> m_pInv;
453 
454  // Barrett modulo reduction precomputation for q_i
455  std::vector<DoubleNativeInt> m_modqBarrettMu;
456 
457  // Barrett modulo reduction precomputation for p_j
458  std::vector<DoubleNativeInt> m_modpBarrettMu;
459 
460  // Stores \frac{t*{Q/q_i}^{-1}/q_i}
461  std::vector<double> m_tQHatInvModqDivqFrac;
462 
463  // when log2(q_i) >= 45 bits, B = \floor[2^{\ceil{log2(q_i)/2}}
464  // Stores \frac{t*{Q/q_i}^{-1}*B/q_i}
465  std::vector<double> m_tQHatInvModqBDivqFrac;
466 
467  // Stores [\floor{t*{Q/q_i}^{-1}/q_i}]_t
468  std::vector<NativeInteger> m_tQHatInvModqDivqModt;
469  // Stores NTL precomputations for [\floor{t*{Q/q_i}^{-1}/q_i}]_t
470  std::vector<NativeInteger> m_tQHatInvModqDivqModtPrecon;
471 
472  // when log2(q_i) >= 45 bits, B = \floor[2^{\ceil{log2(q_i)/2}}
473  // Stores [\floor{t*{Q/q_i}^{-1}*B/q_i}]_t
474  std::vector<NativeInteger> m_tQHatInvModqBDivqModt;
475 
476  // when log2 q_i >= 45 bits, B = \floor[2^{\ceil{log2(q_i)/2}}
477  // Stores NTL precomputations for [\floor{t*{Q/q_i}^{-1}*B/q_i}]_t
478  std::vector<NativeInteger> m_tQHatInvModqBDivqModtPrecon;
479 
480  // Stores [\floor{Q/t}]_{q_i}
481  std::vector<NativeInteger> m_QDivtModq;
482 
483  // Stores [(Q/q_i)^{-1}]_{q_i}
484  std::vector<NativeInteger> m_QHatInvModq;
485  // Stores NTL precomputations for [(Q/q_i)^{-1}]_{q_i}
486  std::vector<NativeInteger> m_QHatInvModqPrecon;
487 
488  // Stores [Q/q_i]_{p_j}
489  std::vector<std::vector<NativeInteger>> m_QHatModp;
490 
491  // Stores [\alpha*Q]_{p_j} for 0 <= alpha <= sizeQ
492  std::vector<std::vector<NativeInteger>> m_alphaQModp;
493 
494  // S = QP
495  // Stores [\floor{t*P*(S/s_k)^{-1}/s_k}]_{p_j}
496  std::vector<std::vector<NativeInteger>> m_tPSHatInvModsDivsModp;
497 
498  // S = QP
499  // Stores \frac{[t*P*(S/s_k)^{-1}]_{s_k}/s_k}
500  std::vector<double> m_tPSHatInvModsDivsFrac;
501 
502  // Stores [(P/p_j)^{-1}]_{p_j}
503  std::vector<NativeInteger> m_PHatInvModp;
504  // Stores NTL precomputations for [(P/p_j)^{-1}]_{p_j}
505  std::vector<NativeInteger> m_PHatInvModpPrecon;
506 
507  // Stores [P/p_j]_{q_i}
508  std::vector<std::vector<NativeInteger>> m_PHatModq;
509 
510  // Stores [\alpha*P]_{q_i} for 0 <= alpha <= sizeP
511  std::vector<std::vector<NativeInteger>> m_alphaPModq;
512 };
513 
520 template <class Element>
522  using IntType = typename Element::Integer;
523  using ParmType = typename Element::Params;
524  using DggType = typename Element::DggType;
525  using DugType = typename Element::DugType;
526  using TugType = typename Element::TugType;
527 
528  public:
533 
550  bool ParamsGen(shared_ptr<LPCryptoParameters<Element>> cryptoParams,
551  int32_t evalAddCount = 0, int32_t evalMultCount = 0,
552  int32_t keySwitchCount = 0, size_t dcrBits = 60,
553  uint32_t n = 0) const;
554 };
555 
563 template <class Element>
564 class LPAlgorithmBFVrns : public LPAlgorithmBFV<Element> {
565  using IntType = typename Element::Integer;
566  using ParmType = typename Element::Params;
567  using DggType = typename Element::DggType;
568  using DugType = typename Element::DugType;
569  using TugType = typename Element::TugType;
570 
571  public:
576 
584  Ciphertext<Element> Encrypt(const LPPublicKey<Element> publicKey,
585  Element plaintext) const;
586 
594  Ciphertext<Element> Encrypt(const LPPrivateKey<Element> privateKey,
595  Element plaintext) const;
596 
606  DecryptResult Decrypt(const LPPrivateKey<Element> privateKey,
607  ConstCiphertext<Element> ciphertext,
608  NativePoly* plaintext) const;
609 };
610 
616 template <class Element>
617 class LPAlgorithmSHEBFVrns : public LPAlgorithmSHEBFV<Element> {
618  using IntType = typename Element::Integer;
619  using ParmType = typename Element::Params;
620  using DggType = typename Element::DggType;
621  using DugType = typename Element::DugType;
622  using TugType = typename Element::TugType;
623 
624  public:
629 
637  Ciphertext<Element> EvalAdd(ConstCiphertext<Element> ct,
638  ConstPlaintext pt) const override;
639 
647  Ciphertext<Element> EvalSub(ConstCiphertext<Element> ct1,
648  ConstPlaintext pt) const override;
649 
660  Ciphertext<Element> EvalMult(ConstCiphertext<Element> ct1,
661  ConstCiphertext<Element> ct2) const override;
662 
670  LPEvalKey<Element> KeySwitchGen(
671  const LPPrivateKey<Element> oldKey,
672  const LPPrivateKey<Element> newKey) const override;
673 
682  void KeySwitchInPlace(const LPEvalKey<Element> keySwitchHint,
683  Ciphertext<Element>& ciphertext) const override;
684 
697  Ciphertext<Element> EvalMultAndRelinearize(
698  ConstCiphertext<Element> ct1, ConstCiphertext<Element> ct2,
699  const vector<LPEvalKey<Element>>& ek) const override;
700 };
701 
707 template <class Element>
708 class LPAlgorithmPREBFVrns : public LPAlgorithmPREBFV<Element> {
709  using IntType = typename Element::Integer;
710  using ParmType = typename Element::Params;
711  using DggType = typename Element::DggType;
712  using DugType = typename Element::DugType;
713  using TugType = typename Element::TugType;
714 
715  public:
720 
747  LPEvalKey<Element> ReKeyGen(const LPPublicKey<Element> newKey,
748  const LPPrivateKey<Element> oldKey) const;
749 
776  Ciphertext<Element> ReEncrypt(
777  const LPEvalKey<Element> ek, ConstCiphertext<Element> ciphertext,
778  const LPPublicKey<Element> publicKey = nullptr) const;
779 };
780 
807 template <class Element>
809  using IntType = typename Element::Integer;
810  using ParmType = typename Element::Params;
811  using DggType = typename Element::DggType;
812  using DugType = typename Element::DugType;
813  using TugType = typename Element::TugType;
814 
815  public:
820 
829  DecryptResult MultipartyDecryptFusion(
830  const vector<Ciphertext<Element>>& ciphertextVec,
831  NativePoly* plaintext) const override;
832 
833  template <class Archive>
834  void save(Archive& ar) const {
835  ar(cereal::base_class<LPAlgorithmMultipartyBFV<Element>>(this));
836  }
837 
838  template <class Archive>
839  void load(Archive& ar) {
840  ar(cereal::base_class<LPAlgorithmMultipartyBFV<Element>>(this));
841  }
842 
853  LPEvalKey<Element> MultiKeySwitchGen(
854  const LPPrivateKey<Element> oldKey, const LPPrivateKey<Element> newKey,
855  const LPEvalKey<Element> ek) const override;
856 
857  std::string SerializedObjectName() const { return "BFVrnsMultiparty"; }
858 };
859 
864 template <class Element>
866  : public LPPublicKeyEncryptionScheme<Element> {
867  using IntType = typename Element::Integer;
868  using ParmType = typename Element::Params;
869  using DggType = typename Element::DggType;
870  using DugType = typename Element::DugType;
871  using TugType = typename Element::TugType;
872 
873  public:
875 
876  bool operator==(
877  const LPPublicKeyEncryptionScheme<Element>& sch) const override {
878  return dynamic_cast<const LPPublicKeyEncryptionSchemeBFVrns<Element>*>(
879  &sch) != nullptr;
880  }
881 
882  void Enable(PKESchemeFeature feature) override;
883 
884  template <class Archive>
885  void save(Archive& ar, std::uint32_t const version) const {
886  ar(::cereal::base_class<LPPublicKeyEncryptionScheme<Element>>(this));
887  }
888 
889  template <class Archive>
890  void load(Archive& ar, std::uint32_t const version) {
891  ar(::cereal::base_class<LPPublicKeyEncryptionScheme<Element>>(this));
892  }
893 
894  std::string SerializedObjectName() const override { return "BFVrnsScheme"; }
895 };
896 } // namespace lbcrypto
897 
898 #endif
const std::vector< std::vector< NativeInteger > > & GetPHatModq() const
Definition: bfvrns.h:384
LPAlgorithmMultipartyBFVrns()
Definition: bfvrns.h:819
const std::vector< std::vector< NativeInteger > > & GetQHatModp() const
Definition: bfvrns.h:327
PRE scheme based on BFV. This functionality is currently DISABLED in LPPublicKeyEncryptionSchemeBFV b...
Definition: bfv.h:749
Decryption result. This represents whether the decryption of a cipheretext was performed correctly...
Definition: pubkeylp.h:105
const std::vector< NativeInteger > & GettQHatInvModqDivqModt() const
Definition: bfvrns.h:264
std::vector< DoubleNativeInt > const & GetModqBarrettMu() const
Definition: bfvrns.h:227
const std::vector< NativeInteger > & GetPHatInvModpPrecon() const
Definition: bfvrns.h:375
const std::vector< NativeInteger > & GetQHatInvModq() const
Definition: bfvrns.h:309
Template for crypto parameters.
Definition: rlwe.h:47
std::vector< double > const & GetpInv() const
Definition: bfvrns.h:220
PRE algorithms implementation for BFVrns.
Definition: bfvrns.h:708
Concrete class for the FHE Multiparty algorithms on BFV. A version of this multiparty scheme built on...
Definition: bfv.h:860
const std::vector< NativeInteger > & GettQHatInvModqBDivqModtPrecon() const
Definition: bfvrns.h:293
LPAlgorithmBFVrns()
Definition: bfvrns.h:575
const std::vector< NativeInteger > & GettQHatInvModqBDivqModt() const
Definition: bfvrns.h:283
bool operator==(const LPCryptoParameters< Element > &rhs) const
Definition: rlwe.h:284
const shared_ptr< ILDCRTParams< BigInteger > > GetParamsP() const
Definition: bfvrns.h:194
LPAlgorithmPREBFVrns()
Definition: bfvrns.h:719
const std::vector< std::vector< NativeInteger > > & GettPSHatInvModsDivsModp() const
Definition: bfvrns.h:356
Definition: exception.h:147
const std::vector< NativeInteger > & GetDelta() const
Definition: bfvrns.h:302
std::vector< double > const & GetqInv() const
Definition: bfvrns.h:213
Main public key encryption scheme for BFVrns implementation,.
Definition: bfvrns.h:865
const std::vector< NativeInteger > & GettQHatInvModqDivqModtPrecon() const
Definition: bfvrns.h:273
This is the parameters class for the BFVrns encryption scheme. This scheme is also referred to as the...
Definition: bfvrns.h:74
Concrete class for the FHE Multiparty algorithms on BFVrns. This scheme is also referred to as the FV...
Definition: bfvrns.h:808
bool SERIALIZE_PRECOMPUTE
Definition: cryptocontext.cpp:30
Parameter generation for BFV. This scheme is also referred to as the FV scheme.
Definition: bfv.h:386
Encryption algorithm implementation for BFV for the basic public key encrypt, decrypt and key generat...
Definition: bfv.h:439
LPAlgorithmSHEBFVrns()
Definition: bfvrns.h:628
const std::vector< std::vector< NativeInteger > > & GetalphaPModq() const
Definition: bfvrns.h:393
const std::vector< NativeInteger > & GetPHatInvModp() const
Definition: bfvrns.h:366
const std::vector< double > & GettQHatInvModqBDivqFrac() const
Definition: bfvrns.h:255
bool operator==(const LPCryptoParameters< Element > &rhs) const
Definition: bfvrns.h:402
Parameter generation for BFVrns. This scheme is also referred to as the FV scheme.
Definition: bfvrns.h:521
const std::vector< double > & GettQHatInvModqDivqFrac() const
Definition: bfvrns.h:245
SHE algorithms implementation for BFVrns.
Definition: bfvrns.h:617
LPCryptoParametersBFVrns()
Definition: bfvrns.cpp:65
main implementation class to capture essential cryptoparameters of any LBC system ...
Definition: pubkeylp.h:73
LPAlgorithmParamsGenBFVrns()
Definition: bfvrns.h:532
std::vector< DoubleNativeInt > const & GetModpBarrettMu() const
Definition: bfvrns.h:236
const std::vector< std::vector< NativeInteger > > & GetalphaQModp() const
Definition: bfvrns.h:336
const std::vector< double > & GettPSHatInvModsDivsFrac() const
Definition: bfvrns.h:346
Definition: binfhecontext.h:36
SHE algorithms implementation for BFV. This scheme is also referred to as the FV scheme.
Definition: bfv.h:517
Abstract interface for public key encryption schemes.
Definition: pubkeylp.h:3181
const std::vector< NativeInteger > & GetQHatInvModqPrecon() const
Definition: bfvrns.h:318
Encryption algorithm implementation for BFVrns for the basic public key encrypt, decrypt and key gene...
Definition: bfvrns.h:564
const shared_ptr< ILDCRTParams< BigInteger > > GetParamsQP() const
Definition: bfvrns.h:204
virtual ~LPCryptoParametersBFVrns()
Definition: bfvrns.h:179