OpenFHE 使用样例

2024-06-02 22:52
文章标签 使用 样例 openfhe

本文主要是介绍OpenFHE 使用样例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考文献:

  • 编译 OpenFHE
  • OpenFHE 源码解析:PKE 部分
  • [ABB+22] Al Badawi A, Bates J, Bergamaschi F, et al. Openfhe: Open-source fully homomorphic encryption library[C]//Proceedings of the 10th Workshop on Encrypted Computing & Applied Homomorphic Cryptography. 2022: 53-63.

文章目录

  • VSCode 的配置
    • 编辑器
    • 调试器
  • GCC 的配置
  • BFV
    • 代码
    • 结果
      • 使用 `BEHZ` 乘法
      • 使用 `HPSPOVERQLEVELED` 乘法
  • BGV
    • 代码
    • 结果
      • 使用 `FIXEDMANUAL` 模切换
      • 使用 `FLEXIBLEAUTO` 模切换
  • CKKS
    • 代码
    • 结果
      • 使用 `FIXEDMANUAL` 模切换
      • 使用 `FLEXIBLEAUTO` 模切换

VSCode 的配置

编辑器

c_cpp_properties.json 如下:

{"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**","/usr/local/include/openfhe/pke","/usr/local/include/openfhe/core","/usr/local/include/openfhe","/usr/local/include/openfhe/binfhe"],"defines": [],"compilerPath": "/usr/bin/gcc","cStandard": "c17","cppStandard": "c++14","intelliSenseMode": "macos-gcc-x64"}],"version": 4
}

调试器

tasks.json 如下:

{"tasks": [{"type": "cppbuild","label": "C/C++: gcc 生成活动文件","command": "/usr/bin/gcc","args": ["-fdiagnostics-color=always","-g","${file}","-o","${fileDirname}/${fileBasenameNoExtension}","-I/usr/local/include/openfhe","-I/usr/local/include/openfhe/pke","-I/usr/local/include/openfhe/core","-I/usr/local/include/openfhe/binfhe","-I/usr/local/include/openfhe/cereal","-L/usr/local/lib","-lstdc++","-lm","-lssl","-lntl","-fopenmp","-fPIC","-lOPENFHEcore","-lOPENFHEpke","-lOPENFHEbinfhe",],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true},"detail": "调试器生成的任务。"}],"version": "2.0.0"
}

GCC 的配置

CMakeLists.txt 如下:

cmake_minimum_required(VERSION 3.10)project(MyCode CXX)set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)#配置编译选项
add_compile_options(-march=native -O3 -lstdc++ -lm -lssl -lntl -pthread -fopenmp -fPIC-mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store-Wno-unused-command-line-argument -Wwrite-strings -v
)#配置头文件和静态库的路径
add_compile_options(-I/usr/local/include/openfhe-I/usr/local/include/openfhe/core-I/usr/local/include/openfhe/pke-I/usr/local/include/openfhe/binfhe-I/usr/local/include/openfhe/cereal-L/usr/local/lib
)#SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/)set(CMAKE_EXE_LINKER_FLAGS "-Wl,--copy-dt-needed-entries") #递归获取动态库的依赖项add_executable(ckks ckks.cpp)
target_link_libraries(ckks OPENFHEcore OPENFHEpke OPENFHEbinfhe)add_executable(use_ckks use_ckks.cpp)
target_link_libraries(use_ckks OPENFHEcore OPENFHEpke OPENFHEbinfhe)add_executable(use_bgv use_bgv.cpp)
target_link_libraries(use_bgv OPENFHEcore OPENFHEpke OPENFHEbinfhe)add_executable(use_bfv use_bfv.cpp)
target_link_libraries(use_bfv OPENFHEcore OPENFHEpke OPENFHEbinfhe)

BFV

代码

BFV 方案使用 MSD 纠错码,不需要模切换。在 Ciphertext<DCRTPoly> 密文中,GetLevel() 总是等于 0 0 0GetNoiseScaleDeg() 记录了乘法深度GetElements().size() 是密文中环元素向量的长度。

对于 CoefPackedPlaintext 打包,明文模数可以是任意的整数,不仅仅是素数或者素数幂。

系数打包的 BFV 用例,

