一、noise
1. 題目信息
附件是一個Python腳本,Gitee備份在此
2.分析
窮舉通過proof_of_work之后,我們來看代碼邏輯:
- secret=getrandbits(1024),注意他自己實現的getrandbits(1024)實際上是生成長1017~1024位的隨機數;
- 對上述生成的secret,服務器最多只會與你交互64次;
- 若op為'god',服務器會返回num * getrandbits(992) % secret,這里num也由我指定;
- 若op為'bless',服務器會判斷num與secret是否相等,若相等服務器返回FLAG。
由於我至少要留一次交互機會發送我計算出的secret,因此我必須在63次交互內計算出secret!為下面敘述方便,聲明如下記號:
- 第 i 次發送的num記為\(n_{i}\);
- 第 i 次getrandbits(992)記為\(g_{i}\);
- 第 i 次接收的num * getrandbits(992) % secret記為\(c_{i}\)。
記secret為\(m\),則:
\(c_{i} \equiv n_{i}\cdot g_{i}\ \textrm{mod}\ m,i=1,\cdots ,63\)
即存在\(k_{i}\in Z\),\(n_{i}\cdot g_{i}=c_{i}+k_{i}\cdot m\)
對等式兩邊模\(n_{i}\)則有:
\(c_{i}+k_{i}\cdot m \equiv 0\ \textrm{mod}\ n_{i}\)
若我能夠控制\(k_{i}=1\),那么:
\(m \equiv (n_{i}-c_{i})\ \textrm{mod}\ n_{i}\)
同時得到多個如上形式的等式可考慮使用中國剩余定理解出\(m\)!
2.1 利用\(n_{i}\)控制\(k_{i}\)
\(m\)有\(1/2\)的概率長1024比特,\(g_{i}\)有\(1/2\)的概率長992比特;此時,要控制\(k_{i}=1\),即:
對上式兩邊取對數:
記\(log(g_{i})=991+\alpha,log(n_{i})=32+\beta,log(m)=1023+\gamma;\alpha,\beta,\gamma \in (0,1)\)(其中\(X=2^{\alpha},Y=2^{\gamma}\)服從\([1,2]\)上的均勻分布)。上式改寫為:
綜上,\(P(k_{i}=1)=P(\alpha+\beta>\gamma,\alpha+\beta<1+\gamma)=P(2^{\beta}\cdot X>Y,2^{\beta-1}\cdot X<Y)\)
直觀地看,\(\beta\)越大越有利於約束條件\(\alpha+\beta>\gamma\)而不利於約束條件\(\alpha+\beta<1+\gamma\),反之,\(\beta\)越小越有利於約束條件\(\alpha+\beta<1+\gamma\)而不利於約束條件\(\alpha+\beta>\gamma\)。
注意到我可以判斷是否滿足約束條件\(\alpha+\beta>\gamma\)—若\(n_{i}\cdot g_{i}<m\)則\(c_{i}=n_{i}\cdot g_{i}\)從而\(c_{i}\equiv 0 \textrm{mod}\ n_{i}\)。
由此,我選擇\(n_{i}\)時應該盡量滿足約束條件\(\alpha+\beta<1+\gamma\),即\(\beta\)應盡量小,為何不設置\(\beta\)為0,理由如下:
當\(\beta=0\)時,\(P(k_{i}=1)=P(\alpha>\gamma,\alpha<1+\gamma)=P(\alpha>\gamma)=1/2\);
由上述:\(n_{i}\)長\(33\)比特,而\(m\)長\(1024\)比特;由中國剩余定理可知:我們需要32個如下形式的同余式才能解出\(m\)!
\(m \equiv (n_{i}-c_{i})\ \textrm{mod}\ n_{i}\)
要得到如上形式的同余式,即需要\(k_{i}=1\),而\(P(k_{i}=1)=1/2\),那么我得到\(32\)個如上形式的同余式“平均”需要\(64\)次交互,從而我沒有發送secret的交互機會。
綜上,\(\beta\)應在大於0的前提下盡量小!
2.2值得注意的地方
通過2.1,我知道了\(n_{i}\)值多大時可以解出\(m\),結合中國剩余定理,同余式的模數之間是互素的,即我選擇的\(n_{i}\)需兩兩互素,因此\(n_{i}\)不是取確定的值而是在一定的取值范圍內取素數!
3. 解題
上述鏈接中的solve.py為解題的Python腳本,程序運行(成功時)結果如下:
$ python3 solve.py
[+] Opening connection to 182.92.153.117 on port 30101: Done
[+] MBruteforcing: Found key: "l9a"
success!
95613903744255213782277288259288084531700829576284706991256294359734535087821985034716432798049279163174069238632678362676474782669781482301447573436852554131343117198284150657465643396718720128642929008328391123641254705186541184339088382138616985634723733544083949806487213357784626124965521562172300016682
b'CONGRATULATIONS ByteCTF{Noise_i5_rea11y_ANN0YING}\n'
[*] Closed connection to 182.92.153.117 port 30101
注:此程序並非次次運行都能解出secret
二、threshold
1.題目信息
附件是一個Python腳本,Gitee備份在此
2.分析
程序又臭又長,但其實考點特別簡單,稍微使用一下歐拉定理即可!我來分析一下程序的邏輯:
在類TSM2初始化時:
\(pks \equiv [(sk+1)\cdot sks]^{n-2}\ \textrm{mod}\ n\)
接着在output_p1函數中:
\(s \equiv (d_{1}\cdot k_{1}\cdot s_{2}+d_{1}\cdot s_{3}-r)\ \textrm{mod}\ n\)
其中\(d_{1}=sks\),而\(r,s_{2},s_{3}\)均由我指定,那么我令\(r=s_{2}=0,s_{3}=1\),則得到的\(s\)即為\(d_{1}\)在模\(n\)下的值,即:
\(s \equiv sks\ \textrm{mod}\ n\)
注意到\(n\)是素數,歐拉函數\(\phi(n)=n-1\),顯然\((n-2,n-1)=1\),即存在\(x\in Z,x\cdot (n-2)\equiv 1\ \textrm{mod}\ \phi(n)\)
由歐拉定理:\(pks^{x}\equiv [(sk+1)\cdot sks]^{(n-2)x}\equiv (sk+1)\cdot sks\ \textrm{mod}\ n\)
因此\((sk+1)\equiv pks^{x}\cdot sks^{-1}\equiv pks^{x}\cdot s^{-1}\ \textrm{mod}\ n\),而密鑰\(sk\)是小於階\(n\)的,因此解出密鑰\(sk\),有了密鑰干什么不行呢,按照程序的要求,對消息b'Hello, Welcome to ByteCTF2020!'簽名即可!
3.解題
略