东西湖区建设局网站,网站片头动画用什么软件做的,大连地区做网站,厦门网站建设培训学校写在前面#xff1a; 本篇继续上篇的测试#xff0c;首先针对密文深度乘法情况#xff0c;虽然密文乘法本就是应该尽量避免的#xff08;时间和内存成本过高#xff09;#xff0c;更不用说深度乘法了#xff0c;但是为了测试的完整性#xff0c;还是做一下方便大家比对…写在前面 本篇继续上篇的测试首先针对密文深度乘法情况虽然密文乘法本就是应该尽量避免的时间和内存成本过高更不用说深度乘法了但是为了测试的完整性还是做一下方便大家比对。 其次是关于参数设置对内存占用的影响这个十分重要因为我们在跑模型的时候经常进程被 kill因为确实是密文出乎意料的大后面根据测试数据大家就能看出来。
一、测试配置
因为和之前的设置一样这里就不多介绍了直接放代码。
1.1 前置设置
EncryptionParameters parms(scheme_type::ckks);
size_t poly_modulus_degree 8192;
parms.set_poly_modulus_degree(poly_modulus_degree);
parms.set_coeff_modulus(CoeffModulus::Create(poly_modulus_degree, { 50, 30, 30, 50 }));
double scale pow(2.0, 30);
SEALContext context(parms);KeyGenerator keygen(context);
auto secret_key keygen.secret_key();
PublicKey public_key;
keygen.create_public_key(public_key);
RelinKeys relin_keys;
keygen.create_relin_keys(relin_keys);
GaloisKeys gal_keys;
keygen.create_galois_keys(gal_keys);
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
CKKSEncoder encoder(context);
size_t slot_count encoder.slot_count();
1.2 输入设置
为了具有对比参考价值这里输入也设置成一样不过对三个乘数进行加密。
vectordouble the_input;
the_input.reserve(slot_count);
for (size_t i 0; i slot_count; i){the_input.push_back((double)i);
}
Plaintext the_input_plain;
encoder.encode(the_input, scale, the_input_plain);
Ciphertext the_input_enc;
encryptor.encrypt(the_input_plain, the_input_enc);Plaintext const_plain_1, const_plain_2, const_plain_3;
encoder.encode(3.14, scale, const_plain_1);
encoder.encode(3.14, scale, const_plain_2);
encoder.encode(3.14, scale, const_plain_3);
Ciphertext const_cipher_1, const_cipher_2, const_cipher_3;
encryptor.encrypt(const_plain_1, const_cipher_1);
encryptor.encrypt(const_plain_2, const_cipher_2);
encryptor.encrypt(const_plain_3, const_cipher_3); 二、密文乘法测试 跟上篇一样每乘一次进行解密输出便于查看中间结果信息。基于之前理论继续 三次乘法两次 Rescale。
2.1 乘法设置及密文大小观察
先写一下乘法代码注意所用的乘法函数和之前不同
evaluator.multiply_inplace(the_input_enc, const_cipher_1);
evaluator.rescale_to_next_inplace(the_input_enc);evaluator.mod_switch_to_inplace(const_cipher_2, the_input_enc.parms_id());
const_cipher_2.scale() the_input_enc.scale();
evaluator.multiply_inplace(the_input_enc, const_cipher_2);evaluator.rescale_to_next_inplace(the_input_enc);evaluator.mod_switch_to_inplace(const_cipher_3, the_input_enc.parms_id());
const_cipher_3.scale() the_input_enc.scale();
evaluator.multiply_inplace(the_input_enc, const_cipher_3);decryptor.decrypt(the_input_enc, the_input_plain);
encoder.decode(the_input_plain, the_input);
先进行两次乘法查看中间结果这里输出一下 密文大小 对比之前的明文乘法密文大小产生了变化明文乘法后大小不变这里密文相乘后结果的密文大小达到了3第二次乘法后大小变成了4当然这里容量的变化比较明显不过不知道其和大小的具体区别。 2.2 重新线性化观察
引入重新线性化继续观察 此处可以发现每次重新线性化后密文大小会减小到2但是不会改变容量。另外最后一位的精确值是 40375.062 上面对第二次乘法和第二次重新线性化后都进行了解密对比不进行重新线性化精度并未明显增强。因为 CKKS 没有噪声预算的概念所以重新线性化在此处并未观察到除减小密文外明显的其他增益效果。 三、深度 密文乘法测试
接下来将 coeff_modulus 的长度为 4 和 5 分别进行测试。 下面也进行了重新线性化 3.1 长度为4的模数链
scale 30coeff_modulus 160 (50 30 30 50) bits 果然想进行第三次乘法会报错scale out of bounds
按照上篇的理论当处在模数链底层时乘法结果的 scale 要小于 coeff_modulus 第一位。 那更改参数为scale 29coeff_modulus 176 (59 29 29 59) bits 果然就不报错成功进行了第三次密文乘法。但是第二次乘法结果还近似正确第三次结果就不正确了第一位本应该是0的证明此种参数配置虽然可以乘但是精度严重不足。 3.2 长度为 5 的模数链
既然上面的结论同上篇相同那同理继续拉长模数链为了减少冗余只截后面乘法结果scale 30coeff_modulus 190 (50 30 30 30 50) bits 第三次乘法后第三位的精确结果是61.9183最后一位应该是126777.6947。可以看出精度还可以。
另外为了严谨我还尝试了不进行重新线性化的三次密文乘法结果为 密文长度从一开始的2增长到了5但是解密的结果与上面近似。再次验证了重新线性化并未带来精确度的提升。
3.3 深度乘法总结
本节的测试与上篇明文乘法的结论相同即
模数链限制了乘法深度准确说是 Rescale 次数处在模数链底的时候较为特殊注意设置 coeff_modulus 第一位大于乘后 scale要想提高精度就要适当拉长模数链但是代价更大下面会测试。
四、参数设置对内存占用的影响
先叠甲 本节测试是统计不同参数设置对内存占用的影响。不同性能的计算机测试数据可能有差异且我是用 Debug 模式运行监视内存占用得出的数据内存本身包含了 “上下文环境、各种密钥和实例”甚至我每次运行都有波动故不能当作精确值来推算只具有相对意义。 测试说明为了减少上述因素带来的差异故编码和加密的数量设置的比较多 设置模式为 CKKS方案设置的 poly_modulus_degree 8192创建 二维 Plaintext 和 Ciphertext 数组。步骤如下
创建 [50,50] 的 Plaintext 数组即一共 2500 个明文块二层循环遍历数组依次对每块进行编码编码内容一样都是相同的4096个数编码结束后统计当前的 内存占用 和 程序运行时间创建 [50,50] 的 Ciphertext 数组即一共 2500 个密文块二层循环遍历数组依次对每块明文加密后放入对应密文块加密结束后统计当前的 内存占用 和 程序运行时间。 这里测试的含义是poly_modulus_degree 8192 时不同参数设置下编码 2500个 明文块以及加密 2500 个密文块。对应能存储的数据数量为 。 因为测试比较无聊这里直接上结果再次强调因为波动的原因忽略小差异 从表中发现结论
明文块的大小 和 编码时间 相对友好密文块大小 和 加密的运行时间 就很夸张了纵向来看调大中间值 和 scale几乎不会影响内存占用横向来看加长模数链会同时增加明文块和密文块的大小 上节提到了除了加大scale加长模数链能提高结果精度但是这里会加大内存。所以第三条结论比较重要为此再追加测试 证明确实加长模数链会加大明文和密文的内存相应的计算时长应该也会增长因为 编码 和 加密 时间确实长了。另外本次虽然只做了 CKKS 方案但是 coeff_modulus 的设置相同故其他方案的结论应该也类似。 五、本篇总结 本篇继续上篇针对 CKKS 方案的测试首先证明了 重新线性化 虽然会减少密文长度但是并不会对 计算结果的精度 有明显的影响模数链的长度确实会限制乘法深度具体来说是 Rescale 次数这点上密文乘法和明文乘法相同 上篇中证明了 增加 scale 会提高精度本篇也继续证明了 增长模数链 也能增加精度但是内存测试后前者 scale 不会提高内存后者会增加 内存成本 和 时间成本。 总结会发现在应用同态加密的时候首先 乘法深度很是受限其次 内存成本 和 时间成本都是很需要考量的。故在设计算法的时候要综合考虑多方面因素还是比较费工夫的。