#include <vector>
#include <iostream>
#include "openfhe.h"
#include "cputimer.h"using namespace std;
using namespace lbcrypto;#define endl2 endl << endl
#define pn puts("")#define print_param(ct)                                         \cout << "Level = " << ct->GetLevel() << " | "               \<< "Depth = " << ct->GetNoiseScaleDeg() << " | "       \<< "SKDeg = " << ct->GetElements().size() - 1 << " | " \<< endl;#define print_pt(pt) \cout << "Result: " << pt << endl2;int main()
{GetFrequency();cout << endl;size_t ringDim = 16384;       // 必须是二的幂次size_t plaintextModulus = 17; // 系数打包可以是任意整数size_t multDepth = 10;size_t maxRelinSkDeg = 4;CCParams<CryptoContextBFVRNS> parameters;parameters.SetSecurityLevel(HEStd_NotSet); // 如果不设置安全级别,则需要手动给出环维度parameters.SetRingDim(ringDim);parameters.SetPlaintextModulus(plaintextModulus);parameters.SetMultiplicativeDepth(multDepth);parameters.SetMaxRelinSkDeg(maxRelinSkDeg);parameters.SetKeySwitchTechnique(HYBRID);// BEHZ,整数指令的 RNS 扩展,乘法速度很慢// HPSPOVERQLEVELED,浮点指令的 RNS 扩展,并且隐式模切换parameters.SetMultiplicationTechnique(HPSPOVERQLEVELED);CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);cc->Enable(PKE);cc->Enable(KEYSWITCH);cc->Enable(LEVELEDSHE);cout << "CyclotomicOrder = " << cc->GetCyclotomicOrder() << endl<< "RingDimension = " << cc->GetRingDimension() << endl<< "Level = " << cc->GetKeyGenLevel() << endl<< "Modulus = " << cc->GetModulus() << endl<< "ModulusBits = " << cc->GetModulus().GetLengthForBase(2) << endl<< "RootOfUnity = " << cc->GetRootOfUnity() << endl<< "PlaintextModulus = " << cc->GetEncodingParams()->GetPlaintextModulus() << endl<< "BatchSize = " << cc->GetEncodingParams()->GetBatchSize() << endl<< "PlaintextGenerator = " << cc->GetEncodingParams()->GetPlaintextGenerator() << endl<< endl2;/***************************************************************************************************/auto keys = cc->KeyGen();cc->EvalMultKeysGen(keys.secretKey);cc->EvalRotateKeyGen(keys.secretKey, {1, -2});// 生成元 g = 5 mod N, ord(g) = N/2map<usint, EvalKey<DCRTPoly>> evk_map = *cc->EvalAutomorphismKeyGen(keys.secretKey, {1u, 5u, 25u});vector<int64_t> x1 = {1, 2, 3, 4, 5, 6, 7, 8};vector<int64_t> x2 = {1, 0, 0, 0, 0, 0, 0, -1};Plaintext pt1 = cc->MakeCoefPackedPlaintext(x1);Plaintext pt2 = cc->MakeCoefPackedPlaintext(x2);print_pt(pt1);print_pt(pt2);/***************************************************************************************************/auto ct1 = cc->Encrypt(keys.publicKey, pt1);auto ct2 = cc->Encrypt(keys.publicKey, pt2);Plaintext pt;print_param(ct1);pn;cc->Decrypt(keys.secretKey, ct1, &pt);print_pt(pt);cc->Decrypt(keys.secretKey, ct2, &pt);print_pt(pt);Ciphertext<DCRTPoly> ct;cout.precision(8);/***************************************************************************************************/Timer("+", ct = ct1 + ct2;); // 比 cc->EvalAdd 要快print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #1", ct = cc->EvalAdd(ct1, ct2);); // 首先会 type 检查print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Scale", ct = cc->EvalMult(ct, cc->MakeCoefPackedPlaintext({0, 2}));); // 必须把 scale 先构造为 Plaintextprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #2", ct = cc->EvalAdd(ct, ct2);); // 相同 Level 不同 ScalingFactorInt 的加法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("*", ct = ct1 * ct2;); // 和 cc->EvalMult 一样,但是不检查 typeprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult", ct = cc->EvalMult(ct1, ct2);); // 总是自动密钥切换,和 cc->EvalMultAndRelinearize 完全一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #3", ct = cc->EvalAdd(ct, ct2);); // 不同 Level 不同 ScalingFactorInt 的加法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult And Relinearize", ct = cc->EvalMultAndRelinearize(ct1, ct2);); // 和 cc->EvalMult 基本一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Mult No Relin #1", ct = cc->EvalMultNoRelin(ct1, ct2);); // 这个才是不做密钥切换的,SKDeg 增长print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult No Relin #2", ct = cc->EvalMultNoRelin(ct, ct2);); // 不同 ScalingFactor 不同 Level 的乘法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Relinear", cc->RelinearizeInPlace(ct);); // 占据几乎全部的时间print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Rotate(1)", ct = cc->EvalRotate(ct1, 1);); // 正数是左旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Rotate(-2)", ct = cc->EvalRotate(ct1, -2);); // 负数是右旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Automorphism(1)", ct = cc->EvalAutomorphism(ct1, 1, evk_map);); // 不旋转print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(5)", ct = cc->EvalAutomorphism(ct1, 5, evk_map);); // 数量 N 的明文槽,由 (-5) 生成print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(25)", ct = cc->EvalAutomorphism(ct1, 25, evk_map);); // 5^2 mod Nprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/return 0;
}

结果

使用 BEHZ 乘法

