python版的present算法实现

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))

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值