简答题(回答可以是中文也可以是英文):
1、What is the difference between diffusion and confusion?
扩散是将明文的冗余度分散到密文中,明文中的一位会影响密文中的许多位,产生扩散的最简单方法是“置换”。
混淆是使用秘钥与密文之间关系复杂化,通常使用非线性代换让统计关系极小化。
所以,扩散是作用于明文和密文的关系,混淆是作用于秘钥和密文的关系。
2、What was the original set of criteria used by NIST to evaluate candidate AES ciphers?
安全性、成本、算法和实现特征
编程题:
1、使用C或者Python语言,写一个函数完成GF(2^8)中任意两个元素的乘法。
本题的操作对象是把多项式系数看成二进制比特串,以字符串的形式存储起来。
主体函数是一个异或函数xoradd和一个乘法函数mul。
GF(2^8)中的元素都是8位。
乘法mul()函数是用简单算法实现的,省去了要模既约多项式要用到的除法。
实现:
def xoradd (P1,P2 ): res='' for i in range (8 ): res+=str (int (P1[i]) ^ int (P2[i])) return res def mul (P1,P2 ): res='00000000' ReducedPoly = '100011011' for i in range (8 ): if P2[7 -i]=='1' : res=xoradd(res,P1) if P1[0 ]=='1' : P1=xoradd(P1[1 ::]+'0' ,ReducedPoly[1 ::]) else : P1=P1[1 ::]+'0' return res def toPoly (P ): poly=['x^7' ,'x^6' ,'x^5' ,'x^4' ,'x^3' ,'x^2' ,'x' ,'1' ] res='' for i in range (len (P)): if P[i]=='1' : res=res+poly[i]+'+' if res[-1 ]=='+' : res=res[0 :-1 ] return res; def main (): print ('请输入多项式系数:' ) a=input () b=input () c=mul(a,b) print (toPoly(a)+' 与 ' +toPoly(b)+' 的乘积为 ' +toPoly(c)) if __name__=='__main__' : main()
运行结果:
2、使用C或者Python语言,写一个程序生成AES算法中使用的S-Box。
要实现S-Box,分三步
(1)产生一个初始化S盒
(2)元素求逆在GF(2^8)中
(3)字节移位
求逆算法使用多项式的egcd,需要实现乘法、除法、异或加。实现除法要先实现乘法,因为上个实验用的是简便算法实现乘法,适用于8位,而本实验的除法涉及到9位,所以要重新写一般形式的乘法。
实现:
def genBox (): n=16 box=[[str (hex (row)[2 :])+str (hex (col)[2 :]) for col in range (n)] for row in range (n)] return box def xoradd (P1,P2 ): res='' P1=P1.zfill(len (P2)) P2=P2.zfill(len (P1)) for i in range (len (P1)): res+=str ((int (P1[i])) ^ int (P2[i])) return res def hex2bits (str ): bits=bin (int (str ,16 ))[2 :].zfill(8 ) return bits def bits2hex (bits ): str =hex (int (bits[0 :4 ],2 ))[2 :]+hex (int (bits[4 ::],2 ))[2 :] return str def div (Abit,Bbit ): Qbit='' while True : Abit=Abit.lstrip('0' ) Bbit=Bbit.lstrip('0' ) if Abit=='' :Abit+='0' if Bbit=='' :Bbit+='0' if int (Abit,2 )<int (Bbit,2 ): Q=list ('000000000' ) for i in range (len (Qbit)): Q[8 -int (Qbit[i])]='1' Q='' .join(Q) return (Q,Abit) else : q=len (Abit)-len (Bbit) Qbit+=str (q) temp=Bbit+q*'0' r=xoradd(Abit,temp) Abit=r def mul (P1,P2 ): res='0' ReducedPoly = '100011011' for i in range (len (P2)): if P2[i]=='1' : temp=P1+(len (P2)-i-1 )*'0' res=xoradd(res,temp) return div(res,ReducedPoly)[1 ] def Poly_egcd (a,b ): if b=='00000000' : return '00000000' r0,r1,s0,s1='1' ,'0' ,'0' ,'1' while (b.count('1' )!=False ): q,a,b=div(a,b)[0 ],b,div(a,b)[1 ] r0,r1=r1,xoradd(r0,mul(q,r1)) s0,s1=s1,xoradd(s0,mul(q,s1)) return s0 def mov (bits ): cbit=str (bin (int ('63' ,16 )))[2 :].zfill(8 ) bits=bits.zfill(8 ) newbits=list () for i in range (len (bits)): newbits.append(str (int (bits[i])^int (bits[(i+4 )%8 ])^int (bits[(i+3 )%8 ])^int (bits[(i+2 )%8 ])^int (bits[(i+1 )%8 ])^int (cbit[i]))) newbits='' .join(newbits) return newbits def S_BOX (): box=genBox() ReducedPoly = '100011011' for i in range (len (box)): for j in range (len (box[i])): h=hex2bits(box[i][j]) temp=mov(Poly_egcd(ReducedPoly,h)) box[i][j]=bits2hex(temp) print (box[i][j],end=' ' ) print () return box def main (): box=S_BOX() if __name__ =='__main__' : main()
运行结果: