SM3Util.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. IV = [1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214, ]
  10. Tj = [
  11. 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
  12. 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
  13. 2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042,
  14. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  15. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  16. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  17. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  18. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  19. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  20. 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
  21. 2055708042, 2055708042, 2055708042, 2055708042
  22. ]
  23. def group(list, n): ##分组
  24. for i in range(0, len(list), n):
  25. yield list[i:i + n]
  26. def xor(a, b):
  27. a1 = int(a, 16)
  28. b1 = int(b, 16)
  29. A = '{:08x}'.format(int(a1 ^ b1))
  30. return A
  31. def left_hex(list, n):
  32. out1 = '{:032b}'.format(int(list, 16))
  33. out2 = out1[n:] + out1[:n]
  34. out_list = '{:08x}'.format(int(out2, 2))
  35. return out_list
  36. def left_int(list, n):
  37. out1 = '{:032b}'.format(list)
  38. out2 = out1[n:] + out1[:n]
  39. out_list = int(out2, 2)
  40. return out_list
  41. def FFj(X, Y, Z, j):
  42. if 0 <= j and j < 16:
  43. return X ^ Y ^ Z
  44. elif 16 <= j and j < 64:
  45. return (X & Y) | (X & Z) | (Y & Z)
  46. def GGj(X, Y, Z, j):
  47. if 0 <= j and j < 16:
  48. return X ^ Y ^ Z
  49. elif 16 <= j and j < 64:
  50. return (X & Y) | ((~ X) & Z)
  51. def P0(X):
  52. return X ^ left_int(X, 9) ^ left_int(X, 17)
  53. def P1(X):
  54. return xor(xor(X, left_hex(X, 15)), left_hex(X, 23))
  55. def CF(V, data):
  56. W = []
  57. W1 = []
  58. [W.append(data[i * 8:(i + 1) * 8]) for i in range(16)]
  59. for i in range(16, 68):
  60. 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])
  61. w_out = '{:08x}'.format(int(w_in, 16))
  62. W.append(w_out)
  63. [W1.append(xor(W[i], W[i + 4])) for i in range(64)]
  64. A, B, C, D, E, F, G, H = V
  65. for i in range(0, 64):
  66. ss1 = left_int((left_int(A, 12) + E + left_int(Tj[i], i % 32) & 0xffffffff), 7)
  67. ss2 = ss1 ^ (left_int(A, 12))
  68. tt1 = (FFj(A, B, C, i) + D + ss2 + int(W1[i], 16)) & 0xffffffff
  69. tt2 = (GGj(E, F, G, i) + H + ss1 + int(W[i], 16)) & 0xffffffff
  70. D = C
  71. C = left_int(B, 9)
  72. B = A
  73. A = tt1
  74. H = G
  75. G = left_int(F, 19)
  76. F = E
  77. E = P0(tt2)
  78. 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]]
  79. return outV
  80. def sm3(data):
  81. l = len(data) // 2
  82. byte = '{0:x}'.format(int(l * 8))
  83. data_list = []
  84. [data_list.append(i) for i in group(data, 128)]
  85. m = l % 64
  86. if m < 56 and m != 0:
  87. data_list[-1] = (data_list[-1] + '80').ljust(112, '0') + str(byte).rjust(16, '0')
  88. elif m >= 56:
  89. data_list[-1] = (data_list[-1] + '80').ljust(128, '0')
  90. data_list.append(112 * '0' + str(byte).rjust(16, '0'))
  91. elif m == 0:
  92. data_list.append('80' + 110 * '0' + str(byte).rjust(16, '0'))
  93. V = IV
  94. for i in range(0, len(data_list)):
  95. V = CF(V, data_list[i])
  96. for i in range(len(V)):
  97. V[i] = '{:08x}'.format(V[i])
  98. return ''.join(V)
  99. def sm3_hmac(data, key):
  100. l = len(key) // 2
  101. if l > 64:
  102. key = sm3(key)
  103. else:
  104. pass
  105. key = key.ljust(128, '0')
  106. opad = '5c' * 64
  107. ipad = '36' * 64
  108. ipadkey = '%x' % (int(key, 16) ^ int(ipad, 16))
  109. M = sm3(ipadkey + data)
  110. opadkey = '%x' % (int(key, 16) ^ int(opad, 16))
  111. out_data = sm3(opadkey + M)
  112. return out_data