SEAL开源库源码07

SEAL开源库源码07

seal/context.h

EncryptionParameterQualifiers 类

Stores a set of attributes (qualifiers) of a set of encryption parameters.
These parameters are mainly used internally in various parts of the library,
e.g., to determine which algorithmic optimizations the current support. The
qualifiers are automatically created by the SEALContext class, silently passed
on to classes such as Encryptor, Evaluator, and Decryptor, and the only way to
change them is by changing the encryption parameters themselves. In other
words, a user will never have to create their own instance of this class, and
in most cases never have to worry about it at all.

存储一组加密参数的一组属性(限定符)。这些参数主要在库的各个部分内部使用,例如,确定当前支持哪些算法优化。限定符由SEALContext类自动创建,并静默传递给Encryptor、Evaluator和Decryptor等类,更改它们的唯一方法是更改加密参数本身。换句话说,用户永远不需要创建他们自己的该类实例,而且在大多数情况下根本不需要担心它。

    class EncryptionParameterQualifiers
    {
   
    public:
        /**
        Identifies the reason why encryption parameters are not valid.
        */
        enum class error_type : int
        {
   
            /**
            constructed but not yet validated
            */
            none = -1,

            /**
            valid
            */
            success = 0,

            /**
            scheme must be BFV or CKKS or BGV
            */
            invalid_scheme = 1,

            /**
            coeff_modulus's primes' count is not bounded by SEAL_COEFF_MOD_COUNT_MIN(MAX)
            */
            invalid_coeff_modulus_size = 2,

            /**
            coeff_modulus's primes' bit counts are not bounded by SEAL_USER_MOD_BIT_COUNT_MIN(MAX)
            */
            invalid_coeff_modulus_bit_count = 3,

            /**
            coeff_modulus's primes are not congruent to 1 modulo (2 * poly_modulus_degree)
            */
            invalid_coeff_modulus_no_ntt = 4,

            /**
            poly_modulus_degree is not bounded by SEAL_POLY_MOD_DEGREE_MIN(MAX)
            */
            invalid_poly_modulus_degree = 5,

            /**
            poly_modulus_degree is not a power of two
            */
            invalid_poly_modulus_degree_non_power_of_two = 6,

            /**
            parameters are too large to fit in size_t type
            */
            invalid_parameters_too_large = 7,

            /**
            parameters are not compliant with HomomorphicEncryption.org security standard
            */
            invalid_parameters_insecure = 8,

            /**
            RNSBase cannot be constructed
            */
            failed_creating_rns_base = 9,

            /**
            plain_modulus's bit count is not bounded by SEAL_PLAIN_MOD_BIT_COUNT_MIN(MAX)
            */
            invalid_plain_modulus_bit_count = 10,

            /**
            plain_modulus is not coprime to coeff_modulus
            */
            invalid_plain_modulus_coprimality = 11,

            /**
            plain_modulus is not smaller than coeff_modulus
            */
            invalid_plain_modulus_too_large = 12,

            /**
            plain_modulus is not zero
            */
            invalid_plain_modulus_nonzero = 13,

            /**
            RNSTool cannot be constructed
            */
            failed_creating_rns_tool = 14,
        };

        /**
        The variable parameter_error is set to:
        - none, if parameters are not validated;
        - success, if parameters are considered valid by Microsoft SEAL;
        - other values, if parameters are validated and invalid.
        */
        error_type parameter_error;

        /**
        Returns the name of parameter_error.
        */
        SEAL_NODISCARD const char *parameter_error_name() const noexcept;

        /**
        Returns a comprehensive message that interprets parameter_error.
        */
        SEAL_NODISCARD const char *parameter_error_message() const noexcept;

        /**
        Tells whether parameter_error is error_type::success.
        */
        SEAL_NODISCARD inline bool parameters_set() const noexcept
        {
   
            return parameter_error == error_type::success;
        }

        /**
        Tells whether FFT can be used for polynomial multiplication. If the
        polynomial modulus is of the form X^N+1, where N is a power of two, then
        FFT can be used for fast multiplication of polynomials modulo the polynomial
        modulus. In this case the variable using_fft will be set to true. However,
        currently Microsoft SEAL requires this to be the case for the parameters
        to be valid. Therefore, parameters_set can only be true if using_fft is
        true.
        */
        bool using_fft;

        /**
        Tells whether NTT can be used for polynomial multiplication. If the primes
        in the coefficient modulus are congruent to 1 modulo 2N, where X^N+1 is the
        polynomial modulus and N is a power of two, then the number-theoretic
        transform (NTT) can be used for fast multiplications of polynomials modulo
        the polynomial modulus and coefficient modulus. In this case the variable
        using_ntt will be set to true. However, currently Microsoft SEAL requires
        this to be the case for the parameters to be valid. Therefore, parameters_set
        can only be true if using_ntt is true.
        */
        bool using_ntt;

        /**
        Tells whether batching is supported by the encryption parameters. If the
        plaintext modulus is congruent to 1 modulo 2N, where X^N+1 is the polynomial
        modulus and N is a power of two, then it is possible to use the BatchEncoder
        class to view plaintext elements as 2-by-(N/2) matrices of integers modulo
        the plaintext modulus. This is called batching, and allows the user to
        operate on the matrix elements (slots) in a SIMD fashion, and rotate the
        matrix rows and columns. When the computation is easily vectorizable, using
        batching can yield a huge performance boost. If the encryption parameters
        support batching, the variable using_batching is set to true.
        */
        bool using_batching;

        /**
        Tells whether fast plain lift is supported by the encryption parameters.
        A certain performance optimization in multiplication of a ciphertext by
        a plaintext (Evaluator::multiply_plain) and in transforming a plaintext
        element to NTT domain (Evaluator::transform_to_ntt) can be used when the
        plaintext modulus is smaller than each prime in the coefficient modulus.
        In this case the variable using_fast_plain_lift is set to true.
        */
        bool using_fast_plain_lift;

        /**
        Tells whether the coefficient modulus consists of a set of primes that
        are in decreasing order. If this is true, certain modular reductions in
        base conversion can be omitted, improving performance.
        */
        bool using_descending_modulus_chain;

        /**
        Tells whether the encryption parameters are secure based on the standard
        parameters from HomomorphicEncryption.org security standard.
        */
        sec_level_type sec_level;

    private:
        EncryptionParameterQualifiers()
            : parameter_error(error_type::none), using_fft(false), using_ntt(false), using_batching(false),
              using_fast_plain_lift(false), using_descending_modulus_chain(false), sec_level(sec_level_type::none)
        {
   }

        friend class SEALContext;
    };

