SEAL参数(3.1.0)

SEAL参数设置


文件原位置SEAL/encryptionparams.h

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

#pragma once

#include 
#include 
#include 
#include "seal/util/defines.h"
#include "seal/util/globals.h"
#include "seal/randomgen.h"
#include "seal/smallmodulus.h"
#include "seal/util/hash.h"
#include "seal/memorymanager.h"

namespace seal
{
	// 加密模式类型,只有两种加密方案
    enum class scheme_type : std::uint8_t
    {
        BFV = 0x1,
        CKKS = 0x2
    };
	// 判断是不是两种加密方案之一
    inline bool is_valid_scheme(scheme_type scheme) noexcept
    {
        return (scheme == scheme_type::BFV) || 
            (scheme == scheme_type::CKKS); 
    }

    /**
    The data type to store unique identifiers of encryption parameters.
    */
    // 用于存储加密参数的唯一标识符的数据类型。一个哈希值。
    using parms_id_type = util::HashFunction::sha3_block_type;

    /**
    A parms_id_type value consisting of zeros.
    */
    // 可以含0的加密参数标识符
    static constexpr parms_id_type parms_id_zero =
        util::HashFunction::sha3_zero_block;

    /**
    Represents user-customizable encryption scheme settings. The parameters (most
    importantly poly_modulus, coeff_modulus, plain_modulus) significantly affect
    the performance, capabilities, and security of the encryption scheme. Once
    an instance of EncryptionParameters is populated with appropriate parameters,
    it can be used to create an instance of the SEALContext class, which verifies
    the validity of the parameters, and performs necessary pre-computations.

    Picking appropriate encryption parameters is essential to enable a particular
    application while balancing performance and security. Some encryption settings
    will not allow some inputs (e.g. attempting to encrypt a polynomial with more
    coefficients than poly_modulus or larger coefficients than plain_modulus) or,
    support the desired computations (with noise growing too fast due to too large
    plain_modulus and too small coeff_modulus).

    @par parms_id
    The EncryptionParameters class maintains at all times a 256-bit SHA-3 hash of
    the currently set encryption parameters. This hash acts as a unique identifier
    of the encryption parameters and is used by all further objects created for
    these encryption parameters. The parms_id is not intended to be directly modified
    by the user but is used internally for pre-computation data lookup and input
    validity checks. In modulus switching the user can use the parms_id to map the
    chain of encryption parameters.

    @par Thread Safety
    In general, reading from EncryptionParameters is thread-safe, while mutating 
    is not.

    @warning Choosing inappropriate encryption parameters may lead to an encryption
    scheme that is not secure, does not perform well, and/or does not support the
    input and computation of the desired application. We highly recommend consulting
    an expert in RLWE-based encryption when selecting parameters, as this is where
    inexperienced users seem to most often make critical mistakes.
    */
    /**
    表示用户可自定义的加密方案设置。参数(最重要的是poly_modulus,coeff_modulus,plain_modulus)显着影响加密方案
    的性能,功能和安全性。一旦使用适当的参数填充EncryptionParameters的实例,它就可以用于创建SEALContext类的实例,
    该实例验证参数的有效性,并执行必要的预计算。

    选择适当的加密参数对于在平衡性能和安全性的同时启用特定应用程序至关重要。一些加密设置将不允许一些输入(例如,尝试
    加密具有比poly_modulus更大的系数的多项式或比plain_modulus更大的系数),或者支持期望的计算(由于太大的
    plain_modulus和太小的coeff_modulus,噪声增长得太快)。

    @par parms_id
    EncryptionParameters类始终维护当前设置的加密参数的256位SHA-3哈希值。此哈希充当加密参数的唯一标识符,并由为这些
    加密参数创建的所有其他对象使用。 parms_id不是由用户直接修改,而是在内部用于预计算数据查找和输入有效性检查。在模
    数切换中,用户可以使用parms_id来映射加密参数链。

    @par 线程安全
    通常,从EncryptionParameters读取是线程安全的,而变异则不是。

    @warning 选择不适当的加密参数可能会导致加密方案不安全,性能不佳,和/或不支持所需应用程序的输入和计算。我们强烈建
    议在选择参数时咨询基于RLWE的加密专家,因为这是缺乏经验的用户最常犯错误的地方。
    */
    class EncryptionParameters
    {
    public:
        /**
        Creates an empty set of encryption parameters. At a minimum, the user needs 
        to specify the parameters poly_modulus, coeff_modulus, and plain_modulus 
        for the parameters to be usable.

        @throw std::invalid_argument if scheme is not supported
        @see scheme_type for the supported schemes
        */
        /**
         创建一组空的加密参数。 用户至少需要为可用的参数指定参数poly_modulus,coeff_modulus和plain_modulus。

         @throw std :: invalid_argument如果不支持scheme
         @see 支持方案的scheme_type
        */
        EncryptionParameters(scheme_type scheme)
        {
            // Check that a valid scheme is given
            // 检查是否给出了有效的方案
            if (!is_valid_scheme(scheme))
            {
                throw std::invalid_argument("unsupported scheme");
            }

            scheme_ = scheme;
            // 计算参数id
            compute_parms_id();
        }