CPU Frequency = 2918913687CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 1532495540865662914854395520533418584588770550682052609
ModulusBits = 180
RootOfUnity = 0
PlaintextModulus = 17
BatchSize = 1024
PlaintextGenerator = 0Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 1 0 0 0 0 0 0 -1 ... )Level = 0 | Depth = 1 | SKDeg = 1 | Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 1 0 0 0 0 0 0 -1 ... )Running Time of <+>:         99032 cycles (  0.033928 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 7 ... )Running Time of <Add #1>:          2736272 cycles (  0.937428 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 7 ... )Running Time of <Scale>:           2735077 cycles (  0.937019 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 0 4 4 6 8 -7 -5 -3 -3 ... )Running Time of <Add #2>:          1133253 cycles (  0.388245 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 4 4 6 8 -7 -5 -4 -3 ... )Running Time of <*>:     253469802 cycles ( 86.837032 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult>:  187670910 cycles ( 64.294779 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Add #3>:           435927 cycles (  0.149346 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 6 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult And Relinearize>:  126839959 cycles ( 43.454508 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult No Relin #1>:      130843571 cycles ( 44.826119 ms)
Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult No Relin #2>:      172007707 cycles ( 58.928672 ms)
Level = 0 | Depth = 3 | SKDeg = 3 | 
Result: ( 1 2 3 4 5 6 7 6 -4 -6 -8 7 5 3 2 2 3 4 5 6 7 8 ... )Running Time of <Relinear>:      208823169 cycles ( 71.541399 ms)
Level = 0 | Depth = 3 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 6 -4 -6 -8 7 5 3 2 2 3 4 5 6 7 8 ... )Running Time of <Rotate(1)>:     115388270 cycles ( 39.531237 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0 8 ... )Running Time of <Rotate(-2)>:     70254530 cycles ( 24.068725 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 ... )Running Time of <Automorphism(1)>:        83246053 cycles ( 28.519532 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(5)>:        74563676 cycles ( 25.545009 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0 8 ... )Running Time of <Automorphism(25)>:       67644689 cycles ( 23.174611 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 ... )

使用 HPSPOVERQLEVELED 乘法

CPU Frequency = 2918959071CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 1532495540865662914854395520533418584588770550682052609
ModulusBits = 180
RootOfUnity = 0
PlaintextModulus = 17
BatchSize = 1024
PlaintextGenerator = 0Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 1 0 0 0 0 0 0 -1 ... )Level = 0 | Depth = 1 | SKDeg = 1 | Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 1 0 0 0 0 0 0 -1 ... )Running Time of <+>:        115828 cycles (  0.039681 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 7 ... )Running Time of <Add #1>:          4293174 cycles (  1.470789 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 7 ... )Running Time of <Scale>:            894332 cycles (  0.306387 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 0 4 4 6 8 -7 -5 -3 -3 ... )Running Time of <Add #2>:           987738 cycles (  0.338387 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 4 4 6 8 -7 -5 -4 -3 ... )Running Time of <*>:     236847696 cycles ( 81.141150 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult>:  162997593 cycles ( 55.841000 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Add #3>:           311286 cycles (  0.106643 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 2 2 3 4 5 6 7 6 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult And Relinearize>:  152945198 cycles ( 52.397171 ms)
Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult No Relin #1>:      108039418 cycles ( 37.012995 ms)
Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ( 1 2 3 4 5 6 7 7 -2 -3 -4 -5 -6 -7 -8 ... )Running Time of <Mult No Relin #2>:      183090958 cycles ( 62.724743 ms)
Level = 0 | Depth = 3 | SKDeg = 3 | 
Result: ( 1 2 3 4 5 6 7 6 -4 -6 -8 7 5 3 2 2 3 4 5 6 7 8 ... )Running Time of <Relinear>:      116302449 cycles ( 39.843809 ms)
Level = 0 | Depth = 3 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 6 -4 -6 -8 7 5 3 2 2 3 4 5 6 7 8 ... )Running Time of <Rotate(1)>:      88811197 cycles ( 30.425640 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0 8 ... )Running Time of <Rotate(-2)>:     87308745 cycles ( 29.910918 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 ... )Running Time of <Automorphism(1)>:        87723653 cycles ( 30.053060 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(5)>:        97097626 cycles ( 33.264470 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0 8 ... )Running Time of <Automorphism(25)>:       80256150 cycles ( 27.494784 ms)
Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 ... )

BGV

代码

BGV 方案使用 LSD 纠错码,需要模切换。在 Ciphertext<DCRTPoly> 密文中,GetScalingFactorInt() 记录了扭曲因子GetLevel() 记录了乘法深度GetNoiseScaleDeg() 记录了扭曲因子的指数GetElements().size() 是密文中环元素向量的长度。

对于 PackedPlaintext 打包,明文模数必须是满足 NTT 的大素数,槽旋转对应的自同构指标由 5 mod{2*N} 生成。

槽打包的 BGV 用例,

