Knapsack Problem
最近经常碰到背包问题,所以稍微整理一下
问题描述#
一般我们碰到的都是0 1背包问题,如下,我们已有数字$a_1,a_2…a_n$,从中给它们分别赋予0或者1的权重$w_i$,使得最终的和为$W$,即
$$\sum_1^n w_ia_i = W$$
而在这类问题中,当$n$较大时就是一个$2^n$复杂度的NP问题
解法#
主要通过构造LLL格解决,目前的解法对Knapsack Problem的密度要求为$\frac{n}{log_2(max(pb))}< 0.9408$,具体的格的方法有很多种,脚本内是其中的一种构造
1 | from sage.all import * |
2020 天翼杯 alicehomework#
1 | #!/usr/bin/python |
从加密的函数看就是01背包问题了,并且给出了公钥和最后的密文,直接带入脚本求出二进制bit,然后通过简单运算可以得到结果
1 | from sage.all import * |
2020 WMCTF babysum#
1 | # task.py |
看了看密度是$0.8<0.9408$,以为用前面的脚本也是可以一把梭,结果改了好多格的构造都不行,最后发现是自己一直都没注意一些东西:比如格求解的条件啊啥的。https://0xdktb.top/2020/08/02/WriteUp-WMCTF2020-Crypto 里写的比较好,但大部分人都是看了出题人的博客2333 https://blog.soreatu.com/posts/crypto-research-subset-sum-problem/。
不过即使看到了博客上的源码,跑这个也是费时费钱。。。听说babysum的大哥sum得100核的机器上跑一个小时才出结果。穷苦人家的孩子只能用四核跑一下babysum,大概15分钟的亚子。
1 | # sage |
然后丢进check.py,可以得到WMCTF{83077532752999414286785898029842440}
参考#
- 《Cryptanalysis of two knapsack public-key cryptosystems》
- http://www.dtc.umn.edu/~odlyzko/doc/arch/knapsack.survey.pdf
- https://0xdktb.top/2020/08/02/WriteUp-WMCTF2020-Crypto/
- https://blog.soreatu.com/posts/crypto-research-subset-sum-problem/