题目
逐题解析
12.1
512bit 256bit
12.2\12.3
12.4
W[16] = 9092E200 W[17] = 00000000 W[18] = 000C0606 W[19] = 719C70ED
12.5
W[20] = 00000000 W[21] = 8001801F W[22] = 939F7DA9 W[23] = 00000000
12.6
W′[16] = 9092E200 W′[17] = 8001801 W′[18] = 93937BAF W′[19] = 719C70ED
12.7
填充结果前64位: 0110000101100010011000110110010001100001011000100110001101100100
填充结果末64位: 0000000000000000000000000000000000000000000000000000001000000000
12.8
A<<<12=7380166F<<<12=0000 0001 0110 0110 1111 0111 0011 1000=0166F738
12.9
B=7380166F C=29657292 D=172442D7
代码
免责声明:我从来不敢保证结果是对的,我只敢保证代码是我认真审的。
#-------------- 基础函数 ----------------#
def str_to_bin(msg: str) -> str:
return ''.join(f'{ord(c):08b}' for c in msg)
def padding_sm3(msg: str) -> str:
m_bin = str_to_bin(msg)
l = len(m_bin)
m_bin += '1'
k = (448 - (l + 1)) % 512
m_bin += '0' * k
l_bin = f'{l:064b}'
m_bin += l_bin
return m_bin
def left_rotate(x, n):
n = n % 32
return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFF
def split_blocks(m_bin: str, block_size=512):
return [m_bin[i:i + block_size] for i in range(0, len(m_bin), block_size)]
def binstr_to_int_list(block_512bit: str):
return [int(block_512bit[i:i+32], 2) for i in range(0, 512, 32)]
#-------------- 扩展函数 ----------------#
def P1(X):
return X ^ left_rotate(X, 15) ^ left_rotate(X, 23)
def P0(X):
return X ^ left_rotate(X, 9) ^ left_rotate(X, 17)
def message_expand(block_512bit: str):
W = binstr_to_int_list(block_512bit)
for j in range(16, 68):
term = P1(W[j - 16] ^ W[j - 9] ^ left_rotate(W[j - 3], 15))
term = term ^ left_rotate(W[j - 13], 7) ^ W[j - 6]
W.append(term & 0xFFFFFFFF)
W_ = [(W[j] ^ W[j + 4]) & 0xFFFFFFFF for j in range(64)]
return W, W_
def print_expansion(W, W_):
print("=== W[0..67] ===")
for i in range(68):
print(f"W[{i:02}] = {W[i]:08X}")
print("\n=== W′[0..63] ===")
for i in range(64):
print(f"W′[{i:02}] = {W_[i]:08X}")
#-------------- 压缩函数 ----------------#
def FF(X, Y, Z, j):
return (X ^ Y ^ Z) if j < 16 else ((X & Y) | (X & Z) | (Y & Z))
def GG(X, Y, Z, j):
return (X ^ Y ^ Z) if j < 16 else ((X & Y) | (~X & Z))
def CF(V, B):
A, B_, C, D, E, F_, G, H = V
W, W_ = message_expand(B)
print("\n>>> [压缩函数初始化] <<<")
print(f"A={A:08X} B={B_:08X} C={C:08X} D={D:08X} E={E:08X} F={F_:08X} G={G:08X} H={H:08X}")
for j in range(64):
Tj = 0x79CC4519 if j < 16 else 0x7A879D8A
SS1 = left_rotate((left_rotate(A, 12) + E + left_rotate(Tj, j)) & 0xFFFFFFFF, 7)
SS2 = SS1 ^ left_rotate(A, 12)
TT1 = (FF(A, B_, C, j) + D + SS2 + W_[j]) & 0xFFFFFFFF
TT2 = (GG(E, F_, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
D = C
C = left_rotate(B_, 9)
B_ = A
A = TT1
H = G
G = left_rotate(F_, 19)
F_ = E
E = P0(TT2)
print(f"j={j:02} → A={A:08X} B={B_:08X} C={C:08X} D={D:08X} E={E:08X} F={F_:08X} G={G:08X} H={H:08X}")
print(">>> [压缩函数结束] <<<")
return [(v ^ n) & 0xFFFFFFFF for v, n in zip(V, [A, B_, C, D, E, F_, G, H])]
#-------------- 哈希函数主控 ----------------#
def sm3_hash(msg: str, visual=True):
IV = [
0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600,
0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0EB0E4E
]
padded = padding_sm3(msg)
blocks = split_blocks(padded)
print("原始长度:", len(str_to_bin(msg)), "bits")
print("填充后总长度:", len(padded), "bits")
print("填充后分组数量:", len(blocks))
print("填充结果前64位:", padded[:64])
print("填充结果末64位:", padded[-64:])
V = IV[:]
for i, block in enumerate(blocks):
print(f"\n>>> 第 {i} 块 <<<")
W, W_ = message_expand(block)
if visual:
print_expansion(W, W_)
V = CF(V, block)
digest = ''.join(f'{x:08x}' for x in V)
print("\n最终 SM3 摘要为:")
print(digest)
return digest
#-------------- 测试入口 ----------------#
if __name__ == "__main__":
msg = "abc" # 可以改为 input("请输入消息: ")
sm3_hash(msg)