最近复现了一道NCTF的压轴密码题。这道密码题我打比赛的时候是懵逼的,后来看了出题人soreatu师傅的wp才学习到了这个算法(其实原理还是有些地方不太懂。。。)
全称为Adleman-Mander-Miller Method。在1977年他们发表的论文里只涉及了开平方根的方法,开n次方根并没有很详细的介绍。《Adleman-Manders-Miller Root Extraction Method Revisited》里三位中国人补充了他们开n次方根的方法。
AMM里开平方根的算法与Tonelli–Shanks算法几乎一样,只不过后面乘积时一个是从大到小一个是从小到大,所以我简要的介绍一下开平方根的思路。
首先令 p − 1 = 2 t s p-1=2^ts p−1=2ts
接着计算出模p的二次非剩余 ρ
根据欧拉准则,我们有
( δ s ) 2 t − 1 ≡ 1 m o d p (δ^s)^ {2^{t-1}}\equiv1\ mod \ p (δs)2t−1≡1 mod p
( ρ s ) 2 t − 1 ≡ − 1 m o d p (ρ^s)^ {2^{t-1}}\equiv-1\ mod \ p (ρs)2t−1≡−1 mod p
如果 t = 1 t=1 t=1,则
( δ s + 1 2 ) 2 ≡ 1 m o d p (δ^{\frac{s+1}{2}})^2\equiv1\ mod \ p (δ2s+1)2≡1 mod p
所以 δ s + 1 2 δ^{\frac{s+1}{2}} δ2s+1就是开平方根的结果。
如果 t ≥ 2 t\geq2 t≥2,
那么 ( δ s ) 2 t − 1 (δ^s)^ {2^{t-1}} (δs)2t−1开平方根以后的结果就是1或者-1。
即:
( δ s ) 2 t − 2 m o d p ∈ { 1 , − 1 } (δ^s)^ {2^{t-2}}mod \ p\in \{1,-1\} (δs)2t−2mod p∈{1,−1}
但我们仍有办法使它变成1。令 k 1 = 0 o r 1 k_1=0\ or\ 1 k1=0 or 1,使得
( δ s ) 2 t − 2 ( ρ s ) 2 t − 1 k 1 ≡ 1 m o d p (δ^s)^ {2^{t-2}}(ρ^s)^{2^{t-1}k_1} \equiv 1\ mod\ p (δs)2t−2(ρs)2t−1k1≡1 mod p
因为 ( ρ s ) 2 t − 1 ∗ 0 = 1 (ρ^s)^{2^{t-1}*0}=1 (ρs)2t−1∗0=1, ( ρ s ) 2 t − 1 ∗ 1 = − 1 (ρ^s)^{2^{t-1}*1}=-1 (ρs)2t−1∗1=−1
同样的,对上式继续开平方根,使得:
( δ s ) 2 t − 3 ( ρ s ) 2 t − 2 k 1 m o d p ∈ { 1 , − 1 } (δ^s)^ {2^{t-3}}(ρ^s)^{2^{t-2}k_1}mod \ p\in \{1,-1\} (δs)2t−3(ρs)2t−2k1mod p∈{1,−1}
令 k 2 = 0 o r 1 k_2=0\ or\ 1 k2=0 or 1,则
( δ s ) 2 t − 3 ( ρ s ) 2 t − 2 k 1 ( ρ s ) 2 t − 1 k 2 ≡ 1 m o d p (δ^s)^ {2^{t-3}}(ρ^s)^{2^{t-2}k_1}(ρ^s)^{2^{t-1}k_2} \equiv 1\ mod\ p (δs)2t−3(ρs)2t−2k1(ρs)2t−1k2≡1 mod p
同样的,我们取 k 3 , k 4 , . . . , k t − 1 ∈ { 1 , − 1 } k_3,k_4,...,k_{t-1}\in\{1,-1\} k3,k4,...,kt−1∈{1,−1},则
( δ s ) ( ρ s ) 2 k 1 + 2 2 k 2 + . . . + 2 t − 2 k t − 1 ≡ 1 m o d p (δ^s)(ρ^s)^{2k_1+2^2k_2+...+2^{t-2}k_{t-1}} \equiv 1\ mod\ p (δs)(ρs)2k1+22k2+...+2t−2kt−1≡1 mod p
两边同时乘δ并提出平方,则:
( δ s + 1 2 ) ( ρ s ) k 1 + 2 k 2 + . . . + 2 t − 3 k t − 1 (δ^{\frac{s+1}{2}})(ρ^s)^{k_1+2k_2+...+2^{t-3}k_{t-1}} (δ2s+1)(ρs)k1+2k2+...+2t−3kt−1
就是开平方根的结果。
(很不成熟,所以有些解决不了的推论当作已知来处理)
解n次方根需要考虑两种情况:
(1) g c d ( r , q − 1 ) = 1 gcd(r,q-1)=1 gcd(r,q−1)=1
(2) r ∣ ( q − 1 ) r|(q-1) r∣(q−1)
如果 r 和 q-1 互素,直接求逆元就能解决(普通RSA解密)
如果 r ∣ ( q − 1 ) r|(q-1) r∣(q−1)
令 q − 1 = r t s q-1=r^ts q−1=rts.
因为δ是r次剩余,所以我们有 δ q − 1 r ≡ ( X r ) q − 1 r ≡ X q − 1 ≡ 1 m o d q δ^{\frac{q-1}{r}}\equiv({X^r})^{\frac{q-1}{r}}\equiv X^{q-1}\equiv 1\ mod\ q δrq−1≡(Xr)rq−1≡Xq−1≡1 mod q
找一个最小的非负整数α使得 s ∣ r α − 1 s|rα-1 s∣rα−1 (后面要开r次方根)
所以 ( δ r α − 1 ) r t − 1 ≡ 1 (δ^{rα-1})^{r^{t-1}}\equiv 1 (δrα−1)rt−1≡1
如果 t = 1 t=1 t=1,则开根结果为δα.
若 t ≥ 2 t\geq2 t≥2,
取r次非剩余 ρ ρ ρ( ρ q − 1 r ≠ 1 m o d q ρ^{\frac{q-1}{r}}\neq1\ mod\ q ρrq−1=1 mod q)
令 K i = ( ρ s ) i ∗ r t − 1 a n d K = { K 0 , K 1 , . . . K r − 1 } K_i=(ρ^s)^{i*r^{t-1}} and\ K=\{K_0,K_1,...K_{r-1}\} Ki=(ρs)i∗rt−1and K={K0,K1,...Kr−1}
且对于所有的 K i K_i Ki,都是模1开r次方根的结果,即 ( K i ) r ≡ 1 (K_i)^r\equiv1 (Ki)r≡1.
而且我们还知道 K i K_i Ki互不相同,即:
( ρ s ) i ∗ r t − 1 ≠ ( ρ s ) j ∗ r t − 1 i ≠ j a n d i , j ∈ { 0 , 1 , . . . , r − 1 } (ρ^s)^{i*r^{t-1}}\neq(ρ^s)^{j*r^{t-1}} \ i\neq j\ and\ i,j\in \{0,1,...,r-1\} (ρs)i∗rt−1=(ρs)j∗rt−1 i=j and i,j∈{0,1,...,r−1}
也就是说模1开r次方根的结果的集合都在K这个集合里。
而且 K i ∗ K r − i ≡ 1 ( r − i ≡ − i m o d r ) K_i*K_{r-i}\equiv1\ (r-i\equiv -i\ mod\ r) Ki∗Kr−i≡1 (r−i≡−i mod r)
这两步我真的不懂,就当作已知了(可是验算出来都是正确的)
2020.5.12 更新:
(来填坑了,之前不理解的现在理解了)
ρ ρ ρ是之前取的一个 r r r次非剩余,我们可以定义一个生成元为 ρ ρ ρ的模 q q q的循环群 G G G
G = { 1 , ρ 2 , ρ 3 , . . . , ρ q − 1 } G=\{1,ρ^2,ρ^3,...,ρ^{q-1}\} G={1,ρ2,ρ3,...,ρq−1}
在该循环群 G G G中,我们再定义 ρ 1 = ρ p − 1 r ρ_1=ρ^{\frac{p-1}{r}} ρ1=ρrp−1,所以可以得到一个生成元为 ρ 1 ρ_1 ρ1的子群 H H H为
H = { 1 , ρ q − 1 r , ρ q − 1 r ∗ 2 , ρ q − 1 r ∗ 3 , . . . , ρ q − 1 r ∗ ( r − 1 ) } H=\{1,ρ^{\frac{q-1}{r}},ρ^{\frac{q-1}{r}*2},ρ^{\frac{q-1}{r}*3},...,ρ^{\frac{q-1}{r}*(r-1)}\} H={1,ρrq−1,ρrq−1∗2,ρrq−1∗3,...,ρrq−1∗(r−1)}
在这个子群里,所有的元素都是由 ρ 1 = ρ p − 1 r ρ_1=ρ^{\frac{p-1}{r}} ρ1=ρrp−1生成的,所以所有元素的 r r r次方都为1,因为子群 H H H里正好有 r r r个元素,所以 H H H是模1开r次方根的结果的集合。(解释了第一个问题)
对于群来说每个元素都存在逆元,而且因为 ρ q − 1 = 1 m o d p ρ^{q-1}=1 mod\ p ρq−1=1mod p,所以对于子群里任何一个元素 ρ p − 1 r ∗ i ρ^{\frac{p-1}{r}*i} ρrp−1∗i来说,都有:
ρ q − 1 r ∗ i ∗ ρ q − 1 r ∗ ( r − i ) = ρ q − 1 = 1 m o d q ρ^{\frac{q-1}{r}*i}*ρ^{\frac{q-1}{r}*(r-i)}=ρ^{{q-1}}= 1 mod\ q ρrq−1∗i∗ρrq−1∗(r−i)=ρq−1=1mod q
(解释了第二个问题)
题外话:其实并不需要群理论,只用把 ( ρ s ) i ∗ r t − 1 (ρ^s)^{i*r^{t-1}} (ρs)i∗rt−1换成 ( ρ ) q − 1 r ∗ i (ρ)^{\frac{q-1}{r}*i} (ρ)rq−1∗i来理解就很好理解了。
有了这两个条件,我们可以开始像解平方根那样解n次方根了:
首先
( ( δ r α − 1 ) r t − 2 ) r ≡ 1 ((δ^{rα-1})^{r^{t-2}})^r\equiv 1 ((δrα−1)rt−2)r≡1
开r次方后余数为集合 K K K中的一个数,设为 K r − j K_{r-j} Kr−j,即:
( δ r α − 1 ) r t − 2 ≡ K r − j (δ^{rα-1})^{r^{t-2}}\equiv K_{r-j} (δrα−1)rt−2≡Kr−j
求逆元,得:
( δ r α − 1 ) r t − 2 K j ≡ 1 (δ^{rα-1})^{r^{t-2}}K_{j}\equiv 1 (δrα−1)rt−2Kj≡1
即:
( δ r α − 1 ) r t − 2 ( ρ s ) j ∗ r t − 1 ≡ 1 (δ^{rα-1})^{r^{t-2}}(ρ^s)^{j*r^{t-1}}\equiv 1 (δrα−1)rt−2(ρs)j∗rt−1≡1
同样的,继续开方,最终得到:
( δ r α − 1 ) ( ρ s ) j 1 ∗ r 1 + j 2 ∗ r 2 + . . . + j t − 1 ∗ r t − 1 ≡ 1 (δ^{rα-1})(ρ^s)^{j_1*r^{1}+j_2*r^2+...+j_{t-1}*r^{t-1} } \equiv 1 (δrα−1)(ρs)j1∗r1+j2∗r2+...+jt−1∗rt−1≡1
最后乘δ提取r次方:
( δ α ) r ( ( ρ s ) j 1 + j 2 ∗ r 1 + . . . + j t − 1 ∗ r t − 2 ) r ≡ δ (δ^{α})^r((ρ^s)^{j_1+j_2*r^1+...+j_{t-1}*r^{t-2} } )^r\equiv δ (δα)r((ρs)j1+j2∗r1+...+jt−1∗rt−2)r≡δ
得到最终结果:
δ α ( ρ s ) j 1 + j 2 ∗ r 1 + . . . + j t − 1 ∗ r t − 2 δ^{α}(ρ^s)^{j_1+j_2*r^1+...+j_{t-1}*r^{t-2} } δα(ρs)j1+j2∗r1+...+jt−1∗rt−2
算法如下:
其实开n次方根的方法还有很多,只不过我目前只学了这一种。。。
大佬wp在这里
CTF三大谎言:baby、easy、warmup
题目只给了e,p,q,c
然而e|p-1,e|q-1,根本无从下手。
其实我们可以先用中国剩余定理展开
m e ≡ c m o d p m^e \equiv c\ mod\ p me≡c mod p m e ≡ c m o d q m^e \equiv c\ mod\ q me≡c mod q
由于e比较小,所以可以用上述开n次方的方法,在模p和模q中分别找到一个0x1337次方的根 m 0 m_0 m0。
然而实际上0x1337开根会产生1337个根,那么如何找到剩余的0x1336个根呢?
根据公式:
( x p − 1 e ) e ≡ x q − 1 ≡ 1 (x^{\frac{p-1}{e}})^e\equiv x^{q-1}\equiv 1 (xep−1)e≡xq−1≡1
所以可以通过用 m 0 ∗ x p − 1 e m_0*x^{\frac{p-1}{e}} m0∗xep−1的方式找到剩余的0x1336个根。
最后模p的0x1337个根和模q的0x1337个根,一共有4919*4919=24196561种组合,再利用中国剩余定理,就能算出最终的flag。
提示:
list=set()
while(len(list)
这几行代码可以保证生成的子根不会有重复
完整代码在这里
参考文章:
首先是大佬的博客
然后是论文
第一次学到了这种开方的姿势,眼光宽广了很多,以后也会继续努力滴!