深圳哪家建設網(wǎng)站公司好國內最大的搜索引擎
SM3是一種廣泛使用在中國國家標準中的哈希算法,全稱為“中國國家密碼算法SM3”。它由中國國家密碼管理局制定,主要用于數(shù)字簽名和消息完整性驗證。SM3算法與SHA-256在結構上類似,但其設計具有特定的改進以增強安全性。
SM3算法生成256位的哈希值,使用了32輪的迭代運算,并且依賴于消息擴展、壓縮函數(shù)、消息混淆等步驟。
1、SM3算法主要步驟
-
消息填充:首先對輸入的消息進行填充,使其長度變?yōu)?12的倍數(shù)。填充方法是在消息末尾添加一個’1’位,然后添加一定數(shù)量的’0’位,最后再添加64位的消息長度。
-
消息擴展:將填充后的消息分為512位的塊,然后進行消息擴展,將每個512位的消息塊擴展為132個32位的字。
-
壓縮函數(shù):將消息塊與初始的IV(Initial Vector,初始向量)通過非線性變換進行壓縮,32輪迭代,每輪使用擴展后的消息字和常量進行混合運算。
-
迭代運算:將壓縮后的結果與前一個結果相加,作為下一次壓縮的輸入,直到所有消息塊都處理完畢。
-
輸出哈希值:最后得到的256位數(shù)據(jù)即為SM3的哈希值。
2、數(shù)據(jù)示例
假設輸入消息為 “abc”。在SM3算法中,這將被轉化為字節(jié)形式進行處理:b"abc"。
2.1步驟 1: 消息填充
SM3算法的第一步是對消息進行填充,使其長度變?yōu)?12的倍數(shù)。
2.1.1 原始消息:
- “abc” 在ASCII中的十六進制表示為:0x61 0x62 0x63,即 b"abc"。
- 長度為3字節(jié),或者24位(二進制)。
2.1.2 附加 ‘1’ 位:
- 在消息末尾添加一個’1’位:0x61 0x62 0x63 0x80,即 b"abc\x80"。
2.1.3 填充 ‘0’ 位:
- 為了使填充后的長度為448位(512位-64位,數(shù)據(jù)長度需要用64位的),我們需要在’1’位后填充448 - 24 - 8 = 416位的0。
- 填充后的消息為:0x61 0x62 0x63 0x80 加上 52 (64字節(jié)-8字節(jié)-3字節(jié)-1字節(jié))個 0x00,即 b"abc\x80" + b’\x00’*52。
2.1.4 附加消息長度:
- 將原始消息的長度(24位)用64位二進制表示,并附加到消息末尾:
0x0000000000000018
(64位表示的十六進制)。 - 最終填充后的消息為:
b"abc\x80" + b'\x00'*52 + b'\x00\x00\x00\x00\x00\x00\x00\x18
0x61 0x62 0x63 0x80 00 00 00 00 00 00 00 00 00 00 00 00 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18
2.2 步驟 2: 消息擴展
將填充后的消息塊擴展為132個32位字(W[0]到W[67]和W’[0]到W’[63]),以便進行后續(xù)的壓縮計算。
2.2.1 分塊:
- 每個512位的消息塊被分成16個32位的字(W[0]到W[15])。
- 對于"abc",原始消息塊為:
W[0] = 0x61626380 W[1] = 0x00000000 W[2] = 0x00000000 ... W[15] = 0x00000018
2.2.2 消息擴展:
- 擴展為68個字(W[16]-W[67]):
W[j] = P1(W[j-16] ^ W[j-9] ^ ROTL(W[j-3], 15)) ^ ROTL(W[j-13], 7) ^ W[j-6]
- 例如:
W[16] = P1(W[0] ^ W[7] ^ ROTL(W[13], 15)) ^ ROTL(W[3], 7) ^ W[10]
2.2.3 計算W’:
W’共64個字,和W合起來共132個字
- 根據(jù)W[j]生成W’[j]:
W'[j] = W[j] ^ W[j+4]
2.3 步驟 3: 壓縮函數(shù)
目標:將擴展后的消息塊與初始向量(IV)通過32輪迭代壓縮,生成新的哈希值。
2.3.1 初始化寄存器:
- 使用8個初始向量IV初始化寄存器(A到H):
A = 0x7380166F, B = 0x4914B2B9, C = 0x172442D7, D = 0xDA8A0600, E = 0xA96F30BC, F = 0x163138AA, G = 0xE38DEE4D, H = 0xB0FB0E4E
2.3.1 32輪迭代計算:
-
每輪使用FF、GG、P0、P1等函數(shù),以及常量T[j],更新寄存器的值。
-
例如,第1輪的計算:
SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[0], 0), 7) SS2 = SS1 ^ ROTL(A, 12) TT1 = FF(A, B, C, j) + D + SS2 + W'[j] TT2 = GG(E, F, G, j) + H + SS1 + W[j]
-
更新寄存器的值:
A = TT1, B = A, C = ROTL(B, 9), D = C, ...
2.3.2 壓縮結果:
- 每一輪的結果與前一輪的結果相加,作為下一輪的輸入。處理完所有消息塊后,將最終結果作為哈希值。
2.4 步驟4:輸出哈希值
目標:將最終壓縮后的256位寄存器值作為SM3的哈希值輸出。
2.4.1組合寄存器值:
-
將最終的寄存器A到H的值連接起來,形成一個256位(64個十六進制字符)的哈希值。
-
對于消息 “abc”,最終輸出的哈希值為:
66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
3、python實現(xiàn)
import structdef left_rotate(n, b):"""左旋轉 n by b bits。"""return ((n << b)