SM3Util.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : SM3Util.py
  4. @Time : 2022/6/28 8:34
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. # -*- encoding: utf-8 -*-
  10. """
  11. @File : SM32.py
  12. @Time : 2022/6/28 9:49
  13. @Author : stephen
  14. @Email : zhangdongming@asj6.wecom.work
  15. @Software: PyCharm
  16. """
  17. from math import ceil
  18. IV = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e"
  19. IV = int(IV.replace(" ", ""), 16)
  20. a = []
  21. for i in range(0, 8):
  22. a.append(0)
  23. a[i] = (IV >> ((7 - i) * 32)) & 0xFFFFFFFF
  24. IV = a
  25. def out_hex(list1):
  26. for i in list1:
  27. print("%08x" % i)
  28. print("\n")
  29. def rotate_left(a, k):
  30. k = k % 32
  31. return ((a << k) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> (32 - k))
  32. T_j = []
  33. for i in range(0, 16):
  34. T_j.append(0)
  35. T_j[i] = 0x79cc4519
  36. for i in range(16, 64):
  37. T_j.append(0)
  38. T_j[i] = 0x7a879d8a
  39. def FF_j(X, Y, Z, j):
  40. if 0 <= j < 16:
  41. ret = X ^ Y ^ Z
  42. elif 16 <= j < 64:
  43. ret = (X & Y) | (X & Z) | (Y & Z)
  44. return ret
  45. def GG_j(X, Y, Z, j):
  46. if 0 <= j < 16:
  47. ret = X ^ Y ^ Z
  48. elif 16 <= j < 64:
  49. # ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
  50. ret = (X & Y) | ((~ X) & Z)
  51. return ret
  52. def P_0(X):
  53. return X ^ (rotate_left(X, 9)) ^ (rotate_left(X, 17))
  54. def P_1(X):
  55. return X ^ (rotate_left(X, 15)) ^ (rotate_left(X, 23))
  56. def CF(V_i, B_i):
  57. W = []
  58. for i in range(16):
  59. weight = 0x1000000
  60. data = 0
  61. for k in range(i * 4, (i + 1) * 4):
  62. data = data + B_i[k] * weight
  63. weight = int(weight / 0x100)
  64. W.append(data)
  65. for j in range(16, 68):
  66. W.append(0)
  67. 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]
  68. str1 = "%08x" % W[j]
  69. W_1 = []
  70. for j in range(0, 64):
  71. W_1.append(0)
  72. W_1[j] = W[j] ^ W[j + 4]
  73. str1 = "%08x" % W_1[j]
  74. A, B, C, D, E, F, G, H = V_i
  75. """
  76. print "00",
  77. out_hex([A, B, C, D, E, F, G, H])
  78. """
  79. for j in range(0, 64):
  80. SS1 = rotate_left(((rotate_left(A, 12)) + E + (rotate_left(T_j[j], j))) & 0xFFFFFFFF, 7)
  81. SS2 = SS1 ^ (rotate_left(A, 12))
  82. TT1 = (FF_j(A, B, C, j) + D + SS2 + W_1[j]) & 0xFFFFFFFF
  83. TT2 = (GG_j(E, F, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
  84. D = C
  85. C = rotate_left(B, 9)
  86. B = A
  87. A = TT1
  88. H = G
  89. G = rotate_left(F, 19)
  90. F = E
  91. E = P_0(TT2)
  92. A = A & 0xFFFFFFFF
  93. B = B & 0xFFFFFFFF
  94. C = C & 0xFFFFFFFF
  95. D = D & 0xFFFFFFFF
  96. E = E & 0xFFFFFFFF
  97. F = F & 0xFFFFFFFF
  98. G = G & 0xFFFFFFFF
  99. H = H & 0xFFFFFFFF
  100. """
  101. str1 = "%02d" % j
  102. if str1[0] == "0":
  103. str1 = ' ' + str1[1:]
  104. print str1,
  105. out_hex([A, B, C, D, E, F, G, H])
  106. """
  107. 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]]
  108. return V_i_1
  109. def hash_msg(msg):
  110. # print(msg)
  111. len1 = len(msg)
  112. reserve1 = len1 % 64
  113. msg.append(0x80)
  114. reserve1 = reserve1 + 1
  115. # 56-64, add 64 byte
  116. range_end = 56
  117. if reserve1 > range_end:
  118. range_end = range_end + 64
  119. for i in range(reserve1, range_end):
  120. msg.append(0x00)
  121. bit_length = len1 * 8
  122. bit_length_str = [bit_length % 0x100]
  123. for i in range(7):
  124. bit_length = int(bit_length / 0x100)
  125. bit_length_str.append(bit_length % 0x100)
  126. for i in range(8):
  127. msg.append(bit_length_str[7 - i])
  128. # print(msg)
  129. group_count = round(len(msg) / 64)
  130. B = []
  131. for i in range(0, group_count):
  132. B.append(msg[i * 64:(i + 1) * 64])
  133. V = [IV]
  134. for i in range(0, group_count):
  135. V.append(CF(V[i], B[i]))
  136. y = V[i + 1]
  137. result = ""
  138. for i in y:
  139. result = '%s%08x' % (result, i)
  140. return result
  141. def str2byte(msg): # 字符串转换成byte数组
  142. ml = len(msg)
  143. msg_byte = []
  144. msg_bytearray = msg.encode('utf-8')
  145. for i in range(ml):
  146. msg_byte.append(msg_bytearray[i])
  147. return msg_byte
  148. def byte2str(msg): # byte数组转字符串
  149. ml = len(msg)
  150. str1 = b""
  151. for i in range(ml):
  152. str1 += b'%c' % msg[i]
  153. return str1.decode('utf-8')
  154. def hex2byte(msg): # 16进制字符串转换成byte数组
  155. ml = len(msg)
  156. if ml % 2 != 0:
  157. msg = '0' + msg
  158. ml = int(len(msg) / 2)
  159. msg_byte = []
  160. for i in range(ml):
  161. msg_byte.append(int(msg[i * 2:i * 2 + 2], 16))
  162. return msg_byte
  163. def byte2hex(msg): # byte数组转换成16进制字符串
  164. ml = len(msg)
  165. hexstr = ""
  166. for i in range(ml):
  167. hexstr = hexstr + ('%02x' % msg[i])
  168. return hexstr
  169. def Hash_sm3(msg, Hexstr=0):
  170. if Hexstr:
  171. msg_byte = hex2byte(msg)
  172. else:
  173. msg_byte = str2byte(msg)
  174. return hash_msg(msg_byte)
  175. def KDF(Z, klen): # Z为16进制表示的比特串(str),klen为密钥长度(单位byte)
  176. klen = int(klen)
  177. ct = 0x00000001
  178. rcnt = ceil(klen / 32)
  179. Zin = hex2byte(Z)
  180. Ha = ""
  181. for i in range(rcnt):
  182. msg = Zin + hex2byte('%08x' % ct)
  183. # print(msg)
  184. Ha = Ha + hash_msg(msg)
  185. # print(Ha)
  186. ct += 1
  187. return Ha[0: klen * 2]
  188. if __name__ == '__main__':
  189. y = Hash_sm3('aee694b9e5908ee9878de590afe7949f010000003d2e8b123c2e8b1211180000be3e', 1)
  190. print(y)
  191. # klen = 19
  192. # print(KDF("57E7B63623FAE5F08CDA468E872A20AFA03DED41BF1403770E040DC83AF31A67991F2B01EBF9EFD8881F0A0493000603", klen))