#include <vector>
#include <iostream>
#include "openfhe.h"
#include "cputimer.h"using namespace std;
using namespace lbcrypto;#define endl2 endl << endl
#define pn puts("")#define print_param(ct)                                                            \cout << "ScalingFactorInt = " << ct->GetScalingFactorInt().ToString() << " | " \<< "Level = " << ct->GetLevel() << " | "                                  \<< "Depth = " << ct->GetNoiseScaleDeg() << " | "                          \<< "SKDeg = " << ct->GetElements().size() - 1 << " | "                    \<< endl;#define print_pt(pt) \cout << "Result: " << pt << endl2;int main()
{GetFrequency();cout << endl;size_t ringDim = 16384;          // 必须是二的幂次size_t plaintextModulus = 65537; // 槽打包必须是大素数size_t multDepth = 10;size_t maxRelinSkDeg = 4;CCParams<CryptoContextBGVRNS> parameters;parameters.SetSecurityLevel(HEStd_NotSet); // 如果不设置安全级别,则需要手动给出环维度parameters.SetRingDim(ringDim);parameters.SetPlaintextModulus(plaintextModulus);parameters.SetMultiplicativeDepth(multDepth);parameters.SetMaxRelinSkDeg(maxRelinSkDeg);parameters.SetKeySwitchTechnique(HYBRID);// FIXEDMANUAL 手动模切换,ScalingFactorInt 总是 1// FLEXIBLEAUTO 自动模切换,ScalingFactorInt 会在 [0, plaintextModulus] 内变换parameters.SetScalingTechnique(FLEXIBLEAUTO);CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);cc->Enable(PKE);cc->Enable(KEYSWITCH);cc->Enable(LEVELEDSHE);cout << "CyclotomicOrder = " << cc->GetCyclotomicOrder() << endl<< "RingDimension = " << cc->GetRingDimension() << endl<< "Level = " << cc->GetKeyGenLevel() << endl<< "Modulus = " << cc->GetModulus() << endl<< "ModulusBits = " << cc->GetModulus().GetLengthForBase(2) << endl<< "RootOfUnity = " << cc->GetRootOfUnity() << endl<< "PlaintextModulus = " << cc->GetEncodingParams()->GetPlaintextModulus() << endl<< "BatchSize = " << cc->GetEncodingParams()->GetBatchSize() << endl<< "PlaintextGenerator = " << cc->GetEncodingParams()->GetPlaintextGenerator() << endl<< endl2;/***************************************************************************************************/auto keys = cc->KeyGen();cc->EvalMultKeysGen(keys.secretKey);cc->EvalRotateKeyGen(keys.secretKey, {1, -2});// 生成元 g = 5 mod N, ord(g) = N/2map<usint, EvalKey<DCRTPoly>> evk_map = *cc->EvalAutomorphismKeyGen(keys.secretKey, {1u, 5u, 25u});vector<int64_t> x1 = {1, 2, 3, 4, 5, 6, 7, 8};vector<int64_t> x2 = {4, 3, 2, 1, 1, 2, 3, 4};Plaintext pt1 = cc->MakePackedPlaintext(x1);Plaintext pt2 = cc->MakePackedPlaintext(x2);print_pt(pt1);print_pt(pt2);/***************************************************************************************************/auto ct1 = cc->Encrypt(keys.publicKey, pt1);auto ct2 = cc->Encrypt(keys.publicKey, pt2);Plaintext pt;print_param(ct1);pn;cc->Decrypt(keys.secretKey, ct1, &pt);print_pt(pt);cc->Decrypt(keys.secretKey, ct2, &pt);print_pt(pt);Ciphertext<DCRTPoly> ct;cout.precision(8);/***************************************************************************************************/Timer("+", ct = ct1 + ct2;); // 比 cc->EvalAdd 要快print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #1", ct = cc->EvalAdd(ct1, ct2);); // 首先会 type 检查print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Scale", ct = cc->EvalMult(ct, cc->MakePackedPlaintext(vector<int64_t>(cc->GetEncodingParams()->GetBatchSize(), 4)));); // 必须把 scale 先构造为 Plaintextprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #2", ct = cc->EvalAdd(ct, ct2);); // 相同 Level 不同 ScalingFactorInt 的加法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("*", ct = ct1 * ct2;); // 和 cc->EvalMult 一样,但是不检查 typeprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult", ct = cc->EvalMult(ct1, ct2);); // 总是自动密钥切换,和 cc->EvalMultAndRelinearize 完全一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Composed Mult #1", ct = cc->ComposedEvalMult(ct1, ct2);); // 密钥切换 + 模切换print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Composed Mult #2", ct = cc->ComposedEvalMult(ct, ct2);); // FLEXIBLEAUTO  在乘法之前做模切换,EXT 第一次乘法之前也做模切换print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #3", ct = cc->EvalAdd(ct, ct2);); // 不同 Level 不同 ScalingFactorInt 的加法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult And Relinearize", ct = cc->EvalMultAndRelinearize(ct1, ct2);); // 和 cc->EvalMult 基本一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Mult No Relin #1", ct = cc->EvalMultNoRelin(ct1, ct2);); // 这个才是不做密钥切换的,SKDeg 增长print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);// cc->ModReduceInPlace(ct);Timer("Mult No Relin #2", ct = cc->EvalMultNoRelin(ct, ct2);); // 不同 ScalingFactor 不同 Level 的乘法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Relinear", cc->RelinearizeInPlace(ct);); // 占据几乎全部的时间print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("ModReduce", cc->ModReduceInPlace(ct);); // 降低一层的缩放print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Rotate(1)", ct = cc->EvalRotate(ct1, 1);); // 正数是左旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Rotate(-2)", ct = cc->EvalRotate(ct1, -2);); // 负数是右旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Automorphism(1)", ct = cc->EvalAutomorphism(ct1, 1, evk_map);); // 不旋转print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(5)", ct = cc->EvalAutomorphism(ct1, 5, evk_map);); // 数量 N 的明文槽,由 (-5) 生成print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(25)", ct = cc->EvalAutomorphism(ct1, 25, evk_map);); // 5^2 mod Nprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/return 0;
}

结果

使用 FIXEDMANUAL 模切换