        /**
        Creates a copy of a given instance of EncryptionParameters.

        @param[in] copy The EncryptionParameters to copy from
        */
        // 深拷贝
        EncryptionParameters(const EncryptionParameters &copy) = default;

        /**
        Overwrites the EncryptionParameters instance with a copy of a given instance.

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

        /**
        Creates a new EncryptionParameters instance by moving a given instance.

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

        /**
        Overwrites the EncryptionParameters instance by moving a given instance.

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

        /**
        Sets the degree of the polynomial modulus parameter to the specified value.
        The polynomial modulus directly affects the number of coefficients in 
        plaintext polynomials, the size of ciphertext elements, the computational 
        performance of the scheme (bigger is worse), and the security level (bigger 
        is better). In SEAL the degree of the polynomial modulus must be a power 
        of 2 (e.g.  1024, 2048, 4096, 8192, 16384, or 32768).

        @param[in] poly_modulus_degree The new polynomial modulus degree
        */
        /**
         将多项式模数参数的度数设置为指定值。 多项式模数直接影响明文多项式中的系数数,密文元素的大小,方案的计算性能
         (越大越好)和安全级别(越大越好)。 在SEAL中,多项式模数的程度必须是2的幂(例如
         1024,2048,4096,8192,16384或32768)。

         @param [in] poly_modulus_degree新的多项式模数度
        */
        inline void set_poly_modulus_degree(std::size_t poly_modulus_degree)
        {
            // Set the degree
            poly_modulus_degree_ = poly_modulus_degree;

            // Re-compute the parms_id
            compute_parms_id();
        }

        /**
        Sets the coefficient modulus parameter. The coefficient modulus consists 
        of a list of distinct prime numbers, and is represented by a vector of 
        SmallModulus objects. The coefficient modulus directly affects the size 
        of ciphertext elements, the amount of computation that the scheme can perform 
        (bigger is better), and the security level (bigger is worse). In SEAL each 
        of the prime numbers in the coefficient modulus must be at most 60 bits, 
        and must be congruent to 1 modulo 2*degree(poly_modulus).

        @param[in] coeff_modulus The new coefficient modulus
        @throws std::invalid_argument if size of coeff_modulus is invalid
        */
        /**
         设置系数模数参数。 系数模数由不同素数的列表组成,并由SmallModulus对象的向量表示。 系数模数直接影响密文元素
         的大小,方案可以执行的计算量(越大越好)和安全级别(越大越差)。 在SEAL中,系数模数中的每个素数必须至多为
         60位,并且必须与1模2 *度(poly_modulus)一致。

         @param [in] coeff_modulus新的系数模数
         如果coeff_modulus的大小无效,则@throws std :: invalid_argument
        */
        inline void set_coeff_modulus(const std::vector<SmallModulus> &coeff_modulus)
        {
            // Set the coeff_modulus_
            if (coeff_modulus.size() > SEAL_COEFF_MOD_COUNT_MAX ||
                coeff_modulus.size() < SEAL_COEFF_MOD_COUNT_MIN)
            {
                throw std::invalid_argument("coeff_modulus is invalid");
            }

            coeff_modulus_ = coeff_modulus;

            // Re-compute the parms_id
            compute_parms_id();
        }

        /**
        Sets the plaintext modulus parameter. The plaintext modulus is an integer 
        modulus represented by the SmallModulus class. The plaintext modulus 
        determines the largest coefficient that plaintext polynomials can represent. 
        It also affects the amount of computation that the scheme can perform 
        (bigger is worse). In SEAL the plaintext modulus can be at most 60 bits 
        long, but can otherwise be any integer. Note, however, that some features 
        (e.g. batching) require the plaintext modulus to be of a particular form.

        @param[in] plain_modulus The new plaintext modulus
        @throws std::logic_error if scheme is not scheme_type::BFV
        */
        /**
         设置明文模数参数。 明文模量是由SmallModulus类表示的整数模数。 明文模数确定了明文多项式可以表示的最大系数。
         它还会影响方案可以执行的计算量(更大更糟)。 在SEAL中,明文模数可以是至多60位长,但也可以是任何整数。 然
         而,注意,一些特征(例如,批处理)要求明文模数具有特定形式。

         @param [in] plain_modulus新的明文模数
         @throws std :: logic_error如果scheme不是scheme_type :: BFV
        */
        inline void set_plain_modulus(const SmallModulus &plain_modulus)
        {
            // CKKS does not use plain_modulus
            if (scheme_ != scheme_type::BFV)
            {
                throw std::logic_error("unsupported scheme");
            }

            plain_modulus_ = plain_modulus;

            // Re-compute the parms_id
            compute_parms_id();
        }

