本文基於FPGA實現高速SM4加密與解密,提供開源Verilog RTL設計和可綜合工程:https://github.com/cassuto/SM4-FPGA。
一、國密標准概述
國家密碼局制定了一系列密碼學算法,包括SM1/2/3/4等,其中SM2是橢圓曲線公鑰密碼算法,SM3是密碼雜湊算法,SM4是分組加密算法。
上述算法的現行標准如下。標准原文可在“國家標准全文公開系統”查詢。
-
SM2:
GB/T 32918系列標准:
《GB/T 32918.1-2016 SM2橢圓曲線公鑰密碼算法 第1部分:總則》
《GB/T 32918.2-2016 SM2橢圓曲線公鑰密碼算法 第2部分:數字簽名算法》
《GB/T 32918.3-2016 SM2橢圓曲線公鑰密碼算法 第3部分:密鑰交換協議》
《GB/T 32918.4-2016 SM2橢圓曲線公鑰密碼算法 第4部分:公鑰加密算法》
《GB/T 32918.5-2017 SM2橢圓曲線公鑰密碼算法 第5部分:參數定義》 -
SM3:
《GB/T 32905-2016 SM3密碼雜湊算法》 -
SM4:
《GB/T 32907-2016 SM4分組密碼算法》
SM1算法並未公開。
二、SM4簡介
SM4算法是分組加密算法,分組長度和密鑰長度均為128bit。SM4算法由密鑰擴展算法與加密(解密)算法兩部分構成,均采用非線性迭代結構;加密與解密算法具有相同的結構,只是對輸入輪密鑰進行反序變換。
2.1 密鑰
密鑰長度為128bit,用\(MK=({MK}_0,{MK}_1, {MK}_2,{MK}_3)\)表示,其中向量\({MK}_i \space (i=0,1,2,3)\)表示一個字(32bit)。
例如密鑰\(\text{0x} \space 01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)對應的\(MK\)為:
其中\({MK}_0=\begin{bmatrix} 01 & 23 & 45 & 67 \end{bmatrix}^T\)。
2.2 密鑰擴展算法
密鑰擴展算法用於生成輪密鑰,輪密鑰用於加密算法每輪非線性迭代的輸入。輪密鑰用\(({rk}_1,{rk}_2, \dots , {rk}_{31})\)表示,其中向量\({rk}_i \space (i=0, \dots ,31)\)為一個字,表示第\(i\)輪迭代所使用的輪密鑰。
在介紹密鑰擴展算法之前,需要引入輪函數和合成置換函數。
2.2.1 輪函數
設輪函數輸入為\((X_0,X_1,X_2,X_3)\),輪密鑰為\(rk \in Z\),輪函數定義為:
2.2.2 合成置換函數
T函數由一個非線性變換和線性變換構成。其中非線性變換函數通過查找表(S盒)確定。設32bit輸入為\(A=(a_0,a_1,a_2,a_3)\),輸出為\(B=(b_0,b_1,b_2,b_3)\),其中分量\(a_i,b_i \space (i=0, \dots 3)\)是一個字節,非線性變換表示為:
每個S盒都是\(16 \times 16\)的查找表,具體取值見附錄C。
經過S盒置換后,再進行如下線性變換。設輸入為B,輸出為C,定義線性變換\(L\):
2.2.3 密鑰擴展算法
其中\({CK}_i\)、\({FK}_i\)都是常量,具體取值見附錄A、B。將合成置換函數\(T\)中的線性變換\(L\)替換為\(L'(B)=B \oplus (B<<13) \oplus (B<<23)\),就得到了\(T'\)函數。
上述每一步迭代的數據流如下圖所示:
第\(i\)、\(i+1\)、\(i+2\)、\(i+3\)步迭代的輸出將作為第\(i+4\)步迭代的輸入,具體可參考下圖:
從總體看,輪密鑰是以密鑰為唯一變量的函數,若密鑰已經確定,則輪密鑰也是確定的。因此當密鑰固定不變時,輪密鑰可以預先計算。
2.3 反序變換
設反序變換的輸入為\(A=(a_0,a_1,a_2,a_3)\),輸出為\(B=(b_0,b_1,b_2,b_3)\),反序變換定義為:
2.4 加密算法
設明文輸入為\((X_3,X_2,X_1,X_0)\),密文輸出為\((Y_0,Y_1,Y_2,Y_3)\),密碼擴展算法輸出輪密鑰為\(rk\),則加密算法由如下步驟完成:
(1)非線性迭代
數據流圖如下所示:
(2)輸出
2.5 解密算法
解密算法與加密算法結構相同,只是對輪密鑰反序變換后再使用,即使用\(rk'=({rk}_{31},{rk}_{30}, \dots ,{rk}_0)\)作為輪密鑰。
三、實現
根據上文得出的數據流圖,容易導出硬件實現。
3.1 流水線總體結構
SM4加密算法核心是32輪非線性迭代,在硬件上,可通過組合邏輯塊來實現每輪迭代,第\(i\)個組合邏輯塊的輸出作為第\(i+1\)個組合邏輯塊的輸入,得到如下所示的非流水線實現:
這種設計在低速時鍾下誠然可以正確工作,但關鍵路徑已經很長,進一步提升時鍾頻率變得困難。
解決辦法是采用流水線,通過寄存器划分關鍵路徑。設每個組合邏輯塊的延時為\(d_i \space (i=0,1, \dots ,31)\),非流水線實現中,關鍵路徑的數據傳輸延時為\(D=\sum_{i=0}^{31}d_i\),而流水線實現中關鍵路徑的數據傳輸延時為\(D'=\max_{0 \le i \le 31}d_i + T_{cko}\)。可知\(D'\lt D\),時序得到了改善。
設流水線時鍾頻率為\(F\),則系統的峰值吞吐率\(T_{max}\)可計算為:
當時鍾頻率\(F=100MHz\)時,峰值吞吐率\(T_{max}\)可達\(12.8Gbps\)。
考慮流水線停頓(stall)對流水線效率造成的影響。若流水線效率為\(0 \lt \eta \le 1\),則實際吞吐率為:
3.2 行為級模型的建立
通過高級語言(這里采用C++)建立算法的行為級模型,這里只貼出關鍵代碼。完整代碼請參考Github倉庫。
合成置換函數\(T\):
/* Transformation function */
uint32_t T(uint32_t x) {
uint32_t B = sbox(x);
return B ^ rol(B, 2) ^ rol(B, 10) ^ rol(B, 18) ^ rol(B, 24);
}
合成置換函數\(T'\)
/* Transformation inverse function */
uint32_t T_1(uint32_t x) {
uint32_t B = sbox(x);
return B ^ rol(B, 13) ^ rol(B, 23);
}
密鑰擴展算法:
void keyexpand(const uint8_t *mk, uint32_t K[36]) {
K[0] = btw(mk) ^ FK[0];
K[1] = btw(mk+4) ^ FK[1];
K[2] = btw(mk+8) ^ FK[2];
K[3] = btw(mk+12) ^ FK[3];
for(int i=0; i<32; i++) {
K[i+4] = K[i] ^ T_1(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]);
}
}
加密/解密算法:
void decenc(bool enc, const uint8_t *in, uint8_t *out, uint32_t K[36]) {
unsigned long X[36] = {0};
X[0] = btw(in);
X[1] = btw(in+4);
X[2] = btw(in+8);
X[3] = btw(in+12);
for(int i = 0; i<32; i++) {
X[i+4] = X[i] ^ T(X[i+1] ^ X[i+2] ^ X[i+3] ^ K[enc ? i+4 : 35-i]);
}
wtb(X[35], out);
wtb(X[34], out+4);
wtb(X[33], out+8);
wtb(X[32], out+12);
}
建立的行為級模型可為仿真驗證提供依據,通過對比FPGA計算結果與行為級模型的計算結果,可檢驗FPGA實現是否正確。
3.3 RTL模型的建立
3.3.1 S盒替換的實現
S盒置換用於合成置換函數\(T\)。S盒置換函數是32bit字到32bit字的映射,按照字節粒度逐字節替換。
通過ROM實現S盒函數。將輸入字節\(a_0,a_1,a_2,a_3\)作為ROM的地址,將ROM的數據輸出作為S盒函數的值。輸入4個字節的替換是並行的。
3.3.2 流水級的實現
流水級實現輪函數。輪函數的基本框架是異或門;合成置換函數\(T\)的非線性變換函數由ROM實現;流水線的數據暫存和傳輸通過寄存器實現。
\(L\)為合成置換函數\(T\)的線性變換函數,具體可參見Verilog源碼,這里不再贅述。
3.3.3 頂層模塊的實現
信號名稱 | 描述 |
---|---|
CLK_i | 時鍾輸入 |
RST_N_i | 異步復位輸入(下降沿有效) |
MK_i | 128bit密鑰輸入 |
MK_VALID_i | 密鑰輸入是否有效 |
DAT_i | 128bit明文(密文)分組輸入 |
DAT_VALID_i | 分組輸入是否有效 |
DAT_o | 128bit密文(明文)分組輸出 |
DAT_READY_o | 分組輸出是否有效 |
頂層模塊內部RTL原理圖
其中keyexp模塊實現密鑰擴展算法,decenc模塊實現加密/解密非線性迭代算法。
3.3.4 頂層模塊的參數化
通過可變參數實現頂層模塊的可配置性。頂層模塊既可以實現分組加密,又可以實現分組解密。此外,還可配置成使用固定輪密鑰,從而省去keyexp模塊的資源。
參數名 | 描述 | 默認值 |
---|---|---|
MODE | 0:加密; 非0:解密 | |
ENABLE_FIXED_RK | 0:不使用固定輪密鑰;非0:使用固定輪密鑰 | 0 |
FIXED_RK | 若使用固定輪密鑰,指定1024bit輪密鑰 | 128’h0 |
注:當ENABLE_FIXED_RK!=0時,采用FIXED_RK指定的輪密鑰,外部輸入信號MK_i和MK_VALID_i將被忽略,此時模塊占用邏輯資源最少;否則,采用MK_i指定的密鑰,輪密鑰將動態生成。
四、FPGA驗證
在Xilinx ZYNQ-7010平台構建如下基於ILA(集成邏輯分析儀)的測試環境,驗證SM4模塊。
通過ILA抓取加密模塊與解密模塊輸入輸出信號波形,驗證其功能。
輸入明文分組:128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)
輸入密鑰為:128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)
加密模塊輸出密文:ciphertext = 128'h \(68 \space 1e \space df \space 34 \space d2 \space 06 \space 96 \space 5e \space 86 \space b3 \space e9 \space 4f \space 53 \space 6e \space 42 \space 46\)
解密模塊輸出明文為:DAT_o = 128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)
結果正確。
4.1 資源占用
4.2 時序(\(Fclk=100MHz\))
計算得出理論最大工作頻率\(F_{max} = \frac{1}{T-WNS} = 130 MHz\)
4.3 功耗
附錄A:CK參數常量表
\({CK}_0\) | \({CK}_1\) | \({CK}_2\) | \({CK}_3\) |
---|---|---|---|
0x00070E15 | 0x1C232A31 | 0x383F464D | 0x545B6269 |
\({CK}_4\) | \({CK}_5\) | \({CK}_6\) | \({CK}_7\) |
---|---|---|---|
0x70777E85 | 0x8C939AA1 | 0xA8AFB6BD | 0xC4CBD2D9 |
\({CK}_8\) | \({CK}_9\) | \({CK}_{10}\) | \({CK}_{11}\) |
---|---|---|---|
0xE0E7EEF5 | 0xFC030A11 | 0x181F262D | 0x343B4249 |
\({CK}_{12}\) | \({CK}_{13}\) | \({CK}_{14}\) | \({CK}_{15}\) |
---|---|---|---|
0x50575E65 | 0x6C737A81 | 0x888F969D | 0xA4ABB2B9 |
\({CK}_{16}\) | \({CK}_{17}\) | \({CK}_{18}\) | \({CK}_{19}\) |
---|---|---|---|
0xC0C7CED5 | 0xDCE3EAF1 | 0xF8FF060D | 0x141B2229 |
\({CK}_{20}\) | \({CK}_{21}\) | \({CK}_{22}\) | \({CK}_{23}\) |
---|---|---|---|
0x30373E45 | 0x4C535A61 | 0x686F767D | 0x848B9299 |
\({CK}_{24}\) | \({CK}_{25}\) | \({CK}_{26}\) | \({CK}_{27}\) |
---|---|---|---|
0xA0A7AEB5 | 0xBCC3CAD1 | 0xD8DFE6ED | 0xF4FB0209 |
\({CK}_{28}\) | \({CK}_{29}\) | \({CK}_{30}\) | \({CK}_{31}\) |
---|---|---|---|
0x10171E25 | 0x2C333A41 | 0x484F565D | 0x646B7279 |
附錄B:FK參數常量表
\({FK}_0\) | \({FK}_1\) | \({FK}_2\) | \({FK}_3\) |
---|---|---|---|
0xA3B1BAC6 | 0x56AA3350 | 0x677D9197 | 0xB27022DC |
附錄C:S盒常量表
(表格較長,請拖動下方滾動條查看)
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0xD6 | 0x90 | 0xE9 | 0xFE | 0xCC | 0xE1 | 0x3D | 0xB7 | 0x16 | 0xB6 | 0x14 | 0xC2 | 0x28 | 0xFB | 0x2C | 0x05 |
1 | 0x2B | 0x67 | 0x9A | 0x76 | 0x2A | 0xBE | 0x04 | 0xC3 | 0xAA | 0x44 | 0x13 | 0x26 | 0x49 | 0x86 | 0x06 | 0x99 |
2 | 0x9C | 0x42 | 0x50 | 0xF4 | 0x91 | 0xEF | 0x98 | 0x7A | 0x33 | 0x54 | 0x0B | 0x43 | 0xED | 0xCF | 0xAC | 0x62 |
3 | 0xE4 | 0xB3 | 0x1C | 0xA9 | 0xC9 | 0x08 | 0xE8 | 0x95 | 0x80 | 0xDF | 0x94 | 0xFA | 0x75 | 0x8F | 0x3F | 0xA6 |
4 | 0x47 | 0x07 | 0xA7 | 0xFC | 0xF3 | 0x73 | 0x17 | 0xBA | 0x83 | 0x59 | 0x3C | 0x19 | 0xE6 | 0x85 | 0x4F | 0xA8 |
5 | 0x68 | 0x6B | 0x81 | 0xB2 | 0x71 | 0x64 | 0xDA | 0x8B | 0xF8 | 0xEB | 0x0F | 0x4B | 0x70 | 0x56 | 0x9D | 0x35 |
6 | 0x1E | 0x24 | 0x0E | 0x5E | 0x63 | 0x58 | 0xD1 | 0xA2 | 0x25 | 0x22 | 0x7C | 0x3B | 0x01 | 0x21 | 0x78 | 0x87 |
7 | 0xD4 | 0x00 | 0x46 | 0x57 | 0x9F | 0xD3 | 0x27 | 0x52 | 0x4C | 0x36 | 0x02 | 0xE7 | 0xA0 | 0xC4 | 0xC8 | 0x9E |
8 | 0xEA | 0xBF | 0x8A | 0xD2 | 0x40 | 0xC7 | 0x38 | 0xB5 | 0xA3 | 0xF7 | 0xF2 | 0xCE | 0xF9 | 0x61 | 0x15 | 0xA1 |
9 | 0xE0 | 0xAE | 0x5D | 0xA4 | 0x9B | 0x34 | 0x1A | 0x55 | 0xAD | 0x93 | 0x32 | 0x30 | 0xF5 | 0x8C | 0xB1 | 0xE3 |
A | 0x1D | 0xF6 | 0xE2 | 0x2E | 0x82 | 0x66 | 0xCA | 0x60 | 0xC0 | 0x29 | 0x23 | 0xAB | 0x0D | 0x53 | 0x4E | 0x6F |
B | 0xD5 | 0xDB | 0x37 | 0x45 | 0xDE | 0xFD | 0x8E | 0x2F | 0x03 | 0xFF | 0x6A | 0x72 | 0x6D | 0x6C | 0x5B | 0x51 |
C | 0x8D | 0x1B | 0xAF | 0x92 | 0xBB | 0xDD | 0xBC | 0x7F | 0x11 | 0xD9 | 0x5C | 0x41 | 0x1F | 0x10 | 0x5A | 0xD8 |
D | 0x0A | 0xC1 | 0x31 | 0x88 | 0xA5 | 0xCD | 0x7B | 0xBD | 0x2D | 0x74 | 0xD0 | 0x12 | 0xB8 | 0xE5 | 0xB4 | 0xB0 |
E | 0x89 | 0x69 | 0x97 | 0x4A | 0x0C | 0x96 | 0x77 | 0x7E | 0x65 | 0xB9 | 0xF1 | 0x09 | 0xC5 | 0x6E | 0xC6 | 0x84 |
F | 0x18 | 0xF0 | 0x7D | 0xEC | 0x3A | 0xDC | 0x4D | 0x20 | 0x79 | 0xEE | 0x5F | 0x3E | 0xD7 | 0xCB | 0x39 | 0x48 |
轉載請注明出處:https://www.cnblogs.com/the-wind/p/14335632.html,謝謝合作!