SEAL context(3.1.0)

SEAL参数设置


文件原位置SEAL/context.h

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#pragma once

#include <unordered_map>
#include <functional>
#include <memory>
#include "seal/encryptionparams.h"
#include "seal/memorymanager.h"
#include "seal/util/smallntt.h"
#include "seal/util/baseconverter.h"
#include "seal/util/pointer.h"

namespace seal
{
    /**
    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 EncryptionParameterQualifiers, and in most
    cases never have to worry about them at all.

    @see EncryptionParameters::GetQualifiers for obtaining the EncryptionParameterQualifiers
    corresponding to the current parameter set.
    */
    /**
     存储一组加密参数的一组属性(限定符)。 这些参数主要在库的各个部分内部使用,例如, 确定当前支持的算法优化。 限定
     符由SEALContext类自动创建,以静默方式传递给Encryptor,Evaluator和Decryptor等类,更改它们的唯一方法是更改加密
     参数本身。 换句话说,用户永远不必创建自己的EncryptionParameterQualifiers实例,并且在大多数情况下根本不必担心
     它们。

     @see EncryptionParameters :: GetQualifiers,用于获取与当前参数集对应的EncryptionParameterQualifiers。
    */
    struct EncryptionParameterQualifiers
    {
        /**
        If the encryption parameters are set in a way that is considered valid by SEAL, the
        variable parameters_set is set to true.
        */
        /**
         如果加密参数以SEAL认为有效的方式设置,则变量parameters_set设置为true。
        */
        bool parameters_set;

        /**
        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 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.
        */
        /**
         判断FFT是否可用于多项式乘法。 如果多项式模数具有X ^ N + 1的形式,其中N是2的幂,则FFT可以用于以多项式模数
         为模的多项式的快速乘法。 在这种情况下,变量using_fft将设置为true。 但是,目前SEAL要求这是参数有效的情况。 
         因此,如果using_fft为true,则parameters_set只能为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 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.
        */
        /**
         告知NTT是否可用于多项式乘法。 如果系数模数中的素数与1模2N一致,其中X ^ N + 1是多项式模数,N是2的幂,那么
         数论变换(NTT)可用于多项式模的快速乘法 多项式模数和系数模数。 在这种情况下,变量using_ntt将设置为true。 
         但是,目前SEAL要求这是参数有效的情况。 因此,如果using_ntt为true,则parameters_set只能为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.
        */
        /**
         告知加密参数是否支持批处理。 如果明文模数与1模2N一致,其中X ^ N + 1是多项式模数而N是2的幂,则可以使用
         BatchEncoder类将明文元素视为2-by-(N / 2)整数矩阵以明文模数为模。 这称为批处理,允许用户以SIMD方式操作
         矩阵元素(插槽),并旋转矩阵行和列。 当计算易于矢量化时,使用批处理可以产生巨大的性能提升。 如果加密参数支
         持批处理,则变量using_batching将设置为true。
        */
        bool using_fast_plain_lift;

        /**
        Tells whether the encryption parameters are secure based on the standard parameters
        from HomomorphicEncryption.org security standard.
        */
        /**
         根据HomomorphicEncryption.org安全标准中的标准参数,判断加密参数是否安全。
        */
        bool using_he_std_security;

    private:
        EncryptionParameterQualifiers() :
            parameters_set(false),
            using_fft(false),
            using_ntt(false),
            using_batching(false),
            using_fast_plain_lift(false),
            using_he_std_security(false)
        {
        }

        friend class 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.

    @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。

    @see EncryptionParameters了解有关参数的更多详细信息。
    @see EncryptionParameterQualifiers了解有关限定符的更多详细信息。
    * /
    class SEALContext
    {
    public:
        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.
            */
            /**
             返回对基础加密参数的const引用。
            */
            inline auto &parms() const
            {
                return parms_;
            }

