@Lin--
2020-01-02T12:39:11.000000Z
字数 5988
阅读 375
ComSec
实现一个命令行程序完成以下功能:对任意的磁盘文件,产生该文件的128或者256比特的hash值。要求如下:
1、不能直接调用Hash函数的库,要自己实现SHA3函数。
2、用命令参数控制得到的hash值存为文件或者是拷贝到粘贴板。
3、严格遵照SHA3的标准。
此作业作为“计算机安全项目”的一部分。
'''
# File : SHA3.py
# Author : Hongpei Lin
# Date : 20191204
# Purpose : Hash Function,input data n(any bits), output hash value l(any bits you want)
'''
import hashlib
import numpy as np
import codecs
#Padding Function
#Input data bits n and block unit length(n:string type;r:int type),and len(n)%8=0
#Output data bits n' that is r|n'(string type)
def Padding(n,r):
mod=len(n)%r
pad_count=r-mod
if pad_count==8:
n=n+"01100001"
else:
n=n+"011"+"0"*(pad_count-4)+"1"
return n
#Block Function, block the data n, get blocks of n
#Input n:string type,r:int type
#output: list type, which value is string type
def Block(n,r):
BlockList=[]
index=0
length_n=len(n)
while index<length_n:
s=n[index:index+r]
news=""
si=0
while si<r:
news+=s[si:si+64][::-1]
si=si+64
BlockList.append(news)
index+=r
return BlockList
#n=1600bit, build a matrix 5*5*64;
#in this matrix, I let it be a 25*64 matrix; sign row=index/5;colunm=index%5 in mind
def Build_Matrix(n):
n_list=[]
index=0
while index<len(n):
n_list.append(n[index:index+64])
index+=64
return n_list
#0 step in f Function
#theta function,input 25*64matrix, oupput 25*64, both are string in list.
def theta(M):
T=["" for i in range(25)]
for j in range(64):#all lanes compute in the same time
sigma0=[0,0,0,0,0]#sigma(a[(x-1),y',z])
sigma1=[0,0,0,0,0]#sigma(a[(x+1),y',(z-1)]
for i in range(5):
sigma0[i]=int(M[(i-1)%25][j])^int(M[(i-6)%25][j])^int(M[(i-11)%25][j])^int(M[(i-16)%25][j])^int(M[(i-21)%25][j])
sigma1[i]=int(M[(i+1)%25][(j+1)%64])^int(M[(i+6)%25][(j+1)%64])^int(M[(i+11)%25][(j+1)%64])^int(M[(i+16)%25][(j+1)%64])^int(M[(i+21)%25][(j+1)%64])
for i in range(25):
T[i]=T[i]+str(int(M[i][j])^int(sigma0[i%5])^int(sigma1[i%5]))
return T
T_Table=[0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,15,21,8,18,2,61,56,14]
#1 step in f Function
#rho function:shift in every lane
#input a 25*64 matrix and T table, output a new matrix 25*64
def rho(M,table):
for i in range(25):
s=M[i]
M[i]=s[table[i]:]+s[:table[i]]
return M
#2 step in f Function
#pi function:lane confusion
#input a 25*64 matrix and T table, output a new matrix 25*64
def pi(M):
v_Matrix=np.array([[0, 1], [2, 3]])
New_Matrix=[""for i in range(25)]
for i in range(25):
x,y=i%5,i//5#x=colunm;y=row
Initial_Matrix=np.array([[x],[y]])
N_Matrix=v_Matrix.dot(Initial_Matrix)
index=int(N_Matrix[0][0]%5+(N_Matrix[1][0]%5)*5)
New_Matrix[index]=New_Matrix[index]+M[i]
return New_Matrix
#3 step in f Function
#chi function:bits transformation
#input a 25*64 matrix output a new matrix 25*64
def chi(M):
T=["" for i in range(25)]
for j in range(64):
for i in range(25):
row=i//5
x_1,x_2=i+1,i+2#x_1=x+1,x_2=x+2 in a same row
if not x_1<(row+1)*5:
x_1=x_1-5
if not x_2<(row+1)*5:
x_2=x_2-5
T[i]=T[i]+str(int(M[i][j])^(int(M[x_1][j])^1)&int(M[x_2][j]))
return T
#4 step in f function
#iota function:transformation of first lane in every round
#input a 25*64 matrix and RC and ordinal round, output a new matrix 25*64
RC=[1,int('8082',16),int('800000000000808A',16),int('8000000080008000',16),
int('808b',16),int('0000000080000001',16),int('8000000080008081',16),int('8000000000008009',16),
int('8a',16),int('88',16),int('0000000080008009',16),int('000000008000000A',16),
int('000000008000808B',16),int('800000000000008B',16),int('8000000000008089',16),int('8000000000008003',16),
int('8000000000008002',16),int('8000000000000080',16),int('000000000000800A',16),int('800000008000000A',16),
int('8000000080008081',16),int('8000000000008080',16),int('0000000080000001',16),int('8000000080008008',16)]
def iota(M,Rc,i):
M[0]=bin(int(M[0],2)^Rc[i])[2:]
pad_count=64-len(M[0])#padding, let string len=64
zero="0"*pad_count
M[0]=zero+M[0]
return M
#f function, input 1600bits string,output 1600bits string
def f(s):
s_Matrix=Build_Matrix(s)
for i in range(24):#24 rounds
s_Matrix=iota(chi(pi(rho(theta(s_Matrix),T_Table))),RC,i)
news=""
for i in s_Matrix:
news+=i
return news
def absorbing(s,r):
s=Padding(s,r)#padding
P_list=Block(s,r)#block
c="0"*(1600-r)
news="0"*1600#initial s
for i in range(len(P_list)):
P_list[i]=P_list[i]+c
news=bin(int(P_list[i],2)^int(news,2))[2:]
pad_count=1600-len(news)#padding , let string len=1600
zero="0"*pad_count
news=zero+news
news=f(news)
return news
def squeezing(s,r,l):
b=s[:r]
i64,i8=0,0
templist=[]
while i64<len(b):
temp_b=b[i64:i64+64]
i8state=i8+64
while i8state>i8:
templist.append(b[i8state-8:i8state])
i8state-=8
i8+=64
i64+=64
news=""
for i in templist:
news+=i
if not l>r:
return news[:l]
BlockCount=l//r+1
while BlockCount:
b=f(b)
templist=[]
i64,i8=0,0
while i64<len(b):
temp_b=b[i64:i64+64]
i8state=i8+64
while i8state>i8:
templist.append(b[i8state-8:i8state])
i8state-=8
i8+=64
i64+=64
for i in templist:
news+=i
BlockCount-=1
return news[:l]
def HashSHA3(s,l):
s=absorbing(s,1600-l-l)
s=squeezing(s,1600-l-l,l)
s=hex(int(s,2))[2:]
while len(s)<l//4:
s="0"+s
return s
def MakeSHA3(filename,l):
fr=codecs.open(filename,"r",encoding='utf-8')
msg=fr.read()
fr.close()
msgstream=""
for i in msg:
temp=bin(ord(i))[2:]
while not temp%8==0:
temp="0"+temp
msgstream+=temp
hashvalue=HashSHA3(msgstream,l)
fw=codecs.open("HashFile.txt","w",encoding='utf-8')
fw.write(hashvalue)
fw.close()
return True
'''
# File : SHA3CMD.py
# Author : Hongpei Lin
# Date : 20191211
# Purpose : Hash software, input a filname, output a hash value, and write it in another file
'''
import sys
import getopt
import SHA3
import codecs
def __main__(argv):
Hashlen=256
filename=""
try:
opts,args=getopt.getopt(argv,"hf:l:",["help","file=","len="])
except getopt.GetoptError:
print("ERROR:SHA3CMD.py -l <224/256/384/512 or others> -f <filename>")
print(" or:SHA3CMD.py --len=<224/256/384/512 or others> --file=<filename>")
sys.exit(2)
for opt,arg in opts:
if opt in ("-h","--help"):
print("Please input in these format")
print("SHA3CMD.py -l <224/256/384/512 or other number> -f <filename>")
print("SHA3CMD.py -len=<224/256/384/512 or other number> --file=<filename>")
sys.exit()
elif opt in ("-l","--len"):
try:
Hashlen=eval(arg)
except NameError as err:
print("Please input in these format")
print("ERROR:SHA3CMD.py -l <224/256/384/512 or other number> -f <filename>")
print(" or:SHA3CMD.py -len=<224/256/384/512 or other number> --file=<filename>")
sys.exit()
elif opt in ("-f","--file"):
filename=arg
if SHA3.MakeSHA3(filename,Hashlen):
print("Hash Successfully!\n Hash reslut has been writen in HashFile.txt")
else:
print("Sorry! I have some BUGS!")
if __name__=="__main__":
__main__(sys.argv[1:])