sm3.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import binascii
  2. import copy
  3. IV = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e"
  4. IV = int(IV.replace(" ", ""), 16)
  5. a = []
  6. for i in range(0, 8):
  7. a.append(0)
  8. a[i] = (IV >> ((7 - i) * 32)) & 0xFFFFFFFF
  9. IV = a
  10. T_j = []
  11. for i in range(0, 16):
  12. T_j.append(0)
  13. T_j[i] = 0x79cc4519
  14. for i in range(16, 64):
  15. T_j.append(0)
  16. T_j[i] = 0x7a879d8a
  17. def rotate_left(a, k):
  18. k = k % 32
  19. return ((a << k) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> (32 - k))
  20. def FF_j(X, Y, Z, j):
  21. if 0 <= j < 16:
  22. ret = X ^ Y ^ Z
  23. elif 16 <= j < 64:
  24. ret = (X & Y) | (X & Z) | (Y & Z)
  25. return ret
  26. def GG_j(X, Y, Z, j):
  27. if 0 <= j < 16:
  28. ret = X ^ Y ^ Z
  29. elif 16 <= j < 64:
  30. # ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
  31. ret = (X & Y) | ((~ X) & Z)
  32. return ret
  33. def P_0(X):
  34. return X ^ (rotate_left(X, 9)) ^ (rotate_left(X, 17))
  35. def P_1(X):
  36. return X ^ (rotate_left(X, 15)) ^ (rotate_left(X, 23))
  37. def CF(V_i, B_i):
  38. W = []
  39. for i in range(16):
  40. weight = 0x1000000
  41. data = 0
  42. for k in range(i * 4, (i + 1) * 4):
  43. data = data + B_i[k] * weight
  44. weight = int(weight / 0x100)
  45. W.append(data)
  46. for j in range(16, 68):
  47. W.append(0)
  48. 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]
  49. str1 = "%08x" % W[j]
  50. W_1 = []
  51. for j in range(0, 64):
  52. W_1.append(0)
  53. W_1[j] = W[j] ^ W[j + 4]
  54. str1 = "%08x" % W_1[j]
  55. A, B, C, D, E, F, G, H = V_i
  56. """
  57. print "00",
  58. out_hex([A, B, C, D, E, F, G, H])
  59. """
  60. for j in range(0, 64):
  61. SS1 = rotate_left(((rotate_left(A, 12)) + E + (rotate_left(T_j[j], j))) & 0xFFFFFFFF, 7)
  62. SS2 = SS1 ^ (rotate_left(A, 12))
  63. TT1 = (FF_j(A, B, C, j) + D + SS2 + W_1[j]) & 0xFFFFFFFF
  64. TT2 = (GG_j(E, F, G, j) + H + SS1 + W[j]) & 0xFFFFFFFF
  65. D = C
  66. C = rotate_left(B, 9)
  67. B = A
  68. A = TT1
  69. H = G
  70. G = rotate_left(F, 19)
  71. F = E
  72. E = P_0(TT2)
  73. A = A & 0xFFFFFFFF
  74. B = B & 0xFFFFFFFF
  75. C = C & 0xFFFFFFFF
  76. D = D & 0xFFFFFFFF
  77. E = E & 0xFFFFFFFF
  78. F = F & 0xFFFFFFFF
  79. G = G & 0xFFFFFFFF
  80. H = H & 0xFFFFFFFF
  81. """
  82. str1 = "%02d" % j
  83. if str1[0] == "0":
  84. str1 = ' ' + str1[1:]
  85. out_hex([A, B, C, D, E, F, G, H])
  86. """
  87. V_i_1 = [
  88. A ^ V_i[0],
  89. B ^ V_i[1],
  90. C ^ V_i[2],
  91. D ^ V_i[3],
  92. E ^ V_i[4],
  93. F ^ V_i[5],
  94. G ^ V_i[6],
  95. H ^ V_i[7]
  96. ]
  97. return V_i_1
  98. def hash_msg(msg):
  99. len1 = len(msg)
  100. reserve1 = len1 % 64
  101. msg.append(0x80)
  102. reserve1 = reserve1 + 1
  103. # 56-64, add 64 byte
  104. range_end = 56
  105. if reserve1 > range_end:
  106. range_end = range_end + 64
  107. for i in range(reserve1, range_end):
  108. msg.append(0x00)
  109. bit_length = (len1) * 8
  110. bit_length_str = [bit_length % 0x100]
  111. for i in range(7):
  112. bit_length = int(bit_length / 0x100)
  113. bit_length_str.append(bit_length % 0x100)
  114. for i in range(8):
  115. msg.append(bit_length_str[7 - i])
  116. group_count = round(len(msg) / 64)
  117. b = []
  118. for i in range(0, group_count):
  119. b.append(msg[i * 64:(i + 1) * 64])
  120. v = [IV]
  121. for i in range(0, group_count):
  122. v.append(CF(v[i], b[i]))
  123. y = v[i + 1]
  124. result = ""
  125. for i in y:
  126. result = '%s%08x' % (result, i)
  127. return result
  128. def to_byte_array(msg): # 转换成byte数组
  129. ml = len(msg)
  130. msg_byte = []
  131. for i in range(ml):
  132. msg_byte.append(msg[i])
  133. return msg_byte
  134. def hash_sm3(msg):
  135. msg_byte = to_byte_array(msg)
  136. return binascii.a2b_hex(hash_msg(msg_byte))
  137. class Sm3:
  138. block_size = 64
  139. def __init__(self, msg_byte=b''):
  140. self.byte_array = to_byte_array(msg_byte)
  141. def update(self, data):
  142. self.byte_array.extend(to_byte_array(data))
  143. def digest(self):
  144. return binascii.a2b_hex(hash_msg(self.byte_array))
  145. def hexdigest(self):
  146. return hash_msg(self.byte_array)
  147. @property
  148. def digest_size(self):
  149. return len(self.byte_array)
  150. def copy(self):
  151. return copy.deepcopy(self)