        /**
        Sets the plaintext modulus parameter. The plaintext modulus is an integer 
        modulus represented by the SmallModulus class. This constructor instead 
        takes a std::uint64_t and automatically creates the SmallModulus object. 
        The plaintext modulus determines the largest coefficient that plaintext 
        polynomials can represent. It also affects the amount of computation that 
        the scheme can perform (bigger is worse). In SEAL the plaintext modulus 
        can be at most 60 bits long, but can otherwise be any integer. Note, 
        however, that some features (e.g. batching) require the plaintext modulus 
        to be of a particular form.

        @param[in] plain_modulus The new plaintext modulus
        @throws std::invalid_argument if plain_modulus is invalid
        */
        /**
         设置明文模数参数。 明文模量是由SmallModulus类表示的整数模数。 这个构造函数改为使用std :: uint64_t并自动
         创建SmallModulus对象。 明文模数确定了明文多项式可以表示的最大系数。 它还会影响方案可以执行的计算量(更大更
         糟)。 在SEAL中,明文模数可以是至多60位长,但也可以是任何整数。 然而,注意,一些特征(例如,批处理)要求明
         文模数具有特定形式。

         @param [in] plain_modulus新的明文模数
         如果plain_modulus无效,则@throws std :: invalid_argument
        */
        inline void set_plain_modulus(std::uint64_t plain_modulus)
        {
            set_plain_modulus(SmallModulus(plain_modulus));

            // Re-compute the parms_id
            compute_parms_id();
        }

        /**
        Sets the standard deviation of the noise distribution used for error 
        sampling. This parameter directly affects the security level of the scheme. 
        However, it should not be necessary for most users to change this parameter 
        from its default value. 

        @param[in] noise_standard_deviation The new standard deviation
        @throw std::invalid_argument if noise_standard_deviation is negative or 
        too large 
        */
        /**
         设置噪声分布的标准偏差。 此参数直接影响方案的安全级别。 但是,大多数用户不必更改此参数的默认值。

         @param [in] noise_standard_deviation新的标准偏差
         @throw std :: invalid_argument如果noise_standard_deviation为负或
         太大了
        */
        inline void set_noise_standard_deviation(double noise_standard_deviation)
        {
            if (std::signbit(noise_standard_deviation) || 
                (noise_standard_deviation > std::numeric_limits<double>::max() /
                util::global_variables::noise_distribution_width_multiplier))
            {
                throw std::invalid_argument("noise_standard_deviation is invalid");
            }

            noise_standard_deviation_ = noise_standard_deviation;
            noise_max_deviation_ =
                util::global_variables::noise_distribution_width_multiplier *
                noise_standard_deviation_;

            // Re-compute the parms_id
            compute_parms_id();
        }

        /**
        Sets the random number generator factory to use for encryption. By default, 
        the random generator is set to UniformRandomGeneratorFactory::default_factory(). 
        Setting this value allows a user to specify a custom random number generator 
        source. 

        @param[in] random_generator Pointer to the random generator factory
        */
        /**
         设置用于加密的随机数生成器。 默认情况下,随机生成器设置为UniformRandomGeneratorFactory :: default_factory()。 
         设置此值允许用户指定自定义随机数生成器源。

         @param [in] random_generator指向随机生成器的指针
        */
        inline void set_random_generator(
            std::shared_ptr<UniformRandomGeneratorFactory> random_generator)
        {
            random_generator_ = std::move(random_generator);
        }

        /**
        Returns the encryption scheme type.
        */
        /**
         返回加密方案类型。
        */
        inline scheme_type scheme() const
        {
            return scheme_;
        }

        /**
        Returns the degree of the polynomial modulus parameter.
        */
        /**
         返回多项式模数参数的度数。
        */
        inline std::size_t poly_modulus_degree() const
        {
            return poly_modulus_degree_;
        }

        /**
        Returns a const reference to the currently set coefficient modulus parameter.
        */
        /**
         返回当前设置的系数模数参数的const引用。
        */
        inline const std::vector<SmallModulus> &coeff_modulus() const
        {
            return coeff_modulus_;
        }

