密码学实验——国密SM4的实现
随便写的答辩代码不要太较真
代码
IV = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e'
def pad(m):
m += '8' # 补1000
lenth = len(m)
k = 112 - (lenth % 128)
m += '0' * k # 补0000
m += '{:016x}'.format(lenth*4-4)
return m
def T_j(j):
if j >= 0 and j <= 15:
return '79cc4519'
else:
return '7a879d8a'
# 异或
def _xor(x, y):
return '{:08x}'.format(int(x, 16) ^ int(y, 16))
# 与
def _and(x, y):
return '{:08x}'.format(int(x, 16) & int(y, 16))
# 或
def _or(x, y):
return '{:08x}'.format(int(x, 16) | int(y, 16))
# 非
def _non(x):
return '{:08x}'.format(~(int(x, 16)) & 0xFFFFFFFF)
# 32位加法
def _add_32(x, y):
return '{:08x}'.format((int(x, 16) + int(y, 16)) % (2 ** 32))
# 左循环移位
def L_shift(x, l):
l %= 32
x = '{:032b}'.format(int(x, 16))
x = int(x[l:] + x[:l], 2)
return '{:08x}'.format(x)
# 布尔函数
def FF_j(X, Y, Z, j):
if j >= 0 and j <= 15:
return _xor(_xor(X, Y), Z)
else:
return _or(_or(_and(X, Y), _and(X, Z)), _and(Y, Z))
def GG_j(X, Y, Z, j):
if j >= 0 and j <= 15:
return _xor(_xor(X, Y), Z)
else:
return _or(_and(X, Y), _and(_non(X), Z))
# 置换函数
def P0(X):
return _xor(_xor(X, L_shift(X, 9)), L_shift(X, 17))
def P1(X):
return _xor(_xor(X, L_shift(X, 15)), L_shift(X, 23))
# 消息扩展
def expand(B):
W = ['0'] * 68
W_0 = ['0'] * 64
for i in range(16):
W[i] = B[i * 8:i * 8 + 8]
for j in range(16, 68):
a = _xor(W[j - 16], W[j - 9])
W_j_3 = L_shift(W[j - 3], 15)
a = _xor(a, W_j_3)
a = P1(a)
W_j_13 = L_shift(W[j - 13], 7)
a = _xor(a, W_j_13)
a = _xor(a, W[j - 6])
W[j] = a
for j in range(64):
W_0[j] = _xor(W[j], W[j+4])
return W, W_0
# 压缩
def CF(V, B_):
W, W_0 = expand(B_)
A = V[0:8]
B = V[8:16]
C = V[16:24]
D = V[24:32]
E = V[32:40]
F = V[40:48]
G = V[48:56]
H = V[56:64]
for j in range(64):
SS1 = _add_32(_add_32(L_shift(A, 12), E), L_shift(T_j(j), j))
SS1 = L_shift(SS1, 7)
SS2 = _xor(SS1, L_shift(A, 12))
TT1 = _add_32(_add_32(FF_j(A, B, C, j), D), SS2)
TT1 = _add_32(TT1, W_0[j])
TT2 = _add_32(_add_32(GG_j(E, F, G, j), H), SS1)
TT2 = _add_32(TT2, W[j])
D = C
C = L_shift(B, 9)
B = A
A = TT1
H = G
G = L_shift(F, 19)
F = E
E = P0(TT2)
return _xor(V, A+B+C+D+E+F+G+H)
# 迭代
def SM3(m):
m = pad(m)
len_B = len(m) // 128
B = [m[128 * i:128 * i + 128] for i in range(len_B)]
V = [IV]
for i in range(len_B):
V.append(CF(V[i], B[i]))
return V[-1]
m = input().encode().hex()
print(SM3(m))