SEAL全同态加密开源库(十一) BFV-源码浅析(2)

2021SC@SDUSC

2021-12-12

前言

从本篇开始,接上一篇的BFV分析,这里我们继续分析BFV源码。争取本篇结束战斗。
与之前的工作相比,这些代码显得更具整体性,也能更好体现出SEAL的工作原理以及流程,算是对前面的集大成者了,因此很有分析的必要。

BFV-2

本篇我们将继续分析examples/1_bfv_basics.cpp。看一看SEAL对于bfv是如何实现的。
先看整体的运行效果:
来自example.cpp,输入1即可得到BFV方案的运行示例。

Microsoft SEAL version: 3.7.1
+---------------------------------------------------------+
| The following examples should be executed while reading |
| comments in associated files in native/examples/.       |
+---------------------------------------------------------+
| Examples                   | Source Files               |
+----------------------------+----------------------------+
| 1. BFV Basics              | 1_bfv_basics.cpp           |
| 2. Encoders                | 2_encoders.cpp             |
| 3. Levels                  | 3_levels.cpp               |
| 4. CKKS Basics             | 4_ckks_basics.cpp          |
| 5. Rotation                | 5_rotation.cpp             |
| 6. Serialization           | 6_serialization.cpp        |
| 7. Performance Test        | 7_performance.cpp          |
+----------------------------+----------------------------+
[      0 MB] Total allocation from the memory pool

> Run example (1 ~ 7) or exit (0): 1

+-------------------------------------+
|         Example: BFV Basics         |
+-------------------------------------+
Line 132 --> Set encryption parameters and print
/
| Encryption parameters :
|   scheme: BFV
|   poly_modulus_degree: 4096
|   coeff_modulus size: 109 (36 + 36 + 37) bits
|   plain_modulus: 1024
\
Parameter validation (success): valid

~~~~~~ A naive way to calculate 4(x^2+1)(x+1)^2. ~~~~~~
Line 212 --> Express x = 6 as a plaintext polynomial 0x6.
Line 223 --> Encrypt x_plain to x_encrypted.
    + size of freshly encrypted x: 2
    + noise budget in freshly encrypted x: 55 bits
    + decryption of x_encrypted: 0x6 ...... Correct.
Line 270 --> Compute x_sq_plus_one (x^2+1).
    + size of x_sq_plus_one: 3
    + noise budget in x_sq_plus_one: 33 bits
    + decryption of x_sq_plus_one: 0x25 ...... Correct.
Line 300 --> Compute x_plus_one_sq ((x+1)^2).
    + size of x_plus_one_sq: 3
    + noise budget in x_plus_one_sq: 33 bits
    + decryption of x_plus_one_sq: 0x31 ...... Correct.
Line 315 --> Compute encrypted_result (4(x^2+1)(x+1)^2).
    + size of encrypted_result: 5
    + noise budget in encrypted_result: 4 bits
NOTE: Decryption can be incorrect if noise budget is zero.

~~~~~~ A better way to calculate 4(x^2+1)(x+1)^2. ~~~~~~
Line 353 --> Generate relinearization keys.
Line 361 --> Compute and relinearize x_squared (x^2),
             then compute x_sq_plus_one (x^2+1)
    + size of x_squared: 3
    + size of x_squared (after relinearization): 2
    + noise budget in x_sq_plus_one: 33 bits
    + decryption of x_sq_plus_one: 0x25 ...... Correct.
Line 376 --> Compute x_plus_one (x+1),
             then compute and relinearize x_plus_one_sq ((x+1)^2).
    + size of x_plus_one_sq: 3
    + noise budget in x_plus_one_sq: 33 bits
    + decryption of x_plus_one_sq: 0x31 ...... Correct.
Line 390 --> Compute and relinearize encrypted_result (4(x^2+1)(x+1)^2).
    + size of encrypted_result: 3
    + size of encrypted_result (after relinearization): 2
    + noise budget in encrypted_result: 11 bits

NOTE: Notice the increase in remaining noise budget.
Line 407 --> Decrypt encrypted_result (4(x^2+1)(x+1)^2).
    + decryption of 4(x^2+1)(x+1)^2 = 0x54 ...... Correct.

Line 425 --> An example of invalid parameters
/
| Encryption parameters :
|   scheme: BFV
|   poly_modulus_degree: 2048
|   coeff_modulus size: 109 (36 + 36 + 37) bits
|   plain_modulus: 1024
\
Parameter validation (failed): parameters are not compliant with HomomorphicEncryption.org security standard

+---------------------------------------------------------+
| The following examples should be executed while reading |
| comments in associated files in native/examples/.       |
+---------------------------------------------------------+
| Examples                   | Source Files               |
+----------------------------+----------------------------+
| 1. BFV Basics              | 1_bfv_basics.cpp           |
| 2. Encoders                | 2_encoders.cpp             |
| 3. Levels                  | 3_levels.cpp               |
| 4. CKKS Basics             | 4_ckks_basics.cpp          |
| 5. Rotation                | 5_rotation.cpp             |
| 6. Serialization           | 6_serialization.cpp        |
| 7. Performance Test        | 7_performance.cpp          |
+----------------------------+----------------------------+
[      8 MB] Total allocation from the memory pool