SEALContext 类

Performs sanity checks (validation) and pre-computations for a given set of encryption
parameters. While the EncryptionParameters class is intended to be a light-weight class
to store the encryption parameters, the SEALContext class is a heavy-weight class that
is constructed from a given set of encryption parameters. It validates the parameters
for correctness, evaluates their properties, and performs and stores the results of
several costly pre-computations.

After the user has set at least the poly_modulus, coeff_modulus, and plain_modulus
parameters in a given EncryptionParameters instance, the parameters can be validated
for correctness and functionality by constructing an instance of SEALContext. The
constructor of SEALContext does all of its work automatically, and concludes by
constructing and storing an instance of the EncryptionParameterQualifiers class, with
its flags set according to the properties of the given parameters. If the created
instance of EncryptionParameterQualifiers has the parameters_set flag set to true, the
given parameter set has been deemed valid and is ready to be used. If the parameters
were for some reason not appropriately set, the parameters_set flag will be false,
and a new SEALContext will have to be created after the parameters are corrected.

By default, SEALContext creates a chain of SEALContext::ContextData instances. The
first one in the chain corresponds to special encryption parameters that are reserved
to be used by the various key classes (SecretKey, PublicKey, etc.). These are the exact
same encryption parameters that are created by the user and passed to th constructor of
SEALContext. The functions key_context_data() and key_parms_id() return the ContextData
and the parms_id corresponding to these special parameters. The rest of the ContextData
instances in the chain correspond to encryption parameters that are derived from the
first encryption parameters by always removing the last one of the moduli in the
coeff_modulus, until the resulting parameters are no longer valid, e.g., there are no
more primes left. These derived encryption parameters are used by ciphertexts and
plaintexts and their respective ContextData can be accessed through the
get_context_data(parms_id_type) function. The functions first_context_data() and
last_context_data() return the ContextData corresponding to the first and the last
set of parameters in the "data" part of the chain, i.e., the second and the last element
in the full chain. The chain itself is a doubly linked list, and is referred to as the
modulus switching chain.

