定义
给定一个由正整数列表和另一个整数(目标和)。问题在于找到该列表的一个子集,使其元素之和恰好等于。
这个问题也可以用二进制向量来描述:寻找一个二进制向量,使得,向量中的1小时对应位置的整数被选中加入子集。
问题的困难性
一般情况:子集和问题通常是一个NP-complete问题,这意味着在计算上通常被认为是困难的
暴力破解:通过检查所有可能的个二进制向量可以找到解,但效率特别低。
碰撞算法:存在一种碰撞算法,可以将运行时间缩短到,但需要巨大的存储空间。
“易解”的情况:超递增序列
如果整数列表是超递增的,那么这个问题就会变得特别容易解决。
- 定义:一个序列是超递增的,如果每一项都大于前面所有项的和,即
- 解法:对于超递增序列,可以使用贪心算法快速找到解,从最大元素开始,如果,则把设为1并从中减去,否则设为0
背包密码系统(Merkle-Hellman)
Merkle和Hellman利用上述特性设计了一种公钥密码系统,其核心思想是将一个“易解”的超递增子集和问题,通过模运算“伪装”成一个看似困难的一般子集和问题
- 密钥生成:
- 私钥:一个超递增序列,以及两个大整数,满足且
- 公钥:一个伪装后的序列,其中,这个序列看起来不再是超递增的
- 加密:发送方将明文消息转化为二进制向量,计算密文发送给接受者
- 解密:接收方(拥有私钥 ),首先计算 。由于 很大,这个同余式实际上是一个等式 。接收方随后利用超递增序列 轻松解出 。
安全性和基于格的攻击
- 主要弱点:教材指出,背包密码系统的根本弱点在于,它可以被重新表述为格中寻找短向量的问题
- 攻击方法:攻击者可以构造一个特定的格,其中包含公钥 和密文 。如果使用格基规约算法(例如 LLL算法)找到了该格中的一个特定短向量,就能直接恢复出明文。
格的构造:
假设公钥序列为,密文为 。攻击者希望找到二进制向量 使得
构造如下 矩阵:
- 格的基:这个矩阵的每一行构成了一个格 的基向量。记前 行为 最后一行为 。
- 目标短向量:如果存在解 ,那么格 中必然包含一个特定的短向量 。这个向量可以通过基向量的线性组合得到:
- 向量的分量:
- 前 格分量为 。由于 只能是 0 或 1 ,所以这些分量的值只能是 1 或 -1。
- 最后一个分量为 。因为 是解,所以这个和等于 ,因此最后一个分量为 0
- 所以,这个特定的短向量 的形式为
- 这个向量 的长度为 ,这相对于格中其他向量(通常长度很大,与 和 的大小有关)来说非常小。使用格基规约算法(如 LLL算法)很有可能找到这个异常短的向量 ,从而恢复出 的值(如果 的第 个分量是 1,则 ,反之为 0),破解密码系统。