# -*- encoding: utf-8 -*- """ @File : SM3Util.py @Time : 2022/6/28 8:34 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ IV = [1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214, ] Tj = [ 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042 ] def group(list, n): ##分组 for i in range(0, len(list), n): yield list[i:i + n] def xor(a, b): a1 = int(a, 16) b1 = int(b, 16) A = '{:08x}'.format(int(a1 ^ b1)) return A def left_hex(list, n): out1 = '{:032b}'.format(int(list, 16)) out2 = out1[n:] + out1[:n] out_list = '{:08x}'.format(int(out2, 2)) return out_list def left_int(list, n): out1 = '{:032b}'.format(list) out2 = out1[n:] + out1[:n] out_list = int(out2, 2) return out_list def FFj(X, Y, Z, j): if 0 <= j and j < 16: return X ^ Y ^ Z elif 16 <= j and j < 64: return (X & Y) | (X & Z) | (Y & Z) def GGj(X, Y, Z, j): if 0 <= j and j < 16: return X ^ Y ^ Z elif 16 <= j and j < 64: return (X & Y) | ((~ X) & Z) def P0(X): return X ^ left_int(X, 9) ^ left_int(X, 17) def P1(X): return xor(xor(X, left_hex(X, 15)), left_hex(X, 23)) def CF(V, data): W = [] W1 = [] [W.append(data[i * 8:(i + 1) * 8]) for i in range(16)] for i in range(16, 68): w_in = xor(xor(P1(xor(xor(W[i - 16], W[i - 9]), left_hex(W[i - 3], 15))), left_hex(W[i - 13], 7)), W[i - 6]) w_out = '{:08x}'.format(int(w_in, 16)) W.append(w_out) [W1.append(xor(W[i], W[i + 4])) for i in range(64)] A, B, C, D, E, F, G, H = V for i in range(0, 64): ss1 = left_int((left_int(A, 12) + E + left_int(Tj[i], i % 32) & 0xffffffff), 7) ss2 = ss1 ^ (left_int(A, 12)) tt1 = (FFj(A, B, C, i) + D + ss2 + int(W1[i], 16)) & 0xffffffff tt2 = (GGj(E, F, G, i) + H + ss1 + int(W[i], 16)) & 0xffffffff D = C C = left_int(B, 9) B = A A = tt1 H = G G = left_int(F, 19) F = E E = P0(tt2) outV = [A ^ V[0], B ^ V[1], C ^ V[2], D ^ V[3], E ^ V[4], F ^ V[5], G ^ V[6], H ^ V[7]] return outV def sm3(data): l = len(data) // 2 byte = '{0:x}'.format(int(l * 8)) data_list = [] [data_list.append(i) for i in group(data, 128)] m = l % 64 if m < 56 and m != 0: data_list[-1] = (data_list[-1] + '80').ljust(112, '0') + str(byte).rjust(16, '0') elif m >= 56: data_list[-1] = (data_list[-1] + '80').ljust(128, '0') data_list.append(112 * '0' + str(byte).rjust(16, '0')) elif m == 0: data_list.append('80' + 110 * '0' + str(byte).rjust(16, '0')) V = IV for i in range(0, len(data_list)): V = CF(V, data_list[i]) for i in range(len(V)): V[i] = '{:08x}'.format(V[i]) return ''.join(V) def sm3_hmac(data, key): l = len(key) // 2 if l > 64: key = sm3(key) else: pass key = key.ljust(128, '0') opad = '5c' * 64 ipad = '36' * 64 ipadkey = '%x' % (int(key, 16) ^ int(ipad, 16)) M = sm3(ipadkey + data) opadkey = '%x' % (int(key, 16) ^ int(opad, 16)) out_data = sm3(opadkey + M) return out_data