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