概述
打开百度百科搜索背包问题的话可以搜到如下解释
背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?它是在1978年由Merkle和Hellman提出的。
背包问题在郑永辉的博士论文:RSA秘密算法的个攻击技术研究中这样简述:
最终该体制于1982年首先由Shamir用整数规划算法破解,随后在1983年Adimen给出了基于格基约化理论的攻击算法,该算法比Shamir的攻击算法更加有效。
背包算法为第一个推广的公开密钥加密算法,虽然后来发现这个算法不安全,但仍值得研究。
背包问题
还是最常用的例子:
给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v]=max{ f[i-1][v], f[i-1][v-w[i]]+v[i] }。
可以压缩空间,f[v]=max{f[v],f[v-w[i]]+v[i]}
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-w[i]的背包中”,此时能获得的最大价值就是f [i-1][v-w[i]]再加上通过放入第i件物品获得的价值v[i]。
背包加密
例如
背包总重量为70,重量序列为{1,4,6,13,27,52}
最大质量52小于70,因此52在此背包中
下一个重量27大于70-52=18,因此27不在背包中
继续以此类推,直到总重量减少到0或者无法继续减少,则表示已经找到
此处对应的明文是110101
从密钥构造公钥
选择一个超递增序列为密钥{2,3,6,13,27,52}
对每一个值乘以一个数n,对m求余
作为模的数应大于序列中所有数的和
此处设m=107, n与m互素, 取n=29
则背包问题序列为:
229 mod 107 = 58
329 mod 107 = 87
6*29 mod 107 = 67
······
最终得到的公钥序列为:{58,87,67,56,34,10}
要对一个二进制消息进行教秘,先将其分成长度和背包序列相同的块,1表示在包内,0则表示不在
如消息:011001 100101 000101
公钥:{58,87,67,56,34,10}
则
011001:87+67+10=164
100101:58+56+10=124
000101:56+10=66
密文为164,124,66
解密
先计算n-1(乘法逆元)满足n * n-1 mod m = 1
将密文的每一个值与n-1 相乘模m,然后用私钥来求解
继续用上个例子
m=107, n=29, 私钥{2,3,6,13,27,52}密文为164,124,66
计算出n-1=48
则密文要与48相乘模107
164 * 48 mod 107 = 61 = 3+6+52 对应011001
124 * 48 mod 107 = 67 = 2+13+52 对应100101
66 * 48 mod 107 = 65 = 13+52 对应000101
背包型公钥密码
背包型公钥密码系统因其加脱密迅速而受到人们的广 泛注意 , 但是自从L破译算法提出后 , 许多背包型系统已被证明是不安全的。然而人们仍在努力地作背包方案的修改与变形工作, 以此来避开或是抵抗L算法的攻击 , 在已提 出的众多背包系统中, 唯一没有受 到严重威胁的是 Chor-Rivest背包密码系统。Chor-Rivest背包系统的效率优于RSA, 但其安全性能还将受各种攻击方法的检验。
对于密码学中考虑的背包问题,其子集和的解必须是唯一的,但组合数学中涉及的背包问题,一般并不能满足这个条件。因此,在构造新型的背包系统时,要注意选取那些子集和的解是唯一的背包。
Chor-Rivest背包型公钥系统的构成是利用基于有限域理论中的Bose定理得到的整数序列 A = ai, 0 ≤ i ≤ p-1,经置换和平移变换后 , 将作为背包向量与另外一些参数一起被公开。
系统所需的诸参数用如下方法产生 :
- 选拔适当的p 和 n , 使得在 GF(p,n) 中求离散对数是容易 的 。
- 在Zp上找一个 n 阶的既约多项 式 f(t) , 以构成扩域 GF(p,n) 。即 ,GF§ [t] / f(t) = GF(p,n)
- 随机选择 t ∈ GF(p,n) , 使得在 Zp[x]上以 t 为根的最小多项式的次数为 n.
- 随机地选取 GF(p,n) 中任意一个乘法生成元 g , 即< g > = {GF< p·n >’ , · }
- 按照定理 1 , 计算 p 个离散对数值 ai = logg (t + i) ,i=0,1,…,p-1
- 对诸 ai,施行一个 随机选择的置换π : ai→bi = an(i)
- 随机选取0 ≤ d ≤ pn-2 , 使ci= bi+d
这样系统的公开密钥为 c0, c 1,… , cp-1 ; p , n 。 秘密 密钥 为 t ,g, π , d。
加密:设 M 是长为 P、重量为 n 的二进制明文 , 将相应于比特 1 的背包分 量 ci1, ci2 , … cin相加并发送和 : E (M) = ci1 + ci2+…+cin ( mod pn-1)
解密:
- 设 q(t) = tn (mod f(t)) , 该 f(t) 就是在系统产生时找到的 n 阶既约多项式 , q(t) 是次数≤ n-1 次多项式。
- 计算 S = E(M) - nd (mod pn -1 )
- 计算 p(t) = gn (mod f(t)) , p(t))也是一个次数 ≤ n 一 1的多项式 。
- 将 t a- q(t) 与 p(t) 相加 , 得到 R (t) = tn + p(t) - q(t)
R (t) 是 Zp[t]上次数为 n 的多项式 , R(t)可以在 Zp上分 解为 n 个 一次项的乘积: R(t) = (t + i1) ( t +i2 ) … (t + in)。用Zp中的元素 (0 , 1 , ~ , p - 1) 逐次代换 , 能确定R (t) 的 n 个根(ij), j=1 , 2 , … , n 。对( ij) 施行逆变换 π-1 , 可复原明文 M 所具有比特 1 的位置。
其他
对背包体制的攻击方式有:格基约化算法攻击、Briekell 攻击方、穷搜攻击、部分信息泄露攻击等。
后面学习格密码
参考
http://www.cnki.com.cn/Article/CJFDTotal-WJGX199502007.htm
https://baike.baidu.com/item/%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98/2416931?fr=aladdin
https://www.cnblogs.com/ojkojk/p/13413830.html