原理
背包问题
有一个背包承重为S,对于n个物品,每个物品的重量是ai。问选择哪些物品可以正好放满。写作数学式子就是
∑i=1nxiai=S,xi∈{0,1}
这是一个NP完全问题,也就是说在一般情况下求解的时间复杂度是O(n2),近乎不可求
然而显然可知,对于超递增序列来说在多项式时间内是可解的。
超递增序列:有序列{ai}且∀ai>∑k=1i−1ak。
背包加密
明文处理:将明文改写成二进制数列{xi},xi∈{0,1}
私钥:选取一个超递增序列{ri}作为私钥
公钥:选取B>∑i=1nai,确定A,gcd(A,B)=1,生成公钥序列{Mi},Mi=Ari mod B
加密:计算S=∑i=1nxiMi
背包解密
S’=A−1S=∑i=1nxiri mod B
即可通过超递增序列求解。
攻击
通解
对于log2 max(Mi)n<0.9480有通解。
可以构造如下的格
(x1,x2,…,xn,−1)20⋮0102⋮01……⋱……00⋮21M1M2⋮MnS=(2x1−1,2x2−1,…,2xn−1,0)
M = [?]
S = ?
ge = Matrix(ZZ,len(M)+1)
for i in range(len(M)):
ge[i,i] = 2
ge[i,-1] = M[i]
ge[-1,i] = 1
ge[-1,-1] = S
Ge = ge.LLL()[0]
print(Ge)
m = ""
for i in Ge[:-1]:
m += str(((i+1)//2^^1))
print(m)
print(int(m,2))
注意:我在实际运用过程中对于不同的实际情况,不同的构造,不同的规约方式(LLL,BKZ),发现会有两种答案的产生,并且这两个答案是01互补的。也就说要根据题给的明文长度再次限制答案。
0 条评论