Crypto方向四道题的全部题解:babysign、easyNTRU、NTRURSA、LWE?。
babysign
简单的ECDSA签名,给定nonce,根据签名(R,S)的关系即可得到私钥:。
1 | import hashlib |
easyNTRU
NTRU格密码的标准实现,但是参数过小,可以用格的方法求解出私钥。核心思想如下:。其中也就是f模q的逆。转换一下也就是:。其中g、f的系数都是1,0,-1,且一般来说1,-1的个数很少,也就是f,g系数组成的向量模长小,因此我们可以通过对的系数构成的格进行格基规约,就可以得到f,g,因为在矩阵M行向量构成的格空间内,并且模长很小。M构造如下:
一个完整的NTRU密码体系的分析和格攻击算法参考:LatticeHacks。
1 | import random |
NTRURSA
首先是在模素数域上一个类似NTRU加密的过程,然后把公钥h进行多项式转换,再进行一个多项式RSA的加密。多项式RSA的解法很简单,这里多项式的次数和模数p都很小,可以分解得到两个本原多项式,模本原多项式的群的阶很好计算,就是对多项式每个位置系数进行穷举,除去零元,因此是,再利用积性即可得到阶。h通过RSA多项式群的阶就可以恢复。
NTRU过程的恢复和这篇博客是几乎相同的:NTRU,与上题多项式形式的NTRU过程的格是一致的。
恢复了g1之后,对低20位进行穷举即可,另外一种方法是已知g高位的分解。
1 | from Crypto.Util.number import * |
LWE?
根据题目,显然与容错学习有关,其实就是最初始的LWE模式,A,B,C都是66×200的矩阵,值都定义在之间,x,y,z分别是flag一部分组成的1×66的向量:,其实简单来写就是:。这就是标准的LWE问题。构造格:
显然误差向量e在M行向量构成的格空间内,因为:。通过LLL算法就可以得到e,然后解多元一次方程组即可得到flag。
1 | import re |