(密码学)(crypto)IDEA_Crypto(ECB模式)——python实现

(密码学)(crypto)IDEA_Crypto(ECB模式)——python实现

四月 27, 2020 (Updated: )

```python

-- coding:utf-8 --

def FindMODreverse(a,m): # 欧几里得除法求模逆元
m_tmp = m
x_1,x_2 = 1,0
y_1,y_2 = 0,1
while m != 0:
q = a//m
x_2,y_2,m,x_1,y_1,a = (x_1 - q x_2),(y_1 - q y_2),a % m,x_2,y_2,m
while x_1 < 0:
x_1 += m_tmp
while x_1 >= m_tmp:
x_1 -= m_tmp
return x_1

def ROL(lit,num): # 循环左移 num 位
return lit[num:] + lit[:num]

def idea_xor(x,y): # 逐位异或
tmp = ‘’ ; i = 0
while True:
try:
tmp += str(int(x[i],2)^int(y[i],2))
i += 1
except:
return tmp

def idea_add(x,y): # 模65536相加
x = int(x,2) ; y = int(y,2)
z = ( x + y ) % 65536
z = bin(z)[2:]
tmp = ‘0’*(16 - len(z)) + z
return tmp

def idea_mul(x,y): # 模65537相乘
x = int(x,2) ; y = int(y,2)
if x == 0:
x = 2^16
if y == 0:
y = 2^16
z = ( ( x y ) % 65537 ) % 65536
z = bin(z)[2:]
tmp = ‘0’
(16 - len(z)) + z
return tmp

def idea_encode(m,num,key): # 加密过程
x_array = [m[i16:i16+16] for i in range(4)]
z_array = key[num6:num6+6]

if num < 8:
    out_1 = idea_mul(x_array[0],z_array[0])
    out_2 = idea_add(x_array[1],z_array[1])
    out_3 = idea_add(x_array[2],z_array[2])
    out_4 = idea_mul(x_array[3],z_array[3])
    out_5 = idea_mul(z_array[4],idea_xor(out_1,out_3))
    out_6 = idea_mul(z_array[5],idea_add(idea_xor(out_2,out_4),out_5))
    out_7 = idea_add(out_5,out_6)

    w_1 = idea_xor(out_1,out_6)
    w_2 = idea_xor(out_3,out_6)
    w_3 = idea_xor(out_2,out_7)
    w_4 = idea_xor(out_4,out_7)

    c = w_1 + w_2 + w_3 + w_4

    num += 1
    c = idea_encode(c,num,key)
else:
    y_1 = idea_mul(x_array[0],z_array[0])
    y_2 = idea_add(x_array[2],z_array[1])
    y_3 = idea_add(x_array[1],z_array[2])
    y_4 = idea_mul(x_array[3],z_array[3])
    c = y_1 + y_2 + y_3 + y_4

return c

def IDEA_Crypto(cm_str,key,mode):
if mode == 0:
if len(cm_str) % 8 != 0: # 对明文进行填充
cm_str += ‘\x00’ * ( 8 - len(cm_str) % 8 )

    m_bin = ''                                       # 将明文转化为二元序列
    for i in cm_str.encode('utf-8'):
        i = bin(i)[2:]
        m_bin += '0'*(8 - len(i)) + i
else:                                                # 将密文转化为二元序列
    c_bin = bin(int(cm_str,16))[2:]
    if len(c_bin) % 8 != 0:
        c_bin = '0'*(8 - (len(c_bin) % 8)) + c_bin

key_bin = ''                                         # 将密钥转化为二元序列
for i in key.encode('utf-8'):
    i = bin(i)[2:]
    key_bin += '0'*(8 - len(i)) + i

key_encrypt_array = []                                       # 生成加密子密钥
for i in range(6):
    for j in [key_bin[k*16:k*16+16] for k in range(8)]:
        key_encrypt_array.append(j)
    key_bin = ROL(key_bin,25)
else:
    key_encrypt_array.extend([key_bin[k*16:k*16+16] for k in range(8)][:4])

key_decrypt_array = [] ; flag = 0                            # 生成解密子密钥
key_tmp_array = key_encrypt_array[::-1]
for i in [key_tmp_array[i*6:i*6+6] for i in range(8)]:
    i[:4] = i[3::-1] ; i[-2:] = i[:-3:-1]

    if flag == 0:                                            # 第一轮和最后一轮的第二三子密钥特殊取值
        Addrev = bin((65536 - int(i[1],2)) % 65536)[2:]
        i[1] = '0'*(16-len(Addrev)) + Addrev
        Addrev = bin((65536 - int(i[2],2)) % 65536)[2:]
        i[2] = '0'*(16-len(Addrev)) + Addrev
        flag += 1
    else:
        Addrev = bin((65536 - int(i[1],2)) % 65536)[2:]
        tmp_1 = '0'*(16-len(Addrev)) + Addrev
        Addrev = bin((65536 - int(i[2],2)) % 65536)[2:]
        tmp_2 = '0'*(16-len(Addrev)) + Addrev
        i[1] = tmp_2
        i[2] = tmp_1

    Modrev = bin(FindMODreverse(int(i[0],2),65537))[2:]
    i[0] = '0'*(16-len(Modrev)) + Modrev
    Modrev = bin(FindMODreverse(int(i[3],2),65537))[2:]
    i[3] = '0'*(16-len(Modrev)) + Modrev

    key_decrypt_array.extend(i)
else:                                                       # 最后一轮第九轮的解密密钥
    i = key_tmp_array[-4:][::-1]

    Addrev = bin((65536 - int(i[1],2)) % 65536)[2:]
    i[1] = '0'*(16-len(Addrev)) + Addrev
    Addrev = bin((65536 - int(i[2],2)) % 65536)[2:]
    i[2] = '0'*(16-len(Addrev)) + Addrev
    Modrev = bin(FindMODreverse(int(i[0],2),65537))[2:]
    i[0] = '0'*(16-len(Modrev)) + Modrev
    Modrev = bin(FindMODreverse(int(i[3],2),65537))[2:]
    i[3] = '0'*(16-len(Modrev)) + Modrev

    key_decrypt_array.extend(i)

if mode == 0:                                   # 文本二元序列的分组
    mc_array = [ m_bin[i*64:i*64+64] \
        for i in range(int(len(m_bin) / 64)) ]  
else:
    mc_array = [ c_bin[i*64:i*64+64] \
        for i in range(int(len(c_bin) / 64)) ]

cm_array = []                                   # 求结果分组
if mode == 0:
    for i in mc_array:
        cm_array.append(idea_encode(i,0,key_encrypt_array))
else:
    for i in mc_array:
        cm_array.append(idea_encode(i,0,key_decrypt_array))

cm = ''                                      # 将结果分组转换为对应的十六进制内容
for i in cm_array:
    tmp = hex(int(i,2))[2:]
    if len(tmp) * 4 != len(i):
        tmp = '0'*int(len(i) / 4 - len(tmp)) + tmp
    cm += tmp

if mode == 0:
    print('密文:' + cm)
else:
    print('明文(hex):' + cm)

return cm

if name == “main“:
m = ‘1234567812345678’
key = ‘1234567812345678’
c = IDEA_Crypto(m,key,0)
m_tmp = IDEA_Crypto(c,key,1)
‘’’

隐藏