            /**
            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.
            */
            /**
             返回与当前加密参数对应的EncryptionParameterQualifiers的副本。 请注意,要更改限定符,必须在对加密参数
             进行适当更改后创建SEALContext的新实例。
            */
            inline auto qualifiers() const
            {
                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.
            */
			/**
             返回指向系数模数中所有素数的预先计算乘积的指针。 加密参数的安全性很大程度上取决于该产品的位长以及多项式
             模数的程度。
            */
            inline const std::uint64_t *total_coeff_modulus() const
            {
                return total_coeff_modulus_.get();
            }

            /**
            Returns the significant bit count of the total coefficient modulus.
            */
            /**
             返回总系数模数的有效位数。
            */
            inline auto total_coeff_modulus_bit_count() const
            {
                return total_coeff_modulus_bit_count_;
            }

            /**
            Returns a const reference to the base converter.
            */
            /**             
            返回对基本转换器的const引用。
            */
            inline auto &base_converter() const
            {
                return base_converter_;
            }

            /**
            Returns a const reference to the NTT tables.返回对NTT表的const引用
            */
            inline auto &small_ntt_tables() const
            {
                return small_ntt_tables_;
            }

            /**
            Returns a const reference to the NTT tables.返回对NTT表的const引用
            */
            inline auto &plain_ntt_tables() const
            {
                return plain_ntt_tables_;
            }

            /**
            Return a pointer to BFV "Delta", i.e. coefficient modulus divided by
            plaintext modulus.返回指向BFV“Delta”的指针,即系数模数除以明文模数。
            */
            inline const std::uint64_t *coeff_div_plain_modulus() const
            {
                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.
            返回整数modulo plain_modulus的上半部分的阈值。(plain_modulus + 1)/ 2
            */
            inline std::uint64_t plain_upper_half_threshold() const
            {
                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.
            返回指向明文上半部增量的指针,即coeff_modulus减去plain_modulus。 如果using_fast_plain_lift为假,则
            上半部分增量表示为完整乘积coeff_modulus的整数,否则按顺序以每个coeff_modulus素数为模。
            */
            inline const std::uint64_t *plain_upper_half_increment() const
            {
                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.
            返回指向相对于总系数模数的上半阈值的指针。 这在CKKS解密中是必需的。
            */
            inline const std::uint64_t *upper_half_threshold() const
            {
                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.
            返回指向用于计算Delta * m的上半部增量并将系数转换为模数coeff_modulus的指针。 例如,明文中的t-1应该变
            为q  -  Delta = Delta * t + r_t(q) -  Delta = Delta *(t-1)+ r_t(q)因此将消息乘以Delta是不够
            的并且还需要 添加r_t(q)。 这正是upper_half_increment。 注意,该操作仅针对负消息系数,即超过
            plain_upper_half_threshold的消息系数。
            */
            inline const std::uint64_t *upper_half_increment() const
            {
                return upper_half_increment_.get();
            }

            /**
            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.
            将shared_ptr返回到与模数转换链中的下一个参数对应的上下文数据。 如果当前数据是链中的最后一个数据,
            则结果为nullptr。
            */
            inline auto next_context_data() const
            {
                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.
            返回链中参数集的索引。 初始参数具有索引0并且索引在参数链中顺序增加。
            */
            inline std::size_t chain_index() const
            {
                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::BaseConverter> base_converter_;

            util::Pointer<util::SmallNTTTables> small_ntt_tables_;

            util::Pointer<util::SmallNTTTables> plain_ntt_tables_;

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

            int total_coeff_modulus_bit_count_;

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

            std::uint64_t plain_upper_half_threshold_;

            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::shared_ptr<const ContextData> next_context_data_{ nullptr };

            std::size_t chain_index_ = 0;
        };

        SEALContext() = delete;

        /**
        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
        */
        static auto Create(const EncryptionParameters &parms, 
            bool expand_mod_chain = true)
        {
            return std::shared_ptr<SEALContext>(
                new SEALContext(parms, expand_mod_chain, 
                MemoryManager::GetPool()));
        }

        /**
        Returns a const reference to ContextData class corresponding to the
        encryption parameters. This is the first set of parameters in a chain
        of parameters when modulus switching is used.
        */
        inline auto context_data() const
        {
            return context_data_map_.at(first_parms_id_);
        }

        /**
        Returns an optional const reference to ContextData class corresponding to
        the 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
        */
        inline auto 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 whether the encryption parameters are valid.
        */
        inline auto parameters_set() const
        {
            return context_data()->qualifiers_.parameters_set;
        }

        /**
        Returns a parms_id_type corresponding to the first set
        of encryption parameters.
        */
        inline auto &first_parms_id() const
        {
            return first_parms_id_;
        }

        /**
        Returns a parms_id_type corresponding to the last set
        of encryption parameters.
        */
        inline auto &last_parms_id() const
        {
            return last_parms_id_;
        }

    private:
        SEALContext(const SEALContext &copy) = delete;

        SEALContext(SEALContext &&source) = delete;

        SEALContext &operator =(const SEALContext &assign) = delete;

        SEALContext &operator =(SEALContext &&assign) = delete;

        /**
        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] pool The MemoryPoolHandle pointing to a valid memory pool
        @throws std::invalid_argument if pool is uninitialized
        */
        SEALContext(EncryptionParameters parms, bool expand_mod_chain,
            MemoryPoolHandle pool);

        ContextData validate(EncryptionParameters parms);

        MemoryPoolHandle pool_;

        parms_id_type first_parms_id_;

        parms_id_type last_parms_id_;

        std::unordered_map<
            parms_id_type, std::shared_ptr<const ContextData>> context_data_map_{};
    };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值