SEAL开源库源码02

SEAL开源库源码02

本篇的最终目的是要分析 seal/modulus.h

文章目录

seal/version.h

保存版本号信息
具有相同主版本和小版本的库的两个版本完全兼容。它们保证具有相同的公共API。补丁版本号的变化表明完全是内部变化,比如不需要修改公共API的bug修复。微调版本号目前没有使用,预计为0。

#pragma once

#include "seal/util/defines.h"
#include <cstdint>

namespace seal
{
   
    /**
    Holds Microsoft SEAL version information. A SEALVersion contains four values:

        1. The major version number;
        2. The minor version number;
        3. The patch version number;
        4. The tweak version number.

    Two versions of the library with the same major and minor versions are fully
    compatible with each other. They are guaranteed to have the same public API.
    Changes in the patch version number indicate totally internal changes, such
    as bug fixes that require no changes to the public API. The tweak version
    number is currently not used, and is expected to be 0.
    */
    struct SEALVersion
    {
   
        /**
        Holds the major version number.
        */
        std::uint8_t major = SEAL_VERSION_MAJOR;

        /**
        Holds the minor version number.
        */
        std::uint8_t minor = SEAL_VERSION_MINOR;

        /**
        Holds the patch version number.
        */
        std::uint8_t patch = SEAL_VERSION_PATCH;

        std::uint8_t tweak = 0;
    };
} // namespace seal

seal/util/hestdparms.h

定义了一些基于不同安全性的参数选择。
Largest allowed bit counts for coeff_modulus based on the security estimates from HomomorphicEncryption.org security standard. Microsoft SEAL samples the secret key from a ternary {-1, 0, 1} distribution.
位于命名空间seal中的命名空间util中

        /**
        Largest allowed bit counts for coeff_modulus based on the security estimates from
        HomomorphicEncryption.org security standard. Microsoft SEAL samples the secret key
        from a ternary {-1, 0, 1} distribution.
        */
     

128-bit 安全性

// Ternary secret; 128 bits classical security
        SEAL_NODISCARD constexpr int seal_he_std_parms_128_tc(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 27;
            case std::size_t(2048):
                return 54;
            case std::size_t(4096):
                return 109;
            case std::size_t(8192):
                return 218;
            case std::size_t(16384):
                return 438;
            case std::size_t(32768):
                return 881;
            }
            return 0;
        }

192-bit安全性

// Ternary secret; 192 bits classical security
        SEAL_NODISCARD constexpr int seal_he_std_parms_192_tc(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 19;
            case std::size_t(2048):
                return 37;
            case std::size_t(4096):
                return 75;
            case std::size_t(8192):
                return 152;
            case std::size_t(16384):
                return 305;
            case std::size_t(32768):
                return 611;
            }
            return 0;
        }

256-bit安全性

// Ternary secret; 256 bits classical security
        SEAL_NODISCARD constexpr int seal_he_std_parms_256_tc(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 14;
            case std::size_t(2048):
                return 29;
            case std::size_t(4096):
                return 58;
            case std::size_t(8192):
                return 118;
            case std::size_t(16384):
                return 237;
            case std::size_t(32768):
                return 476;
            }
            return 0;
        }

128-bit量子安全性

// Ternary secret; 128 bits quantum security
        SEAL_NODISCARD constexpr int seal_he_std_parms_128_tq(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 25;
            case std::size_t(2048):
                return 51;
            case std::size_t(4096):
                return 101;
            case std::size_t(8192):
                return 202;
            case std::size_t(16384):
                return 411;
            case std::size_t(32768):
                return 827;
            }
            return 0;
        }

192-bit量子安全性

// Ternary secret; 192 bits quantum security
        SEAL_NODISCARD constexpr int seal_he_std_parms_192_tq(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 17;
            case std::size_t(2048):
                return 35;
            case std::size_t(4096):
                return 70;
            case std::size_t(8192):
                return 141;
            case std::size_t(16384):
                return 284;
            case std::size_t(32768):
                return 571;
            }
            return 0;
        }

256-bit量子安全性

// Ternary secret; 256 bits quantum security
        SEAL_NODISCARD constexpr int seal_he_std_parms_256_tq(std::size_t poly_modulus_degree) noexcept
        {
   
            switch (poly_modulus_degree)
            {
   
            case std::size_t(1024):
                return 13;
            case std::size_t(2048):
                return 27;
            case std::size_t(4096):
                return 54;
            case std::size_t(8192):
                return 109;
            case std::size_t(16384):
                return 220;
            case std::size_t(32768):
                return 443;
            }
            return 0;
        }

