前言
從本篇開始,接上一篇的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();
}
下一步是設定明文模數引數,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/379672.html
標籤:區塊鏈
下一篇:PHP登錄系統未正確重定向