@see EncryptionParameters for more details on the parameters.
@see EncryptionParameterQualifiers for more details on the qualifiers.

对给定的加密参数集执行完整性检查(验证)和预计算。EncryptionParameters类是用来存储加密参数的轻量级类,而SEALContext类是一个重量级类,它是根据给定的一组加密参数构造的。它验证参数的正确性,评估它们的属性,并执行和存储几个昂贵的预计算的结果。

用户在给定的EncryptionParameters实例中至少设置了poly_modulus、coeff_modulus和plain_modulus参数之后,就可以通过构造SEALContext的实例来验证这些参数的正确性和功能性。SEALContext的构造函数自动完成它的所有工作,并通过构造和存储EncryptionParameterQualifiers类的一个实例来结束,该实例的标志根据给定参数的属性设置。如果EncryptionParameterQualifiers创建的实例将parameters_set标志设置为true,则认为给定的参数集是有效的,可以使用了。如果由于某些原因参数没有适当地设置,parameters_set标志将为false,并且在纠正参数之后必须创建一个新的SEALContext。

默认情况下,SEALContext创建一个SEALContext::ContextData实例链。链中的第一个对应于保留给各种密钥类(SecretKey, PublicKey等)使用的特殊加密参数。这些加密参数与用户创建并传递给SEALContext构造函数的加密参数完全相同。函数key_context_data()和key_parms_id()返回与这些特殊参数对应的ContextData和parms_id。链中其余的ContextData实例对应于加密参数,这些加密参数是通过始终移除coeff_modulus中的最后一个模数而派生出的第一个加密参数,直到得到的参数不再有效,例如,不再剩下素数。这些派生的加密参数由密文和明文使用,它们各自的ContextData可以通过get_context_data(parms_id_type)函数访问。函数first_context_data()和last_context_data()返回对应于链“数据”部分的第一个和最后一个参数集的ContextData,即整个链中的第二个和最后一个元素。链本身是一个双链表,被称为模切换链。

@see EncryptionParameters关于参数的更多细节。
@关于限定符的更多细节,请参阅EncryptionParameterQualifiers。

