|
@@ -6,131 +6,232 @@
|
|
|
@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
|
|
|
-]
|
|
|
-
|
|
|
+# -*- encoding: utf-8 -*-
|
|
|
+"""
|
|
|
+@File : SM32.py
|
|
|
+@Time : 2022/6/28 9:49
|
|
|
+@Author : stephen
|
|
|
+@Email : zhangdongming@asj6.wecom.work
|
|
|
+@Software: PyCharm
|
|
|
+"""
|
|
|
+from math import ceil
|
|
|
|
|
|
-def group(list, n): ##分组
|
|
|
- for i in range(0, len(list), n):
|
|
|
- yield list[i:i + n]
|
|
|
+IV = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e"
|
|
|
+IV = int(IV.replace(" ", ""), 16)
|
|
|
+a = []
|
|
|
+for i in range(0, 8):
|
|
|
+ a.append(0)
|
|
|
+ a[i] = (IV >> ((7 - i) * 32)) & 0xFFFFFFFF
|
|
|
+IV = a
|
|
|
|
|
|
|
|
|
-def xor(a, b):
|
|
|
- a1 = int(a, 16)
|
|
|
- b1 = int(b, 16)
|
|
|
- A = '{:08x}'.format(int(a1 ^ b1))
|
|
|
- return A
|
|
|
+def out_hex(list1):
|
|
|
+ for i in list1:
|
|
|
+ print("%08x" % i)
|
|
|
+ print("\n")
|
|
|
|
|
|
|
|
|
-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 rotate_left(a, k):
|
|
|
+ k = k % 32
|
|
|
+ return ((a << k) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> (32 - k))
|
|
|
|
|
|
|
|
|
-def left_int(list, n):
|
|
|
- out1 = '{:032b}'.format(list)
|
|
|
- out2 = out1[n:] + out1[:n]
|
|
|
- out_list = int(out2, 2)
|
|
|
- return out_list
|
|
|
+T_j = []
|
|
|
+for i in range(0, 16):
|
|
|
+ T_j.append(0)
|
|
|
+ T_j[i] = 0x79cc4519
|
|
|
+for i in range(16, 64):
|
|
|
+ T_j.append(0)
|
|
|
+ T_j[i] = 0x7a879d8a
|
|
|
|
|
|
|
|
|
-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 FF_j(X, Y, Z, j):
|
|
|
+ if 0 <= j < 16:
|
|
|
+ ret = X ^ Y ^ Z
|
|
|
+ elif 16 <= j < 64:
|
|
|
+ ret = (X & Y) | (X & Z) | (Y & Z)
|
|
|
+ return ret
|
|
|
|
|
|
|
|
|
-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 GG_j(X, Y, Z, j):
|
|
|
+ if 0 <= j < 16:
|
|
|
+ ret = X ^ Y ^ Z
|
|
|
+ elif 16 <= j < 64:
|
|
|
+ # ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
|
|
|
+ ret = (X & Y) | ((~ X) & Z)
|
|
|
+ return ret
|
|
|
|
|
|
|
|
|
-def P0(X):
|
|
|
- return X ^ left_int(X, 9) ^ left_int(X, 17)
|
|
|
+def P_0(X):
|
|
|
+ return X ^ (rotate_left(X, 9)) ^ (rotate_left(X, 17))
|
|
|
|
|
|
|
|
|
-def P1(X):
|
|
|
- return xor(xor(X, left_hex(X, 15)), left_hex(X, 23))
|
|
|
+def P_1(X):
|
|
|
+ return X ^ (rotate_left(X, 15)) ^ (rotate_left(X, 23))
|
|
|
|
|
|
|
|
|
-def CF(V, data):
|
|
|
+def CF(V_i, B_i):
|
|
|
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
|
|
|
+ for i in range(16):
|
|
|
+ weight = 0x1000000
|
|
|
+ data = 0
|
|
|
+ for k in range(i * 4, (i + 1) * 4):
|
|
|
+ data = data + B_i[k] * weight
|
|
|
+ weight = int(weight / 0x100)
|
|
|
+ W.append(data)
|
|
|
+
|
|
|
+ for j in range(16, 68):
|
|
|
+ W.append(0)
|
|
|
+ W[j] = P_1(W[j - 16] ^ W[j - 9] ^ (rotate_left(W[j - 3], 15))) ^ (rotate_left(W[j - 13], 7)) ^ W[j - 6]
|
|
|
+ str1 = "%08x" % W[j]
|
|
|
+ W_1 = []
|
|
|
+ for j in range(0, 64):
|
|
|
+ W_1.append(0)
|
|
|
+ W_1[j] = W[j] ^ W[j + 4]
|
|
|
+ str1 = "%08x" % W_1[j]
|
|
|
+
|
|
|
+ A, B, C, D, E, F, G, H = V_i
|
|
|
+ """
|
|
|
+ print "00",
|
|
|
+ out_hex([A, B, C, D, E, F, G, H])
|
|
|
+ """
|
|
|
+ for j in range(0, 64):
|
|
|
+ SS1 = rotate_left(((rotate_left(A, 12)) + E + (rotate_left(T_j[j], j))) & 0xFFFFFFFF, 7)
|
|
|
+ SS2 = SS1 ^ (rotate_left(A, 12))
|
|
|
+ TT1 = (FF_j(A, B, C, j) + D + SS2 + W_1[j]) & 0xFFFFFFFF
|
|
|
+ TT2 = (GG_j(E, F, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
|
|
|
D = C
|
|
|
- C = left_int(B, 9)
|
|
|
+ C = rotate_left(B, 9)
|
|
|
B = A
|
|
|
- A = tt1
|
|
|
+ A = TT1
|
|
|
H = G
|
|
|
- G = left_int(F, 19)
|
|
|
+ G = rotate_left(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)
|
|
|
+ E = P_0(TT2)
|
|
|
+
|
|
|
+ A = A & 0xFFFFFFFF
|
|
|
+ B = B & 0xFFFFFFFF
|
|
|
+ C = C & 0xFFFFFFFF
|
|
|
+ D = D & 0xFFFFFFFF
|
|
|
+ E = E & 0xFFFFFFFF
|
|
|
+ F = F & 0xFFFFFFFF
|
|
|
+ G = G & 0xFFFFFFFF
|
|
|
+ H = H & 0xFFFFFFFF
|
|
|
+ """
|
|
|
+ str1 = "%02d" % j
|
|
|
+ if str1[0] == "0":
|
|
|
+ str1 = ' ' + str1[1:]
|
|
|
+ print str1,
|
|
|
+ out_hex([A, B, C, D, E, F, G, H])
|
|
|
+ """
|
|
|
+
|
|
|
+ V_i_1 = [A ^ V_i[0], B ^ V_i[1], C ^ V_i[2], D ^ V_i[3], E ^ V_i[4], F ^ V_i[5], G ^ V_i[6], H ^ V_i[7]]
|
|
|
+ return V_i_1
|
|
|
+
|
|
|
+
|
|
|
+def hash_msg(msg):
|
|
|
+ # print(msg)
|
|
|
+ len1 = len(msg)
|
|
|
+ reserve1 = len1 % 64
|
|
|
+ msg.append(0x80)
|
|
|
+ reserve1 = reserve1 + 1
|
|
|
+ # 56-64, add 64 byte
|
|
|
+ range_end = 56
|
|
|
+ if reserve1 > range_end:
|
|
|
+ range_end = range_end + 64
|
|
|
+
|
|
|
+ for i in range(reserve1, range_end):
|
|
|
+ msg.append(0x00)
|
|
|
+
|
|
|
+ bit_length = len1 * 8
|
|
|
+ bit_length_str = [bit_length % 0x100]
|
|
|
+ for i in range(7):
|
|
|
+ bit_length = int(bit_length / 0x100)
|
|
|
+ bit_length_str.append(bit_length % 0x100)
|
|
|
+ for i in range(8):
|
|
|
+ msg.append(bit_length_str[7 - i])
|
|
|
+
|
|
|
+ # print(msg)
|
|
|
+
|
|
|
+ group_count = round(len(msg) / 64)
|
|
|
+
|
|
|
+ B = []
|
|
|
+ for i in range(0, group_count):
|
|
|
+ B.append(msg[i * 64:(i + 1) * 64])
|
|
|
+
|
|
|
+ V = [IV]
|
|
|
+ for i in range(0, group_count):
|
|
|
+ V.append(CF(V[i], B[i]))
|
|
|
+
|
|
|
+ y = V[i + 1]
|
|
|
+ result = ""
|
|
|
+ for i in y:
|
|
|
+ result = '%s%08x' % (result, i)
|
|
|
+ return result
|
|
|
+
|
|
|
+
|
|
|
+def str2byte(msg): # 字符串转换成byte数组
|
|
|
+ ml = len(msg)
|
|
|
+ msg_byte = []
|
|
|
+ msg_bytearray = msg.encode('utf-8')
|
|
|
+ for i in range(ml):
|
|
|
+ msg_byte.append(msg_bytearray[i])
|
|
|
+ return msg_byte
|
|
|
+
|
|
|
+
|
|
|
+def byte2str(msg): # byte数组转字符串
|
|
|
+ ml = len(msg)
|
|
|
+ str1 = b""
|
|
|
+ for i in range(ml):
|
|
|
+ str1 += b'%c' % msg[i]
|
|
|
+ return str1.decode('utf-8')
|
|
|
+
|
|
|
+
|
|
|
+def hex2byte(msg): # 16进制字符串转换成byte数组
|
|
|
+ ml = len(msg)
|
|
|
+ if ml % 2 != 0:
|
|
|
+ msg = '0' + msg
|
|
|
+ ml = int(len(msg) / 2)
|
|
|
+ msg_byte = []
|
|
|
+ for i in range(ml):
|
|
|
+ msg_byte.append(int(msg[i * 2:i * 2 + 2], 16))
|
|
|
+ return msg_byte
|
|
|
+
|
|
|
+
|
|
|
+def byte2hex(msg): # byte数组转换成16进制字符串
|
|
|
+ ml = len(msg)
|
|
|
+ hexstr = ""
|
|
|
+ for i in range(ml):
|
|
|
+ hexstr = hexstr + ('%02x' % msg[i])
|
|
|
+ return hexstr
|
|
|
+
|
|
|
+
|
|
|
+def Hash_sm3(msg, Hexstr=0):
|
|
|
+ if Hexstr:
|
|
|
+ msg_byte = hex2byte(msg)
|
|
|
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
|
|
|
-
|
|
|
-
|
|
|
+ msg_byte = str2byte(msg)
|
|
|
+ return hash_msg(msg_byte)
|
|
|
+
|
|
|
+
|
|
|
+def KDF(Z, klen): # Z为16进制表示的比特串(str),klen为密钥长度(单位byte)
|
|
|
+ klen = int(klen)
|
|
|
+ ct = 0x00000001
|
|
|
+ rcnt = ceil(klen / 32)
|
|
|
+ Zin = hex2byte(Z)
|
|
|
+ Ha = ""
|
|
|
+ for i in range(rcnt):
|
|
|
+ msg = Zin + hex2byte('%08x' % ct)
|
|
|
+ # print(msg)
|
|
|
+ Ha = Ha + hash_msg(msg)
|
|
|
+ # print(Ha)
|
|
|
+ ct += 1
|
|
|
+ return Ha[0: klen * 2]
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ y = Hash_sm3('aee694b9e5908ee9878de590afe7949f010000003d2e8b123c2e8b1211180000be3e', 1)
|
|
|
+ print(y)
|
|
|
+
|
|
|
+ # klen = 19
|
|
|
+ # print(KDF("57E7B63623FAE5F08CDA468E872A20AFA03DED41BF1403770E040DC83AF31A67991F2B01EBF9EFD8881F0A0493000603", klen))
|