误差分布的标准差

定义为常量 3.2 3.2 3.2

// Standard deviation for error distribution
        constexpr double seal_he_std_parms_error_std_dev = 3.2;

seal/util/common.h

里面定义的所有函数位于namespace seal中的namespace util中

VoidType结构体 和 seal_void_t类型

template <typename... Ts>
        struct VoidType
        {
   
            using type = void;
        };

        template <typename... Ts>
        using seal_void_t = typename VoidType<Ts...>::type;

seal_for_each_n函数

传入迭代器 first 和 大小 size 和 要执行的函数 func,对每个执行 func 函数

template <typename ForwardIt, typename Size, typename Func>
        inline ForwardIt seal_for_each_n(ForwardIt first, Size size, Func &&func)
        {
   
            for (; size--; (void)++first)
            {
   
                func(*first);
            }
            return first;
        }

seal_apply_impl 和 seal_apply 函数

std::forward通常是用于完美转发的,它会将输入的参数原封不动地传递到下一个函数中,这个“原封不动”指的是,如果输入的参数是左值,那么传递给下一个函数的参数的也是左值;如果输入的参数是右值,那么传递给下一个函数的参数的也是右值。

大概意思就是对 tuple 中 index 元素执行 func 函数,然后返回执行结果。
std::Tuple
函数中的 Tuple 不一定是 std::Tuple

template <typename Func, typename Tuple, std::size_t... Is>
        inline decltype(auto) seal_apply_impl(Func &&func, Tuple &&tp, std::index_sequence<Is...>)
        {
   
            return func(std::get<Is>(std::forward<Tuple>(tp))...);
        }

        template <typename Func, typename Tuple, std::size_t... Is>
        inline decltype(auto) seal_apply(Func &&func, Tuple &&tp)
        {
   
            using iseq_t = std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>;
            return seal_apply_impl(std::forward<Func>(func), std::forward<Tuple>(tp), iseq_t{
   });
        }

IsUInt64 结构体

判断是否是 unsigned int64 类型

        template <typename T, typename...>
        struct IsUInt64
            : std::conditional<
                  std::is_integral<T>::value && std::is_unsigned<T>::value && (sizeof(T) == sizeof(std::uint64_t)),
                  std::true_type, std::false_type>::type
        {
   };

        template <typename T, typename U, typename... Rest>
        struct IsUInt64<T, U, Rest...>
            : std::conditional<IsUInt64<T>::value && IsUInt64<U, Rest...>::value, std::true_type, std::false_type>::type
        {
   };

        template <typename T, typename... Rest>
        constexpr bool is_uint64_v = IsUInt64<T, Rest...>::value;

IsUint32结构体

判断是否为 unsigned int32 类型

        template <typename T, typename...>
        struct IsUInt32
            : std::conditional<
                  std::is_integral<T>::value && std::is_unsigned<T>::value && (sizeof(T) == sizeof(std::uint32_t)),
                  std::true_type, std::false_type>::type
        {
   };

        template <typename T, typename U, typename... Rest>
        struct IsUInt32<T, U, Rest...>
            : std::conditional<IsUInt32<T>::value && IsUInt32<U, Rest...>::value, std::true_type, std::false_type>::type
        {
   };

        template <typename T, typename... Rest>
        constexpr bool is_uint32_v = IsUInt32<T, Rest...>::value;

一些 unsigned 比较运算

包括小于、小于等于、大于、大于等于、等于、不等于

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_lt(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) < static_cast<std::uint64_t>(in2);
        }

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_leq(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) <= static_cast<std::uint64_t>(in2);
        }
        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_gt(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) > static_cast<std::uint64_t>(in2);
        }

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_geq(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) >= static_cast<std::uint64_t>(in2);
        }

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_eq(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) == static_cast<std::uint64_t>(in2);
        }

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_integral<T>::value>,
            typename = std::enable_if_t<std::is_integral<S>::value>>
        SEAL_NODISCARD inline constexpr bool unsigned_neq(T in1, S in2) noexcept
        {
   
            return static_cast<std::uint64_t>(in1) != static_cast<std::uint64_t>(in2);
        }