ContextData 类,具有链表结构,保存了指前一个后一个的指针

  Class to hold pre-computation data for a given set of encryption parameters.
        /**
        Class to hold pre-computation data for a given set of encryption parameters.
        */
        class ContextData
        {
   
            friend class SEALContext;

        public:
            ContextData() = delete;

            ContextData(const ContextData &copy) = delete;

            ContextData(ContextData &&move) = default;

            ContextData &operator=(ContextData &&move) = default;

            /**
            Returns a const reference to the underlying encryption parameters.
            */
            SEAL_NODISCARD inline const EncryptionParameters &parms() const noexcept
            {
   
                return parms_;
            }

            /**
            Returns the parms_id of the current parameters.
            */
            SEAL_NODISCARD inline const parms_id_type &parms_id() const noexcept
            {
   
                return parms_.parms_id();
            }

            /**
            Returns a copy of EncryptionParameterQualifiers corresponding to the
            current encryption parameters. Note that to change the qualifiers it is
            necessary to create a new instance of SEALContext once appropriate changes
            to the encryption parameters have been made.
            */
            SEAL_NODISCARD inline EncryptionParameterQualifiers qualifiers() const noexcept
            {
   
                return qualifiers_;
            }

            /**
            Returns a pointer to a pre-computed product of all primes in the coefficient
            modulus. The security of the encryption parameters largely depends on the
            bit-length of this product, and on the degree of the polynomial modulus.
            */
            SEAL_NODISCARD inline const std::uint64_t *total_coeff_modulus() const noexcept
            {
   
                return total_coeff_modulus_.get();
            }

            /**
            Returns the significant bit count of the total coefficient modulus.
            */
            SEAL_NODISCARD inline int total_coeff_modulus_bit_count() const noexcept
            {
   
                return total_coeff_modulus_bit_count_;
            }

            /**
            Returns a constant pointer to the RNSTool.
            */
            SEAL_NODISCARD inline const util::RNSTool *rns_tool() const noexcept
            {
   
                return rns_tool_.get();
            }

            /**
            Returns a constant pointer to the NTT tables.
            */
            SEAL_NODISCARD inline const util::NTTTables *small_ntt_tables() const noexcept
            {
   
                return small_ntt_tables_.get();
            }

            /**
            Returns a constant pointer to the NTT tables.
            */
            SEAL_NODISCARD inline const util::NTTTables *plain_ntt_tables() const noexcept
            {
   
                return plain_ntt_tables_.get();
            }

            /**
            Returns a constant pointer to the GaloisTool.
            */
            SEAL_NODISCARD inline const util::GaloisTool *galois_tool() const noexcept
            {
   
                return galois_tool_.get();
            }

            /**
            Return a pointer to BFV "Delta", i.e. coefficient modulus divided by
            plaintext modulus.
            */
            SEAL_NODISCARD inline const util::MultiplyUIntModOperand *coeff_div_plain_modulus() const noexcept
            {
   
                return coeff_div_plain_modulus_.get();
            }

            /**
            Return the threshold for the upper half of integers modulo plain_modulus.
            This is simply (plain_modulus + 1) / 2.
            */
            SEAL_NODISCARD inline std::uint64_t plain_upper_half_threshold() const noexcept
            {
   
                return plain_upper_half_threshold_;
            }

            /**
            Return a pointer to the plaintext upper half increment, i.e. coeff_modulus
            minus plain_modulus. The upper half increment is represented as an integer
            for the full product coeff_modulus if using_fast_plain_lift is false and is
            otherwise represented modulo each of the coeff_modulus primes in order.
            */
            SEAL_NODISCARD inline const std::uint64_t *plain_upper_half_increment() const noexcept
            {
   
                return plain_upper_half_increment_.get();
            }

            /**
            Return a pointer to the upper half threshold with respect to the total
            coefficient modulus. This is needed in CKKS decryption.
            */
            SEAL_NODISCARD inline const std::uint64_t *upper_half_threshold() const noexcept
            {
   
                return upper_half_threshold_.get();
            }

            /**
            Return a pointer to the upper half increment used for computing Delta*m
            and converting the coefficients to modulo coeff_modulus. For example,
            t-1 in plaintext should change into
            q - Delta = Delta*t + r_t(q) - Delta
            = Delta*(t-1) + r_t(q)
            so multiplying the message by Delta is not enough and requires also an
            addition of r_t(q). This is precisely the upper_half_increment. Note that
            this operation is only done for negative message coefficients, i.e. those
            that exceed plain_upper_half_threshold.
            */
            SEAL_NODISCARD inline const std::uint64_t *upper_half_increment() const noexcept
            {
   
                return upper_half_increment_.get();
            }

            /**
            Return the non-RNS form of upper_half_increment which is q mod t.
            */
            SEAL_NODISCARD inline std::uint64_t coeff_modulus_mod_plain_modulus() const noexcept
            {
   
                return coeff_modulus_mod_plain_modulus_;
            }

            /**
            Returns a shared_ptr to the context data corresponding to the previous parameters
            in the modulus switching chain. If the current data is the first one in the
            chain, then the result is nullptr.
            */
            SEAL_NODISCARD inline std::shared_ptr<const ContextData> prev_context_data() const noexcept
            {
   
                return prev_context_data_.lock();
            }

            /**
            Returns a shared_ptr to the context data corresponding to the next parameters
            in the modulus switching chain. If the current data is the last one in the
            chain, then the result is nullptr.
            */
            SEAL_NODISCARD inline std::shared_ptr<const ContextData> next_context_data() const noexcept
            {
   
                return next_context_data_;
            }

            /**
            Returns the index of the parameter set in a chain. The initial parameters
            have index 0 and the index increases sequentially in the parameter chain.
            */
            SEAL_NODISCARD inline std::size_t chain_index() const noexcept
            {
   
                return chain_index_;
            }

        private:
            ContextData(EncryptionParameters parms, MemoryPoolHandle pool) : pool_(std::move(pool)), parms_(parms)
            {
   
                if (!pool_)
                {
   
                    throw std::invalid_argument("pool is uninitialized");
                }
            }

            MemoryPoolHandle pool_;

            EncryptionParameters parms_;

            EncryptionParameterQualifiers qualifiers_;

            util::Pointer<util::RNSTool> rns_tool_;

            util::Pointer<util::NTTTables> small_ntt_tables_;

            util::Pointer<util::NTTTables> plain_ntt_tables_;

            util::Pointer<util::GaloisTool> galois_tool_;

            util::Pointer<std::uint64_t> total_coeff_modulus_;

            int total_coeff_modulus_bit_count_ = 0;

            util::Pointer<util::MultiplyUIntModOperand> coeff_div_plain_modulus_;

            std::uint64_t plain_upper_half_threshold_ = 0;

            util::Pointer<std::uint64_t> plain_upper_half_increment_;

            util::Pointer<std::uint64_t> upper_half_threshold_;

            util::Pointer<std::uint64_t> upper_half_increment_;

            std::uint64_t coeff_modulus_mod_plain_modulus_ = 0;

            std::weak_ptr<const ContextData> prev_context_data_;

            std::shared_ptr<const ContextData> next_context_data_{
    nullptr };

            std::size_t chain_index_ = 0;
        };