下面我们可以分析BFV源码了。
在此示例中,我们演示了使用 BFV 加密方案对加密整数执行简单计算(多项式评估)。
第一个任务是设置 EncryptionParameters 类的实例。
了解不同参数的行为方式、它们如何影响加密方案、性能和安全级别至关重要。需要设置三个加密参数:
- poly_modulus_degree(多项式模数的程度);
- coeff_modulus([密文]系数模数);
- plain_modulus(明文模数;仅适用于 BFV 方案)。
BFV 方案不能对加密数据执行任意计算。相反,每个密文都有一个特定的数量,称为“不变噪声预算”——或简称“噪声预算”——以比特为单位。新加密密文中的噪声预算(初始噪声预算)由加密参数决定。同态运算以同样由加密参数确定的速率消耗噪声预算。在 BFV 中,允许对加密数据进行的两个基本操作是加法和乘法,其中加法通常可以被认为是几乎无代价的,与乘法相比的噪声预算消耗相比。由于噪声预算消耗在顺序乘法中复合,因此选择适当加密参数的最重要因素是用户想要对加密数据进行评估的算术电路的乘法深度。一旦密文的噪声预算达到零,它就会变得太损坏而无法解密。因此,必须选择足够大的参数以支持所需的计算;否则即使使用密钥也无法理解结果。

EncryptionParameters parms(scheme_type::bfv);

我们设置的第一个参数是“多项式模数”的次数。 这必须是 2 的正幂,表示二次分圆多项式的次数;没有必要理解这意味着什么。
较大的 poly_modulus_degree 使密文大小更大且所有操作更慢,但可以实现更复杂的加密计算。 推荐值为1024、2048、4096、8192、16384、32768,但也有可能超出这个范围。
在本例中,我们使用相对较小的多项式模数。 任何比这更小的东西都将只适用非常有限的加密计算。

size_t poly_modulus_degree = 4096;
parms.set_poly_modulus_degree(poly_modulus_degree);

这个函数如下:

inline void set_poly_modulus_degree(std::size_t poly_modulus_degree)
        {
            if (scheme_ == scheme_type::none && poly_modulus_degree)
            {
                throw std::logic_error("poly_modulus_degree is not supported for this scheme");
            }

            // Set the degree
            poly_modulus_degree_ = poly_modulus_degree;

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

接下来我们设置[密文]“系数模数”(coeff_modulus)。该参数是一个大整数,它是不同质数的乘积,每个质数最多 60 位。它表示为这些素数的向量,每个素数都由 Modulus 类的一个实例表示。 coeff_modulus 的位长是指其质因数的位长之和。

更大的 coeff_modulus 意味着更大的噪声预算,因此更加密的计算能力。但是,coeff_modulus 的总比特长度的上限由 poly_modulus_degree 确定,如下所示:

    +------------------------------------------------- ---+
    | poly_modulus_degree |最大 coeff_modulus 位长 |
    +---------------------+---------------------------- ---+
    | 1024 | 27 |
    | 2048 | 54 |
    | 4096 | 109 |
    | 8192 |  218 |
    | 16384 | 438 |
    | 32768 | 881 |
    +---------------------+---------------------------- ---+

这些数字也可以在函数 SEAL_HE_STD_PARMS_128_TC 中编码的 native/src/seal/util/hestdparms.h 中找到,也可以从函数CoeffModulus::MaxBitCount(poly_modulus_degree)。
例如,如果 poly_modulus_degree 为 4096,则 coeff_modulus 可以由三个 36 位素数(108 位)组成。
Microsoft SEAL 附带用于选择 coeff_modulus 的辅助函数。
对于新用户,最简单的方法是简单地使用 CoeffModulus::BFVDefault(poly_modulus_degree),它返回 std::vector,其中包含对给定 poly_modulus_degree 的一个通常不错的选择。

parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));

函数具体实现如下:

inline void set_coeff_modulus(const std::vector<Modulus> &coeff_modulus)
        {
            // Check that a scheme is set
            if (scheme_ == scheme_type::none)
            {
                if (!coeff_modulus.empty())
                {
                    throw std::logic_error("coeff_modulus is not supported for this scheme");
                }
            }
            else 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();
        }

下一步是设置明文模数参数。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于你的问题,我会尽力回答。不过需要说明的是,我是一个语言模型,并不能直接进行代码实现和运行。以下是基于同态加密SEAL实现同态算法BFV并验证其满足同态性的流程: 1. 安装SEAL并配置环境。SEAL是一个用于实现同态加密的C++,可以在官网(https://www.microsoft.com/en-us/research/project/simple-encrypted-arithmetic-library-seal/)下载。安装完成后需要进行环境配置,主要是设置编译器和SEAL的路径等。 2. 生成加密参数。BFV算法需要一些参数来进行加密和计算,如多项式次数、扰动项数量、模数等。可以使用SEAL提供的工具程序生成这些参数,也可以手动设置。 3. 加密数据。使用SEAL提供的API对需要计算的数据进行加密,得到密文。注意,加密后的数据格式与原始数据不同,需要进行转换。 4. 进行同态计算。使用SEAL提供的API对密文进行同态计算,得到结果密文。BFV算法支持加法和乘法运算,可以进行多次计算。 5. 解密结果。使用SEAL提供的API将结果密文解密得到明文结果。 6. 检验同态性。对于加法和乘法运算,需要验证其是否满足同态性质。即对于两个明文x和y,其加密结果密文为c1和c2,加法的结果为c3,有decrypt(c3) = decrypt(c1) + decrypt(c2);乘法的结果为c3,有decrypt(c3) = decrypt(c1) * decrypt(c2)。 以上就是基于同态加密SEAL实现同态算法BFV并验证其满足同态性的流程。需要注意的是,BFV算法虽然可以实现同态,但是其计算效率较低,且只能处理有限的数据范围。因此在实际应用中需要根据具体情况选择适当的同态加密算法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值