sm3.py 4.4 KB

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