present是轻量级分组密码算法,过程一共迭代31轮,分块长度64bit,密钥分80和128比特,在该文中实现80位的。具体流程如下:
#s盒
s_bos=[0xC,0x5,0x6,0xB,0x9,0x0,0xA,0xD,0x3,0xE,0xF,0x8,0x4,0x7,0x1,0x2]
s_box=[]
#将十六进制转成4位的二进制表示
for i in range(len(s_bos)):
s_box.append(format(s_bos[i],'04b'))
#逆s盒
inv_s_bos= [0x5,0xE,0xF,0x8,0xC,0x1,0x2,0xD,0xB,0x4,0x6,0x3,0x0,0x7,0x9,0xA]
inv_s_box=[]
for i in range(len(s_bos)):
inv_s_box.append(format(inv_s_bos[i],'04b'))
def left_rotate_list(lst, n):
return lst[n:] + lst[:n]
def left_rotate_string(s, n):
return s[n:] + s[:n]
#更新密钥
def updatekey(key,roundc):
r=format(roundc,'05b')
rc=list(r)
# 1.密钥循环左移61位
b=left_rotate_list(key,61)
# 2.对最高四位进行字节代换(S盒)
#left_rotate_string(b[0], 3) + left_rotate_string(b[1], 2) + left_rotate_string(b[2], 1)+b[4]
s=s_box[(int(b[0])<<3)+(int(b[1])<<2)+(int(b[2])<<1)+int(b[3])]
# print('s:',b)
b[0]=s[0]
b[1]=s[1]
b[2]=s[2]
b[3]=s[3]
# 3.对k19到k15与加密轮数计数器round_counter进行异或(因字符串的顺序是从头到尾,所以是k60到k64)
b[60] = int(b[60]) ^ int(rc[0])
b[61] = int(b[61]) ^ int(rc[1])
b[62] = int(b[62]) ^ int(rc[2])
b[63] = int(b[63]) ^ int(rc[3])
b[64] = int(b[64]) ^ int(rc[4])
# print('s2:', b)
return b
#轮密钥加
def roundadd(state,key):
#state=format(state,'064b')
sss=state
for i in range(len(sss)):
sss[i]=int(sss[i]) ^ int(key[i])
return sss
#字节代换
def subbyte(state):
#state = format(state, '064b')
sss = state
# print('11:',sss)
for i in range(0,64,4):
s=s_box[(int(sss[i])<<3)+(int(sss[i+1])<<2)+(int(sss[i+2])<<1)+int(sss[i+3])]
sss[i]=s[0]
sss[i+1] = s[1]
sss[i+2] = s[2]
sss[i+3] = s[3]
return sss
#解密的字节代换
def inv_subbyte(sss):
for i in range(0,len(sss),4):
s=inv_s_box[(int(sss[i])<<3)+(int(sss[i+1])<<2)+(int(sss[i+2])<<1)+int(sss[i+3])]
sss[i]=s[0]
sss[i+1] = s[1]
sss[i+2] = s[2]
sss[i+3] = s[3]
return sss
#P置换
def psub(s):
#state = format(state, '064b')
#s是处理的消息的中间状态
#定义一个空数组
sss=list(format(0,'064b'))
for i in range(0,63,1):
sss[i*16%63]=s[i]
# print(i,'sss:',sss)
sss[63]=s[63]
return sss
#解密时的P置换
def inv_psub(s):
# s是处理的消息的中间状态
# 定义一个空数组
sss = list(format(0, '064b'))
# 定义一个空数组
for i in range(0,63,1):
sss[i]=s[i*16%63]
sss[63]=s[63]
return sss
#加密,31轮
def encrypt(state,key):
sss = state
#31轮
for i in range(1,32,1):
sss=roundadd(sss,key)
sss=subbyte(sss)
# print(i, ':', sss)
sss=psub(sss)
# print(i, ':', sss)
key=updatekey(key,i)
# print(i,':',sss)
sss=roundadd(sss,key)
return sss
#解密函数
def decrypt(state,key):
k=[]
k.append(key)
for i in range(1,32,1):
key=updatekey(key,i)
k.append(key)
# print(i,':',k[i])
for i in range(31,0,-1):
state=roundadd(state, k[i])
state=inv_psub(state)
state=inv_subbyte(state)
state=roundadd(state, k[0])
# print(print(k))
return state
k=0
t=format(k,'080b')
key=list(t)
m=0
tt=format(m,'064b')
mm=list(tt)
ll=encrypt(mm,key)#加密得到的密文
print('c:',ll)
print(decrypt(ll,key))