2323#include < helib/powerful.h>
2424#include < helib/apiAttributes.h>
2525#include < helib/range.h>
26+ #include < helib/scheme.h>
2627
2728#include < NTL/Lazy.h>
2829
@@ -72,13 +73,13 @@ inline double lweEstimateSecurity(int n, double log2AlphaInv, int hwt)
7273 if (hwt == 0 ) { // dense keys
7374 slope = 3.8 ;
7475 consterm = -20 ;
75- } else if (idx < numWghts - 1 ) {
76+ } else if (idx < numWghts - 1 ) {
7677 // estimate prms on a line from prms[i] to prms[i+1]
7778 // how far into this interval
7879 double a = double (hwt - hwgts[idx]) / (hwgts[idx + 1 ] - hwgts[idx]);
7980 slope = slopes[idx] + a * (slopes[idx + 1 ] - slopes[idx]);
8081 consterm = cnstrms[idx] + a * (cnstrms[idx + 1 ] - cnstrms[idx]);
81- } else {
82+ } else {
8283 // Use the params corresponding to largest weight (450 above)
8384 slope = slopes[numWghts - 1 ];
8485 consterm = cnstrms[numWghts - 1 ];
@@ -387,6 +388,17 @@ class Context
387388 const std::vector<long >& gens = std::vector<long >(),
388389 const std::vector<long >& ords = std::vector<long >());
389390
391+ // FIXME: This is a temporary fix to allow proper copy of the context.
392+ // Without the fixes there would be discrepancies between context's zMStar and
393+ // alMod const reference one.
394+ // TODO: Add doxygen comments to the following methods.
395+ ~Context () = default ;
396+ Context (const Context& other);
397+ Context (Context&& other);
398+ // Deleted assignment operators.
399+ Context& operator =(const Context& other) = delete ;
400+ Context& operator =(Context&& other) = delete ;
401+
390402 void makeBootstrappable (const NTL::Vec<long >& mvec,
391403 long skWht = 0 ,
392404 bool build_cache = false ,
@@ -596,6 +608,7 @@ void readContextBaseBinary(std::istream& s,
596608 unsigned long & r,
597609 std::vector<long >& gens,
598610 std::vector<long >& ords);
611+
599612std::unique_ptr<Context> buildContextFromBinary (std::istream& str);
600613void readContextBinary (std::istream& str, Context& context);
601614
@@ -616,10 +629,315 @@ void buildModChain(Context& context,
616629 long skHwt = 0 ,
617630 long resolution = 3 ,
618631 long bitsInSpecialPrimes = 0 );
632+
619633// should be called if after you build the mod chain in some way
620634// *other* than calling buildModChain.
621635void endBuildModChain (Context& context);
622636
637+ // Forward declaration of ContextBuilder
638+ template <typename SCHEME>
639+ class ContextBuilder ;
640+
641+ /* *
642+ * @brief `ostream` operator for serializing the `ContextBuilder` object.
643+ * @tparam SCHEME The encryption scheme to be used, must be `BGV` or `CKKS`.
644+ * @param os Reference to the output stream.
645+ * @param cb The `ContextBuilder` object to serialize.
646+ * @return Reference to the `std::ostream`
647+ **/
648+ template <typename SCHEME>
649+ std::ostream& operator <<(std::ostream& os, const ContextBuilder<SCHEME>& cb);
650+
651+ /* *
652+ * @class ContextBuilder
653+ * @brief Builder to help construct a context.
654+ * @tparam SCHEME The encryption scheme to be used, must be `BGV` or `CKKS`.
655+ **/
656+ template <typename SCHEME>
657+ class ContextBuilder
658+ {
659+ static_assert (std::is_same<SCHEME, CKKS>::value ||
660+ std::is_same<SCHEME, BGV>::value,
661+ " Can only create context object parameterized by the crypto "
662+ " scheme (CKKS or BGV)" );
663+
664+ private:
665+ // Default values by scheme.
666+ struct default_values ;
667+
668+ // General parameters
669+ std::vector<long > gens_;
670+ std::vector<long > ords_;
671+ long m_ = default_values::m; // BGV: 3, CKKS: 4
672+ long p_ = default_values::p; // BGV: 2, CKKS: -1
673+ long r_ = default_values::r; // BGV: Hensel lifting = 1,
674+ // CKKS: Precision = 20
675+ long c_ = 3 ;
676+
677+ // Modulus chain params
678+ long bits_ = 300 ;
679+ long skHwt_ = 0 ;
680+ long resolution_ = 3 ;
681+ long bitsInSpecialPrimes_ = 0 ;
682+ bool buildModChainFlag_ = true ; // Default build the modchain.
683+
684+ // Boostrap params (BGV only)
685+ NTL::Vec<long > mvec_;
686+ bool buildCacheFlag_ = false ;
687+ bool thickFlag_ = false ;
688+ bool bootstrappableFlag_ = false ; // Default not boostrappable.
689+
690+ public:
691+ /* *
692+ * @brief Sets `m` the order of the cyclotomic polynomial.
693+ * @param m The order of the cyclotomic polynomial.
694+ * @return Reference to this `ContextBuilder` object.
695+ **/
696+ ContextBuilder& m (long m)
697+ {
698+ m_ = m;
699+ return *this ;
700+ }
701+
702+ /* *
703+ * @brief Sets `p` the prime number of the ciphertext space.
704+ * @param p The prime number of the plaintext space.
705+ * @return Reference to the `ContextBuilder` object.
706+ * @note Only exists when the `SCHEME` is `BGV`.
707+ **/
708+ template <typename S = SCHEME,
709+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
710+ ContextBuilder& p (long p)
711+ {
712+ p_ = p;
713+ return *this ;
714+ }
715+
716+ /* *
717+ * @brief Sets `r` the Hensel lifting parameter.
718+ * @param r The Hensel lifting parameter.
719+ * @return Reference to the `ContextBuilder` object.
720+ * @note Only exists when the `SCHEME` is `BGV`.
721+ **/
722+ template <typename S = SCHEME,
723+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
724+ ContextBuilder& r (long r)
725+ {
726+ r_ = r;
727+ return *this ;
728+ }
729+
730+ /* *
731+ * @brief Sets `precision` the bit precision parameter.
732+ * @param precision The bit precision parameter.
733+ * @return Reference to the `ContextBuilder` object.
734+ * @note Only exists when the `SCHEME` is `CKKS`.
735+ **/
736+ template <typename S = SCHEME,
737+ std::enable_if_t <std::is_same<S, CKKS>::value>* = nullptr >
738+ ContextBuilder& precision (long precision)
739+ {
740+ r_ = precision;
741+ return *this ;
742+ }
743+
744+ /* *
745+ * @brief Sets `c` the number of columns (a.k.a. digits) in the key switching
746+ * matrices.
747+ * @param c The number of columns in the key switching matrix.
748+ * @return Reference to the `ContextBuilder` object.
749+ **/
750+ ContextBuilder& c (long c)
751+ {
752+ c_ = c;
753+ return *this ;
754+ }
755+
756+ /* *
757+ * @brief Sets `gens` the generators of the `ZMStar` group.
758+ * @param gens A `std::vector` containing the generators.
759+ * @return Reference to the `ContextBuilder` object.
760+ **/
761+ ContextBuilder& gens (const std::vector<long >& gens)
762+ {
763+ gens_ = gens;
764+ return *this ;
765+ }
766+
767+ /* *
768+ * @brief Sets `ords` the order of the corresponding generators in `gens` in
769+ * `ZmStar`.
770+ * @param ords A `std::vector` containing the orders of `gens`. The order
771+ * taken is the absolute value; a negative in `ords` represents a bad
772+ * dimension.
773+ * @return Reference to the `ContextBuilder` object.
774+ **/
775+ ContextBuilder& ords (const std::vector<long >& ords)
776+ {
777+ ords_ = ords;
778+ return *this ;
779+ }
780+
781+ /* *
782+ * @brief Sets the bit size of the primes in the modulus chain.
783+ * @param bits How many bits to make the modulus chain.
784+ * @return Reference to the `ContextBuilder` object.
785+ * @note The actual bit size that is set is typically higher than requested.
786+ **/
787+ ContextBuilder& bits (long bits)
788+ {
789+ bits_ = bits;
790+ return *this ;
791+ }
792+
793+ /* *
794+ * @brief Sets the secret key Hamming weight.
795+ * @param bits The secret key Hamming weight.
796+ * @return Reference to the `ContextBuilder` object.
797+ * @note If the Hamming weight is `0` (default) then a "dense" key will be
798+ * generated.
799+ **/
800+ ContextBuilder& skHwt (long skHwt)
801+ {
802+ skHwt_ = skHwt;
803+ return *this ;
804+ }
805+
806+ /* *
807+ * @brief Sets the resolution for the modulus chain.
808+ * @param bits How many bit size of resolution.
809+ * @return Reference to the `ContextBuilder` object.
810+ **/
811+ ContextBuilder& resolution (long bits)
812+ {
813+ resolution_ = bits;
814+ return *this ;
815+ }
816+
817+ /* *
818+ * @brief Sets the bit size of the special primes in the modulus chain.
819+ * @param bits The bit size of the special primes in the modulus chain.
820+ * @return Reference to this `ContextBuilder` object.
821+ **/
822+ ContextBuilder& bitsInSpecialPrimes (long bits)
823+ {
824+ bitsInSpecialPrimes_ = bits;
825+ return *this ;
826+ }
827+
828+ /* *
829+ * @brief Sets a flag determining whether the modulus chain will be built.
830+ * @param `yesno` A `bool` to determine whether the modulus chain should be
831+ * built.
832+ * @return Reference to the `ContextBuilder` object.
833+ * @note `ContextBuilder` by default will build the modulus chain.
834+ **/
835+ ContextBuilder& buildModChain (bool yesno)
836+ {
837+ buildModChainFlag_ = yesno;
838+ return *this ;
839+ }
840+
841+ /* *
842+ * @brief Sets `mvec` the unique primes which are factors of `m`.
843+ * @param mvec An `NTL::Vec` of primes factors.
844+ * @return Reference to the `ContextBuilder` object.
845+ * @note Only exists when the `SCHEME` is `BGV`.
846+ **/
847+ template <typename S = SCHEME,
848+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
849+ ContextBuilder& mvec (const NTL::Vec<long >& mvec)
850+ {
851+ mvec_ = mvec;
852+ return *this ;
853+ }
854+
855+ /* *
856+ * @brief Sets boostrapping to be `thin`.
857+ * @return Reference to the `ContextBuilder` object.
858+ * @note Only exists when the `SCHEME` is `BGV`.
859+ **/
860+ template <typename S = SCHEME,
861+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
862+ ContextBuilder& thinboot ()
863+ {
864+ thickFlag_ = false ;
865+ return *this ;
866+ }
867+
868+ /* *
869+ * @brief Sets boostrapping to be `thick`.
870+ * @return Reference to the `ContextBuilder` object.
871+ * @note Only exists when the `SCHEME` is `BGV`.
872+ **/
873+ template <typename S = SCHEME,
874+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
875+ ContextBuilder& thickboot ()
876+ {
877+ thickFlag_ = true ;
878+ return *this ;
879+ }
880+
881+ /* *
882+ * @brief Sets flag to choose that the cache for boostrapping will be
883+ * built.
884+ * @param yesno A `bool` to determine whether the cache is built.
885+ * @return Reference to the `ContextBuilder` object.
886+ * @note @note Only exists when the `SCHEME` is `BGV`.
887+ **/
888+ template <typename S = SCHEME,
889+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
890+ ContextBuilder& buildCache (bool yesno)
891+ {
892+ buildCacheFlag_ = yesno;
893+ return *this ;
894+ }
895+
896+ /* *
897+ * @brief Sets a flag determining if the context will be bootstrappable.
898+ * @param yesno A `bool` to determine whether the context will be
899+ * bootstrappable.
900+ * @return Reference to this `ContextBuilder` object.
901+ * @note `ContextBuilder` by default will not be bootstrappable.
902+ * @note Only exists when the `SCHEME` is `BGV`.
903+ **/
904+ template <typename S = SCHEME,
905+ std::enable_if_t <std::is_same<S, BGV>::value>* = nullptr >
906+ ContextBuilder& bootstrappable (bool yesno)
907+ {
908+ bootstrappableFlag_ = yesno;
909+ return *this ;
910+ }
911+
912+ /* *
913+ * @brief Builds a `Context` object from the arguments stored in the
914+ * `ContextBuilder` object.
915+ * @return A `Context` object.
916+ **/
917+ Context build () const ;
918+
919+ friend std::ostream& operator <<<SCHEME>(std::ostream& os,
920+ const ContextBuilder& cb);
921+ };
922+
923+ // Default BGV values
924+ template <>
925+ struct ContextBuilder <BGV>::default_values
926+ {
927+ static constexpr long m = 3 ;
928+ static constexpr long p = 2 ;
929+ static constexpr long r = 1 ;
930+ };
931+
932+ // Default CKKS values
933+ template <>
934+ struct ContextBuilder <CKKS>::default_values
935+ {
936+ static constexpr long m = 4 ;
937+ static constexpr long p = -1 ;
938+ static constexpr long r = 20 ;
939+ };
940+
623941// /@}
624942// Should point to the "current" context
625943extern Context* activeContext;
0 commit comments