剩余部分

validate 函数验证参数的合法性

        /**
        Creates an instance of SEALContext and performs several pre-computations
        on the given EncryptionParameters.

        @param[in] parms The encryption parameters
        @param[in] expand_mod_chain Determines whether the modulus switching chain
        should be created
        @param[in] sec_level Determines whether a specific security level should be
        enforced according to HomomorphicEncryption.org security standard
        */
        SEALContext(
            const EncryptionParameters &parms, bool expand_mod_chain = true,
            sec_level_type sec_level = sec_level_type::tc128)
            : SEALContext(parms, expand_mod_chain, sec_level, MemoryManager::GetPool())
        {
   }

        /**
        Creates a new SEALContext by copying a given one.

        @param[in] copy The SEALContext to copy from
        */
        SEALContext(const SEALContext &copy) = default;

        /**
        Creates a new SEALContext by moving a given one.

        @param[in] source The SEALContext to move from
        */
        SEALContext(SEALContext &&source) = default;

        /**
        Copies a given SEALContext to the current one.

        @param[in] assign The SEALContext to copy from
        */
        SEALContext &operator=(const SEALContext &assign) = default;

        /**
        Moves a given SEALContext to the current one.

        @param[in] assign The SEALContext to move from
        */
        SEALContext &operator=(SEALContext &&assign) = default;

        /**
        Returns the ContextData corresponding to encryption parameters with a given
        parms_id. If parameters with the given parms_id are not found then the
        function returns nullptr.

        @param[in] parms_id The parms_id of the encryption parameters
        */
        SEAL_NODISCARD inline std::shared_ptr<const ContextData> get_context_data(parms_id_type parms_id) const
        {
   
            auto data = context_data_map_.find(parms_id);
            return (data != context_data_map_.end()) ? data->second : std::shared_ptr<ContextData>{
    nullptr };
        }

        /**
        Returns the ContextData corresponding to encryption parameters that are
        used for keys.
        */
        SEAL_NODISCARD inline std::shared_ptr<const ContextData> key_context_data() const
        {
   
            auto data = context_data_map_.find(key_parms_id_);
            return (data != context_data_map_.end()) ? data->second : std::shared_ptr<ContextData>{
    nullptr };
        }

        /**
        Returns the ContextData corresponding to the first encryption parameters
        that are used for data.
        */
        SEAL_NODISCARD inline std::shared_ptr<const ContextData> first_context_data() const
        {
   
            auto data = context_data_map_.find(first_parms_id_);
            return (data != context_data_map_.end
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值