程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

SM3算法python實現

編輯:Python
""" SM3是中華人民共和國政府采用的一種密碼散列函數標准,適用於商用密碼應用中的數字簽名和驗證、消息認證碼的生成與驗證以及隨機數的生成, 可滿足多種密碼應用的安全需求 對長度為l(l < 2 ^ 64) 比特的消息m,SM3雜湊算法經過填充和迭代壓縮,生成雜湊值,雜湊值長度 為256比特。 s2m2b(s) 字符串s 轉化為二進制字符串m & 數據m填充,分組b[i] cf(v,b) CF函數實現 zy(n,k) #循環左移k%32位,共32比特 cut_text(text,lenth) #數據按間距分組 異或等基礎運算 FF(x,y,z,j) GG(x,y,z,j) p0(x) p1(x) """
import re
def cut_text(text,lenth): #數據按間距分組劃分iv向量
textArr = re.findall('.{'+str(lenth)+'}', text)
textArr.append(text[(len(textArr)*lenth):])
return textArr
def zy(n,k): #循環左移k位,共32比特
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): #字符串s 轉化為二進制字符串m & 數據m填充,分組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): #布爾函數1,式中X,Y,Z 為字。
if j<=15:
return x^y^z
else:
return (x&y)|(y&z)|(x&z)
def GG(x,y,z,j): #布爾函數2,式中X,Y,Z 為字。
if j<=15:
return x^y^z
else:
return (x&y)|(~x&z)
def p0(x): #置換函數1,式中X為字
return x^(zy(x,9))^(zy(x,17))
def p1(x): #置換函數2,式中X為字
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):
# 對明文 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("請輸入明文:")
B=s2m2b(plain)
for b in B:
if b!='':
iv=cf(iv,b)
print(iv)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved