SEAL參數(3.1.0)

SEAL參數設置


文件原位置SEAL/encryptionparams.h

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

#pragma once

#include <iostream>
#include <numeric>
#include <memory>
#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; });
        }
    };
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章