""" SM3 It is a cryptographic hash function standard adopted by the government of the people's Republic of China , It is suitable for digital signature and verification in commercial password applications 、 Generation and verification of message authentication code and generation of random number , It can meet the security requirements of various cryptographic applications The length is l(l < 2 ^ 64) Bit message m,SM3 The hash algorithm is filled and iteratively compressed , Generating hash values , Hash value length by 256 The bit . s2m2b(s) character string s Convert to binary string m & data m fill , grouping b[i] cf(v,b) CF Function implementation zy(n,k) # Cyclic shift to the left k%32 position , common 32 The bit cut_text(text,lenth) # Data grouped by spacing Basic operations such as XOR FF(x,y,z,j) GG(x,y,z,j) p0(x) p1(x) """
import re
def cut_text(text,lenth): # The data is grouped by spacing iv vector
textArr = re.findall('.{'+str(lenth)+'}', text)
textArr.append(text[(len(textArr)*lenth):])
return textArr
def zy(n,k): # Cyclic shift to the left k position , common 32 The bit
k=k%32
b=str(bin(n))
b=b.split('0b')[1]
b=(32-len(b))*'0'+b
return int(b[k:]+b[:k],2)
def s2m2b(s): # character string s Convert to binary string m & data m fill , grouping b[i]
r = ""
x = ""
for i in s:
l = 8 - len((x + bin(ord(i))).split('0b')[1]) % 8
r = r + l * '0' + (x + bin(ord(i))).split('0b')[1]
k=512-(64+(len(r)+1))%512
out=r+'1'+k*'0'
length=bin(len(r)).split('0b')[1]
t=64-len(length)
out=out+t*'0'+length
out=cut_text(out,512)
return out
def T(j):
if j<16:
T =int('0x79cc4519',16)
else:
T =int('0x7a879d8a',16)
return T
def FF(x,y,z,j): # Boolean function 1, In style X,Y,Z For the word .
if j<=15:
return x^y^z
else:
return (x&y)|(y&z)|(x&z)
def GG(x,y,z,j): # Boolean function 2, In style X,Y,Z For the word .
if j<=15:
return x^y^z
else:
return (x&y)|(~x&z)
def p0(x): # Permutation function 1, In style X For the word
return x^(zy(x,9))^(zy(x,17))
def p1(x): # Permutation function 2, In style X For the word
return x^(zy(x,15))^(zy(x,23))
def cf(v,b):
w = cut_text(b, 32)
w2 = []
for j in range(16):
w[j]=int(w[j],2)
del w[16]
for j in range(16, 68):
x = p1(w[j - 16] ^ w[j - 9] ^ zy(w[j - 3] ,15)) ^ zy(w[j - 13] ,7) ^ w[j - 6]
w.append(x)
for j in range(64):
x = w[j] ^ w[j + 4]
w2.append(x)
# print("w1,w2",len(w),len(w2))
# print("w1,w2",w,w2)
A=cut_text(v,8)
# print("len(a),a",len(A),A)
for i in range(8):
A[i]=int(A[i],16)
for j in range(64):
ss1=zy((zy(A[0],12)+A[4]+zy(T(j),j))%(2**32),7)%(2**32)
ss2=(ss1^zy(A[0],12))%(2**32)
tt1=(FF(A[0],A[1],A[2],j)+A[3]+ss2+w2[j])%(2**32)
tt2=(GG(A[4],A[5],A[6],j)+A[7]+ss1+w[j])%(2**32)
A[3]=A[2]
A[2]=zy(A[1],9)
A[1]=A[0]
A[0]=tt1
A[7]=A[6]
A[6]=zy(A[5],19)
A[5]=A[4]
A[4]=p0(tt2)
# {print(j,end=":")
# for i in A:
# if i !='':
# print(hex(i),end=',')
# print()}
a=''
for i in range(8):
A[i]=str(hex(A[i])).split('0x')[1]
k=8-len(A[i])
a=a+k*'0'+A[i]
v1=int(a,16)^int(v,16)
v1=hex(v1).split('0x')[1]
if len(v1)<64:
v1="0"*(64-len(v1))+str(v1)
# print(v1,"v1")
return v1
def G_hash(P):
# The clear hash
iv = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e'
B = s2m2b(P)
for b in B:
if b != '':
iv = cf(iv, b)
return iv
if __name__ == '__main__':
iv='7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e'
plain = input(" Please input plaintext :")
B=s2m2b(plain)
for b in B:
if b!='':
iv=cf(iv,b)
print(iv)