多表代替密码:由多个简单的代替密码构成,例如,可能有5个被使用的不同的简单代替密码,单独的一个字符用来改变明文的每个字符的位置。其算法可简述为:设密钥为k,明文为m,加密为c,则有加密变换ek(m)=c1c2…cn,其中,ci=mi+ki mod q。其中Vigenere密码和Beaufort密码均是多表密码的实例。
1.密钥生成
(1)随机生成3ⅹ3可逆矩阵A,其中 :
计算其行列式并模去26,若其行列式等于零或与26不互素,则重新生成矩阵。
矩阵生成后,计算其在模26下的逆矩阵。
(2)生成3维向量 ,其中 。
(3)保存A,A-1,B作为秘密密钥。
2. 加密
3. 解密
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 10 12:44:52 2018
@author: Baron
"""
import numpy as np
from numpy.linalg import *
def my_int_inv(mat, n=26):
x = np.zeros(mat.shape, dtype=np.int16)
for i in range(mat.shape[0]):
for j in range(mat.shape[1]):
x[i, j] = int(round(mat[i, j])) % n
return x
def gcd(a, b):
while a != 0:
a, b = b % a, a
return b
def exgcd(a, m):
if gcd(a, m) != 1:
return None
u1, u2, u3 = 1, 0, a
v1, v2, v3 = 0, 1, m
while v3 != 0:
q = u3 // v3
v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
return u1 % m
a = np.mat([[11, 2, 19], [5, 23, 25], [20, 7, 17]])
b = np.mat([[3], [3], [2]])
m = np.mat([[24, 17, 13, 8, 14], [14, 15, 13, 18, 20], [20, 8, 14, 5, 17]])
c = a * m + b
c = my_int_inv(c)
a_inv = a.I
a_det = det(a)
a_adju = my_int_inv(a_det * a_inv)
a_det_inv = exgcd(int(round((det(a) % 26))), 26)
aa_inv = my_int_inv(a_det_inv * a_adju)
m = (aa_inv * (c - b)) % 26
print(m)