一些安全的加减乘运算

        template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
        SEAL_NODISCARD inline constexpr T mul_safe(T in1) noexcept
        {
   
            return in1;
        }

        template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
        SEAL_NODISCARD inline constexpr T mul_safe(T in1, T in2)
        {
   
            SEAL_IF_CONSTEXPR(std::is_unsigned<T>::value)
            {
   
                if (in1 && (in2 > (std::numeric_limits<T>::max)() / in1))
                {
   
                    throw std::logic_error("unsigned overflow");
                }
            }
            else
            {
   
                // Positive inputs
                if ((in1 > 0) && (in2 > 0) && (in2 > (std::numeric_limits<T>::max)() / in1))
                {
   
                    throw std::logic_error("signed overflow");
                }
#if (SEAL_COMPILER == SEAL_COMPILER_MSVC) && !defined(SEAL_USE_IF_CONSTEXPR)
#pragma warning(push)
#pragma warning(disable : 4146)
#endif
                // Negative inputs
                else if ((in1 < 0) && (in2 < 0) && ((-in2) > (std::numeric_limits<T>::max)() / (-in1)))
                {
   
                    throw std::logic_error("signed overflow");
                }
                // Negative in1; positive in2
                else if ((in1 < 0) && (in2 > 0) && (in2 > (std::numeric_limits<T>::max)() / (-in1)))
                {
   
                    throw std::logic_error("signed underflow");
                }
#if (SEAL_COMPILER == SEAL_COMPILER_MSVC) && !defined(SEAL_USE_IF_CONSTEXPR)
#pragma warning(pop)
#endif
                // Positive in1; negative in2
                else if ((in1 > 0) && (in2 < 0) && (in2 < (std::numeric_limits<T>::min)() / in1))
                {
   
                    throw std::logic_error("signed underflow");
                }
            }
            return static_cast<T>(in1 * in2);
        }

        template <typename T, typename... Args, typename = std::enable_if_t<std::is_integral<T>::value>>
        SEAL_NODISCARD inline constexpr T mul_safe(T in1, T in2, Args &&...args)
        {
   
            return mul_safe(mul_safe(in1, in2), mul_safe(std::forward<Args>(args)...));
        }

        template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
        SEAL_NODISCARD inline constexpr T add_safe(T in1) noexcept
        {
   
            return in1;
        }

        template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
        SEAL_NODISCARD inline constexpr T add_safe(T in1, T in2)
        {
   
            SEAL_IF_CONSTEXPR(std::is_unsigned<T>::value)
            {
   
                if (in2 > (std::numeric_limits<T>::max)() - in1)
                {
   
                    throw std::logic_error("unsigned overflow");
                }
            }
            else
            {
   
                if (in1 > 0 && (in2 > (std::numeric_limits<T>::max)() - in1))
                {
   
                    throw std::logic_error("signed overflow");
                }
                else if (in1 < 0 && (in2 < (std::numeric_limits<T>::min)() - in1))
                {
   
                    throw std::logic_error("signed underflow");
                }
            }
            return static_cast<T>(in1 + in2);
        }

        template <typename T, typename... Args, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
        SEAL_NODISCARD inline constexpr T add_safe(T in1, T in2, Args &&...args)
        {
   
            return add_safe(add_safe(in1, in2), add_safe(std::forward<Args>(args)...));
        }

        template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
        SEAL_NODISCARD inline T sub_safe(T in1, T in2)
        {
   
            SEAL_IF_CONSTEXPR(std::is_unsigned<T>::value)
            {
   
                if (in1 < in2)
                {
   
                    throw std::logic_error("unsigned underflow");
                }
            }
            else
            {
   
                if (in1 < 0 && (in2 > (std::numeric_limits<T>::max)() + in1))
                {
   
                    throw std::logic_error("signed underflow");
                }
                else if (in1 > 0 && (in2 < (std::numeric_limits<T>::min)() + in1))
                {
   
                    throw std::logic_error("signed overflow");
                }
            }
            return static_cast<T>(in1 - in2);
        }

fits_in 函数,判断类型是否兼容

        template <
            typename T, typename S, typename = std::enable_if_t<std::is_arithmetic<T>::value>,
            typename = std::enable_if_t<std::is_arithmetic<S>::value>>
        SEAL_NODISCARD inline constexpr bool fits_in(S value SEAL_MAYBE_UNUSED) noexcept
        {
   
            bool result = false;

            SEAL_IF_CONSTEXPR(std::is_same<T, S>::value)
            {
   
                // Same type
                result = true;
            }
            else SEAL_IF_CONSTEXPR(sizeof(S) <= sizeof(T))
            {
   
                // Converting to bigger type
                SEAL_IF_CONSTEXPR(std::is_integral<T>::value && std::is_integral<S>::value)
                {
   
                    // Converting to at least equally big integer type
                    SEAL_IF_CONSTEXPR(
                        (std::is_unsigned<T>::value && std::is_unsigned<S>::value) ||
                        (!std::is_unsigned<T>::value && !std::is_unsigned<S>::value))
                    {
   
                        <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值