        /**
        Returns a const reference to the currently set plaintext modulus parameter.
        */
        /**
         返回当前设置的明文模数参数的const引用。
        */
        inline const SmallModulus &plain_modulus() const
        {
            return plain_modulus_;
        }

        /**
        Returns the currently set standard deviation of the noise distribution.
        */
        /**
         返回当前设置的噪声分布标准偏差。
        */
        inline double noise_standard_deviation() const
        {
            return noise_standard_deviation_;
        }

        /**
        Returns the currently set maximum deviation of the noise distribution. 
        This value cannot be directly controlled by the user, and is automatically 
        set to be an appropriate multiple of the noise_standard_deviation parameter.
        */
        /**
         返回当前设置的噪声分布的最大偏差。 该值不能由用户直接控制,并自动设置为noise_standard_deviation参数的适当倍数。
        */
        inline double noise_max_deviation() const
        {
            return noise_max_deviation_;
        }

        /**
        Returns a pointer to the random number generator factory to use for encryption.
        */
        inline std::shared_ptr<UniformRandomGeneratorFactory> random_generator() const
        {
            return random_generator_;
        }

        /**
        Compares a given set of encryption parameters to the current set of 
        encryption parameters. The comparison is performed by comparing the 
        parms_ids of the parameter sets rather than comparing the parameters 
        individually.

        @parms[in] other The EncryptionParameters to compare against
        */
        /**
         将给定的一组加密参数与当前的加密参数集进行比较。 通过比较参数集的parms_ids而不是单独比较参数来执行比较。

         @parms [in]其他要比较的EncryptionParameters
        */
        inline bool operator ==(const EncryptionParameters &other) const
        {
            return (parms_id_ == other.parms_id_);
        }

        /**
        Compares a given set of encryption parameters to the current set of 
        encryption parameters. The comparison is performed by comparing 
        parms_ids of the parameter sets rather than comparing the parameters 
        individually.

        @parms[in] other The EncryptionParameters to compare against
        */
        /**
         将给定的一组加密参数与当前的加密参数集进行比较。 通过比较参数集的parms_ids而不是单独比较参数来执行比较。

         @parms [in]其他要比较的EncryptionParameters
        */
        inline bool operator !=(const EncryptionParameters &other) const
        {
            return (parms_id_ != other.parms_id_);
        }

        /**
        Returns the parms_id of the current parameters. This function is intended
        mainly for internal use.
        */
        /**
         返回当前参数的parms_id。 这个功能是有意的
         主要供内部使用。
        */
        inline auto &parms_id() const
        {
            return parms_id_;
        }

        /**
        Saves EncryptionParameters to an output stream. The output is in binary 
        format and is not human-readable. The output stream must have the "binary" 
        flag set.

        @param[in] stream The stream to save the EncryptionParameters to
        @throws std::exception if the EncryptionParameters could not be written 
        to stream
        */
        /**
         将EncryptionParameters保存到输出流。 输出是二进制格式,不是人类可读的。 输出流必须设置“二进制”标志。

         @param [in] stream将EncryptionParameters保存到的流
         如果无法将EncryptionParameters写入流,则@throws std :: exception
        */
        static void Save(const EncryptionParameters &parms, std::ostream &stream);

        /**
        Loads EncryptionParameters from an input stream.

        @param[in] stream The stream to load the EncryptionParameters from
        @throws std::exception if valid EncryptionParameters could not be read 
        from stream
        */
        static EncryptionParameters Load(std::istream &stream);

    private:
        void compute_parms_id();

        MemoryPoolHandle pool_ = MemoryManager::GetPool();

        scheme_type scheme_;

        std::size_t poly_modulus_degree_ = 0;

        std::vector<SmallModulus> coeff_modulus_{};

        double noise_standard_deviation_ =
            util::global_variables::default_noise_standard_deviation;

        double noise_max_deviation_ =
            util::global_variables::noise_distribution_width_multiplier *
            util::global_variables::default_noise_standard_deviation;

        std::shared_ptr<UniformRandomGeneratorFactory> random_generator_{ nullptr };

        SmallModulus plain_modulus_{};

        parms_id_type parms_id_ = parms_id_zero;
    };
}

/**
Specializes the std::hash template for parms_id_type.
*/
namespace std
{
    template<>
    struct hash<seal::parms_id_type>
    {
        std::size_t operator()(
            const seal::parms_id_type &parms_id) const
        {
            return std::accumulate(parms_id.begin(), parms_id.end(), std::size_t(0),
                [](std::size_t acc, std::uint64_t curr) { return acc ^ curr; });
        }
    };
}

你可能感兴趣的:(SEAL,同态加密)