Python 使用国密有很多第三方库
有gmssl、pycryptodome等
以下是手动实现(参考了网上的代码且做略微修改)
from array import array
Tj_rl = array('L', ((0x79cc4519 << j | 0x79cc4519 >> 32 - j) & 0xffffffff for j in range(16)))
Tj_rl.extend((0x7a879d8a << (j & 31) | 0x7a879d8a >> (32 - j & 31)) & 0xffffffff for j in range(16, 64))
V0 = array('L', [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e])
def CF(V, B):
W = array('L', B)
for j in range(16, 68):
X = W[j - 16] ^ W[j - 9] ^ (W[j - 3] << 15 | W[j - 3] >> 17) & 0xffffffff
W.append((X ^ (X << 15 | X >> 17) ^ (X << 23 | X >> 9) ^ (W[j - 13] << 7 | W[j - 13] >> 25) ^ W[j - 6]) & 0xffffffff)
W_ = array('L', (W[j] ^ W[j + 4] for j in range(64)))
A, B, C, D, E, F, G, H = V
for j in range(64):
A_rl12 = A << 12 | A >> 20
tmp = (A_rl12 + E + Tj_rl[j]) & 0xffffffff
SS1 = (tmp << 7 | tmp >> 25)
SS2 = SS1 ^ A_rl12
if j & 0x30: # 16 <= j
FF, GG = A & B | A & C | B & C, E & F | ~E & G
else:
FF, GG = A ^ B ^ C, E ^ F ^ G
TT1, TT2 = (FF + D + SS2 + W_[j]) & 0xffffffff, (GG + H + SS1 + W[j]) & 0xffffffff
C, D, G, H = (B << 9 | B >> 23) & 0xffffffff, C, (F << 19 | F >> 13) & 0xffffffff, G
A, B, E, F = TT1, A, (TT2 ^ (TT2 << 9 | TT2 >> 23) ^ (TT2 << 17 | TT2 >> 15)) & 0xffffffff, E
return A ^ V[0], B ^ V[1], C ^ V[2], D ^ V[3], E ^ V[4], F ^ V[5], G ^ V[6], H ^ V[7]
def digest(data):
# 填充
pad_num = 64 - (len(data) + 1 & 0x3f)
data += b'\x80' + (len(data) << 3).to_bytes(pad_num if pad_num >= 8 else pad_num + 64, 'big')
V, B = V0, array('L', data)
B.byteswap()
# 迭代压缩
for i in range(0, len(B), 16):
V = CF(V, B[i:i + 16])
V = array('L', V)
V.byteswap()
return V.tobytes()
使用gmssl库进行比对算出来的结果
from gmssl import sm3, func
from util.gm_util import digest
def test_sm3():
data = "sm3_test_12345678"
data_bytes = data.encode('utf-8')
# 计算SM3哈希值
sm3_hash = sm3.sm3_hash(func.bytes_to_list(data_bytes))
sm3_hash2 = digest(data_bytes)
sm3_hash2 = ''.join(f'{byte:02x}' for byte in sm3_hash2)
print("gmssl库生成->", sm3_hash)
print("自定义函数生成->", sm3_hash2)
test_sm3()
最后的输出结果
gmssl库生成-> 78d24683f804ada766f92313843548a357dbc9adaa6aae95902db1b031e8b1a0
自定义函数生成-> 78d24683f804ada766f92313843548a357dbc9adaa6aae95902db1b031e8b1a0
和GMSSL库生成的完全一致,说明自定义的函数实现是符合标准算法的。