CPU Frequency = 2919164586CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 101915945247153194422621674945726031044678923861288323567523751344699549609876260625831851757818456743873649587405440263849024730822259572880063879169
ModulusBits = 495
RootOfUnity = 0
PlaintextModulus = 65537
BatchSize = 1024
PlaintextGenerator = 0Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 4 3 2 1 1 2 3 4 ... )ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 4 3 2 1 1 2 3 4 ... )Running Time of <+>:        928928 cycles (  0.318217 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 5 5 5 5 6 8 10 12 ... )Running Time of <Add #1>:           918166 cycles (  0.314530 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 5 5 5 5 6 8 10 12 ... )Running Time of <Scale>:           1406846 cycles (  0.481934 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 20 20 20 20 24 32 40 48 ... )Running Time of <Add #2>:           721196 cycles (  0.247056 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 24 23 22 21 25 34 43 52 ... )Running Time of <*>:      98448862 cycles ( 33.725012 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult>:   74771761 cycles ( 25.614096 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Composed Mult #1>:      103001350 cycles ( 35.284530 ms)
ScalingFactorInt = 1 | Level = 1 | Depth = 1 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Composed Mult #2>:       97931103 cycles ( 33.547647 ms)
ScalingFactorInt = 1 | Level = 2 | Depth = 1 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Add #3>:           660204 cycles (  0.226162 ms)
ScalingFactorInt = 1 | Level = 2 | Depth = 1 | SKDeg = 1 | 
Result: ( 20 21 14 5 6 26 66 132 ... )Running Time of <Mult And Relinearize>:  121328656 cycles ( 41.562801 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult No Relin #1>:        1237702 cycles (  0.423992 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult No Relin #2>:        1619596 cycles (  0.554815 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 3 | SKDeg = 3 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Relinear>:      207136845 cycles ( 70.957577 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 3 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <ModReduce>:        991996 cycles (  0.339822 ms)
ScalingFactorInt = 1 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Rotate(1)>:      82565072 cycles ( 28.283802 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ... )Running Time of <Rotate(-2)>:    118772481 cycles ( 40.687148 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 0 0 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(1)>:        98264131 cycles ( 33.661730 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(5)>:       104197049 cycles ( 35.694133 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ... )Running Time of <Automorphism(25)>:       96996770 cycles ( 33.227578 ms)
ScalingFactorInt = 1 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 ... )

使用 FLEXIBLEAUTO 模切换

CPU Frequency = 2919001454CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 11090766327926935557496534795450603891404351373393750077990741913791395272295156970046992897184754308334673051240449197703818432513
ModulusBits = 433
RootOfUnity = 0
PlaintextModulus = 65537
BatchSize = 1024
PlaintextGenerator = 0Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 4 3 2 1 1 2 3 4 ... )ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | Result: ( 1 2 3 4 5 6 7 8 ... )Result: ( 4 3 2 1 1 2 3 4 ... )Running Time of <+>:        876028 cycles (  0.300112 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 5 5 5 5 6 8 10 12 ... )Running Time of <Add #1>:           882874 cycles (  0.302458 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 5 5 5 5 6 8 10 12 ... )Running Time of <Scale>:           1067962 cycles (  0.365866 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 20 20 20 20 24 32 40 48 ... )Running Time of <Add #2>:           903446 cycles (  0.309505 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 24 23 22 21 25 34 43 52 ... )Running Time of <*>:      79417215 cycles ( 27.206980 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult>:   96562770 cycles ( 33.080754 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Composed Mult #1>:       74693744 cycles ( 25.588800 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Composed Mult #2>:       98139791 cycles ( 33.621015 ms)
ScalingFactorInt = 48252 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Add #3>:           923506 cycles (  0.316377 ms)
ScalingFactorInt = 48252 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ( 20 21 14 5 6 26 66 132 ... )Running Time of <Mult And Relinearize>:   94704513 cycles ( 32.444147 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult No Relin #1>:        1258456 cycles (  0.431126 ms)
ScalingFactorInt = 48252 | Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ( 4 6 6 4 5 12 21 32 ... )Running Time of <Mult No Relin #2>:        2055410 cycles (  0.704148 ms)
ScalingFactorInt = 48252 | Level = 1 | Depth = 2 | SKDeg = 3 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Relinear>:      179685843 cycles ( 61.557298 ms)
ScalingFactorInt = 48252 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <ModReduce>:          6682 cycles (  0.002289 ms)
ScalingFactorInt = 48252 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ( 16 18 12 4 5 24 63 128 ... )Running Time of <Rotate(1)>:     109469187 cycles ( 37.502272 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ... )Running Time of <Rotate(-2)>:     74563389 cycles ( 25.544142 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 0 0 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(1)>:        84518442 cycles ( 28.954573 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 1 2 3 4 5 6 7 8 ... )Running Time of <Automorphism(5)>:       104449053 cycles ( 35.782460 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ... )Running Time of <Automorphism(25)>:       75254525 cycles ( 25.780914 ms)
ScalingFactorInt = 20731 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ( 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 ... )

CKKS

代码

CKKS 方案不使用纠错码,但是把浮点数缩放为整数,需要重缩放。在 Ciphertext<DCRTPoly> 密文中,GetScalingFactor() 记录了缩放因子GetLevel() 记录了乘法深度GetNoiseScaleDeg() 记录了缩放因子的指数GetElements().size() 是密文中环元素向量的长度。

对于 CKKSPackedPlaintext 打包,仅支持 Real() 部分的加解密。SetScalingModSize() 用于设置缩放因子的比特数SetBatchSize() 用于设置明文槽的个数。对于 BatchSize <= RingDim/2,打包成维度 2*BatchSize子环,槽旋转对应的自同构指标由 5 mod{4*BatchSize} 生成。

槽打包的 CKKS 用例,

#include <vector>
#include <iostream>
#include "openfhe.h"
#include "cputimer.h"using namespace std;
using namespace lbcrypto;#define endl2 endl << endl
#define pn puts("")#define print_param(ct)                                           \cout << "ScalingFactor = " << ct->GetScalingFactor() << " | " \<< "Level = " << ct->GetLevel() << " | "                 \<< "Depth = " << ct->GetNoiseScaleDeg() << " | "         \<< "SKDeg = " << ct->GetElements().size() - 1 << " | "   \<< endl;#define print_pt(pt)    \cout << "Result: "; \PrintComplex(pt);   \cout << "Estimated precision in bits: " << pt->GetLogPrecision() << endl2;void PrintComplex(Plaintext pt)
{vector<complex<double>> value = pt->GetCKKSPackedValue();size_t len = pt->GetLength();cout << "(";while (--len > 0)if (value[len] != complex<double>(0, 0))break;for (int i = 0; i <= len; i++){cout << value[i] << ", ";}cout << " ... ); "<< "Estimated precision: " << pt->GetLogPrecision() << " bits" << endl;
}int main()
{GetFrequency();cout << endl;size_t ringDim = 16384;   // 必须是二的幂次size_t batchSize = 8;     // 必须是 N/2 的因子,二的幂次size_t scaleModSize = 50; // 仅支持至多 60-bit 尾数size_t multDepth = 10;size_t maxRelinSkDeg = 4;CCParams<CryptoContextCKKSRNS> parameters;parameters.SetSecurityLevel(HEStd_NotSet); // 如果不设置安全级别,则需要手动给出环维度parameters.SetRingDim(ringDim);parameters.SetBatchSize(batchSize);parameters.SetScalingModSize(scaleModSize);parameters.SetMultiplicativeDepth(multDepth);parameters.SetMaxRelinSkDeg(maxRelinSkDeg);parameters.SetKeySwitchTechnique(HYBRID);// FIXEDMANUAL 手动模切换,ScalingFactor 会变// FLEXIBLEAUTO 自动模切换,ScalingFactor 总是 2^scaleModSizeparameters.SetScalingTechnique(FIXEDMANUAL);CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);cc->Enable(PKE);cc->Enable(KEYSWITCH);cc->Enable(LEVELEDSHE);cc->Enable(ADVANCEDSHE);cout << "CyclotomicOrder = " << cc->GetCyclotomicOrder() << endl<< "RingDimension = " << cc->GetRingDimension() << endl<< "Level = " << cc->GetKeyGenLevel() << endl<< "Modulus = " << cc->GetModulus() << endl<< "ModulusBits = " << cc->GetModulus().GetLengthForBase(2) << endl<< "RootOfUnity = " << cc->GetRootOfUnity() << endl<< "PlaintextModulus = " << cc->GetEncodingParams()->GetPlaintextModulus() << endl<< "BatchSize = " << cc->GetEncodingParams()->GetBatchSize() << endl<< "PlaintextGenerator = " << cc->GetEncodingParams()->GetPlaintextGenerator() << endl<< endl2;/***************************************************************************************************/auto keys = cc->KeyGen();cc->EvalMultKeysGen(keys.secretKey);cc->EvalRotateKeyGen(keys.secretKey, {1, -2});// 生成元 g = 5 mod{4*batchSize}, ord(g) = batchSizemap<usint, EvalKey<DCRTPoly>> evk_map = *cc->EvalAutomorphismKeyGen(keys.secretKey, {1u, 5u, 25u, 29u, 17u, 21u, 9u, 13u});vector<complex<double>> x1 = {{0.25, 0.5}, {0.5, 1}, {0.75, 1.5}, {1, 2}, {2, 4}, {3, 6}, {4, 8}, {5, 10}};vector<double> x2 = {5, 4, 3, 2, 1, 0.75, 0.5, 0.25};Plaintext pt1 = cc->MakeCKKSPackedPlaintext(x1);Plaintext pt2 = cc->MakeCKKSPackedPlaintext(x2);print_pt(pt1); // 明文编码了 Re 以及 Imprint_pt(pt2);/***************************************************************************************************/auto ct1 = cc->Encrypt(keys.publicKey, pt1);auto ct2 = cc->Encrypt(keys.publicKey, pt2);Plaintext pt;print_param(ct1);pn;cc->Decrypt(keys.secretKey, ct1, &pt); // 但是仅加密 Re 部分,丢弃 Im 部分,复制在 Z_{4*batchSize}^* = <-1, 5> 中的 <5> 和 <-5> 两行print_pt(pt);cc->Decrypt(keys.secretKey, ct2, &pt);print_pt(pt);Ciphertext<DCRTPoly> ct;cout.precision(8);/***************************************************************************************************/Timer("+", ct = ct1 + ct2;); // 比 cc->EvalAdd 要快print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Add #1", ct = cc->EvalAdd(ct1, ct2);); // 首先会 type 检查print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Scale", ct = cc->EvalMult(ct1, 4);); // 速度接近 operator+print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);cc->RescaleInPlace(ct); // 相同 Level 不同 ScalingFactor 的加法,错误Timer("Add #2", ct = cc->EvalAdd(ct, ct2);); // 相同 ScalingFactor 不同 Level 的加法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("*", ct = ct1 * ct2;); // 和 cc->EvalMult 一样,但是不检查 typeprint_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult", ct = cc->EvalMult(ct1, ct2);); // 总是自动密钥切换,和 cc->EvalMultAndRelinearize 完全一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Composed Mult #1", ct = cc->ComposedEvalMult(ct1, ct2);); // 密钥切换 + 模切换print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Composed Mult #2", ct = cc->ComposedEvalMult(ct, ct2);); // FLEXIBLEAUTO  在乘法之前做模切换,EXT 第一次乘法之前也做模切换print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Mult And Relinearize", ct = cc->EvalMultAndRelinearize(ct1, ct2);); // 和 cc->EvalMult 基本一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Mult No Relin #1", ct = cc->EvalMultNoRelin(ct1, ct2);); // 这个才是不做密钥切换的,SKDeg 增长print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);// cc->RescaleInPlace(ct);Timer("Mult No Relin #2", ct = cc->EvalMultNoRelin(ct, ct2);); // 不同 ScalingFactor 不同 Level 的乘法,正确print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Relinear", cc->RelinearizeInPlace(ct);); // 占据几乎全部的时间print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("ModReduce", cc->ModReduceInPlace(ct);); // 降低一层的缩放,和 cc->RescaleInPlace 完全一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Rescale", cc->RescaleInPlace(ct);); // 降低一层的缩放,和 cc->ModReduceInPlace 完全一样print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Rotate(1)", ct = cc->EvalRotate(ct1, 1);); // 正数是左旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Rotate(-2)", ct = cc->EvalRotate(ct1, -2);); // 负数是右旋print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/Timer("Automorphism(1)", ct = cc->EvalAutomorphism(ct1, 1, evk_map);); // 不旋转print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(5)", ct = cc->EvalAutomorphism(ct1, 5, evk_map);); // 次数 4*batchSize 的子环上,数量 batchSize 的明文槽,由 (-5) 生成print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(25)", ct = cc->EvalAutomorphism(ct1, 25, evk_map);); // 5^2 mod 32print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(29)", ct = cc->EvalAutomorphism(ct1, 29, evk_map);); // 5^3 mod 32print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(17)", ct = cc->EvalAutomorphism(ct1, 17, evk_map););print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(21)", ct = cc->EvalAutomorphism(ct1, 21, evk_map););print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(9)", ct = cc->EvalAutomorphism(ct1, 9, evk_map););print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);Timer("Automorphism(13)", ct = cc->EvalAutomorphism(ct1, 13, evk_map););print_param(ct);cc->Decrypt(keys.secretKey, ct, &pt);print_pt(pt);/***************************************************************************************************/return 0;
}

结果

使用 FIXEDMANUAL 模切换

CPU Frequency = 2919133983CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 3773962425391299449455856105110342697983390191203387110210545988123360807414630715088298851847265236596671914551723351177669086733035396939530237480795634800286060664833
ModulusBits = 561
RootOfUnity = 0
PlaintextModulus = 50
BatchSize = 8
PlaintextGenerator = 0Result: ((0.25,0.5), (0.5,1), (0.75,1.5), (1,2), (2,4), (3,6), (4,8), (5,10),  ... ); Estimated precision: 50 bits
Estimated precision in bits: 50Result: ((5,0), (4,0), (3,0), (2,0), (1,0), (0.75,0), (0.5,0), (0.25,0),  ... ); Estimated precision: 50 bits
Estimated precision in bits: 50ScalingFactor = 1.1259e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | Result: ((0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Result: ((5,0), (4,0), (3,0), (2,0), (1,0), (0.75,0), (0.5,0), (0.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <+>:        232698 cycles (  0.079715 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5.25,0), (4.5,0), (3.75,0), (3,0), (3,0), (3.75,0), (4.5,0), (5.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Add #1>:           293886 cycles (  0.100676 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5.25,0), (4.5,0), (3.75,0), (3,0), (3,0), (3.75,0), (4.5,0), (5.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Scale>:            218742 cycles (  0.074934 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1,0), (2,0), (3,0), (4,0), (8,0), (12,0), (16,0), (20,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Add #2>:           138844 cycles (  0.047563 ms)
ScalingFactor = 1.1258999e+15 | Level = 1 | Depth = 1 | SKDeg = 1 | 
Result: ((6,0), (6,0), (6,0), (6,0), (9,0), (12.75,0), (16.5,0), (20.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <*>:      88682107 cycles ( 30.379595 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Mult>:   83510222 cycles ( 28.607876 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Composed Mult #1>:      125045991 cycles ( 42.836674 ms)
ScalingFactor = 1.1258999e+15 | Level = 1 | Depth = 1 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Composed Mult #2>:      126722970 cycles ( 43.411152 ms)
ScalingFactor = 1.1258999e+15 | Level = 2 | Depth = 1 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Mult And Relinearize>:  100906735 cycles ( 34.567353 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Mult No Relin #1>:         477430 cycles (  0.163552 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Mult No Relin #2>:        1077588 cycles (  0.369146 ms)
ScalingFactor = 1.4272477e+45 | Level = 0 | Depth = 3 | SKDeg = 3 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Relinear>:      162462043 cycles ( 55.654192 ms)
ScalingFactor = 1.4272477e+45 | Level = 0 | Depth = 3 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <ModReduce>:        390542 cycles (  0.133787 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Rescale>:          294642 cycles (  0.100935 ms)
ScalingFactor = 1.1258999e+15 | Level = 2 | Depth = 1 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Rotate(1)>:      85623396 cycles ( 29.331780 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Rotate(-2)>:     85083932 cycles ( 29.146977 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(1)>:        84371770 cycles ( 28.903014 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(5)>:        32532042 cycles ( 11.144415 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(25)>:      102897566 cycles ( 35.249347 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(29)>:      154811323 cycles ( 53.033305 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(17)>:       79522168 cycles ( 27.241699 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Automorphism(21)>:       72500099 cycles ( 24.836167 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(9)>:        82870142 cycles ( 28.388605 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(13)>:       84619741 cycles ( 28.987961 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41

使用 FLEXIBLEAUTO 模切换

CPU Frequency = 2918792554CyclotomicOrder = 2048
RingDimension = 1024
Level = 0
Modulus = 3773962422988620268549387626283230612775297831378964384076336766063448441293238012679355400777370037636733749256861996141103106549700437881327817936926763295941309458433
ModulusBits = 560
RootOfUnity = 0
PlaintextModulus = 50
BatchSize = 8
PlaintextGenerator = 0Result: ((0.25,0.5), (0.5,1), (0.75,1.5), (1,2), (2,4), (3,6), (4,8), (5,10),  ... ); Estimated precision: 50 bits
Estimated precision in bits: 50Result: ((5,0), (4,0), (3,0), (2,0), (1,0), (0.75,0), (0.5,0), (0.25,0),  ... ); Estimated precision: 50 bits
Estimated precision in bits: 50ScalingFactor = 1.1259e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | Result: ((0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Result: ((5,0), (4,0), (3,0), (2,0), (1,0), (0.75,0), (0.5,0), (0.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <+>:        217702 cycles (  0.074586 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5.25,0), (4.5,0), (3.75,0), (3,0), (3,0), (3.75,0), (4.5,0), (5.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Add #1>:           195658 cycles (  0.067034 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5.25,0), (4.5,0), (3.75,0), (3,0), (3,0), (3.75,0), (4.5,0), (5.25,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Scale>:            336894 cycles (  0.115422 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1,0), (2,0), (3,0), (4,0), (8,0), (12,0), (16,0), (20,0),  ... ); Estimated precision: 39 bits
Estimated precision in bits: 39Running Time of <Add #2>:           474080 cycles (  0.162423 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((6,0), (6,0), (6,0), (6,0), (9,0), (12.75,0), (16.5,0), (20.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <*>:     118372907 cycles ( 40.555437 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Mult>:  102517626 cycles ( 35.123300 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Composed Mult #1>:       68991449 cycles ( 23.636983 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Composed Mult #2>:       83294391 cycles ( 28.537277 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Mult And Relinearize>:   83116483 cycles ( 28.476324 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 1 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Mult No Relin #1>:         661054 cycles (  0.226482 ms)
ScalingFactor = 1.2676506e+30 | Level = 0 | Depth = 2 | SKDeg = 2 | 
Result: ((1.25,0), (2,0), (2.25,0), (2,0), (2,0), (2.25,0), (2,0), (1.25,0),  ... ); Estimated precision: 40 bits
Estimated precision in bits: 40Running Time of <Mult No Relin #2>:        1388252 cycles (  0.475625 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 3 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 38 bits
Estimated precision in bits: 38Running Time of <Relinear>:      161033258 cycles ( 55.171190 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 38 bits
Estimated precision in bits: 38Running Time of <ModReduce>:          7684 cycles (  0.002633 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 38 bits
Estimated precision in bits: 38Running Time of <Rescale>:            1646 cycles (  0.000564 ms)
ScalingFactor = 1.2676506e+30 | Level = 1 | Depth = 2 | SKDeg = 1 | 
Result: ((6.25,0), (8,0), (6.75,0), (4,0), (2,0), (1.6875,0), (1,0), (0.3125,0),  ... ); Estimated precision: 38 bits
Estimated precision in bits: 38Running Time of <Rotate(1)>:      26580736 cycles (  9.106758 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Rotate(-2)>:     17406282 cycles (  5.963521 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(1)>:        41046903 cycles ( 14.062974 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(5)>:        37049927 cycles ( 12.693580 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(25)>:       98023806 cycles ( 33.583684 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((0.75,0), (1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Automorphism(29)>:       92120842 cycles ( 31.561284 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((1,0), (2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Automorphism(17)>:       87246888 cycles ( 29.891432 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((2,0), (3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41Running Time of <Automorphism(21)>:      136802988 cycles ( 46.869719 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((3,0), (4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(9)>:       103675496 cycles ( 35.519995 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((4,0), (5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0),  ... ); Estimated precision: 42 bits
Estimated precision in bits: 42Running Time of <Automorphism(13)>:       65311725 cycles ( 22.376282 ms)
ScalingFactor = 1.1258999e+15 | Level = 0 | Depth = 1 | SKDeg = 1 | 
Result: ((5,0), (0.25,0), (0.5,0), (0.75,0), (1,0), (2,0), (3,0), (4,0),  ... ); Estimated precision: 41 bits
Estimated precision in bits: 41

这篇关于OpenFHE 使用样例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1025317

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud