2021江西省賽線下賽賽後總結(Crypto)
阿新 • • 發佈:2021-10-25
題很耐斯,我覺得對我這種菜雞來說值得好好琢磨
是二進位制下\(l-1\)位的數字。所以在兩邊同時加上p,有:
\[\begin{equation}
\begin{aligned}
p+adlit(p)&=((2^l-1)\oplus p)+p \\
p+adlit(p)&=\neg p+p
\end{aligned}
\end{equation}
\]
crypto1
題目:
from random import randint from gmpy2 import * from Crypto.Util.number import * from flag import flag e = 65537 def getprime(bits): while True: n = 1 while n.bit_length() < bits: n *= next_prime(randint(1, 1000)) if isPrime(n - 1): return n - 1, next_prime(n - 1) m = bytes_to_long(flag) p, q = getprime(512) n = p * q print(n) cipher = pow(m, e, n) print(cipher) ''' 1218619816262698783546648940878194669948979438203709672616480993515396961355395106056079918611561560475179643559119588585898564073516537184901016698826515936521556602092317546069579399703397931712467163230371193719052714305461017238967564606988838393544992753947092855374755747446894202750381311264877872839091 352354447911429303374519396490477565259821643971034839508568182565346164389287956989900378749729230944730331100775811131476843801977815021460665576439081472176097865974428184576142512412853496411268585776818066203487906030045789380455941042181582290374609632090947501064978978356385970005273609161215198427253 '''
思路:
- 直接yafu分解n
- 仔細看了看,好像可能是不是沒有其它解法了?
crypto2
題目:
from Crypto.Util.number import * from secret import flag, NBIT, MIDDLE assert MIDDLE < 4096 def rsarsa(nbit): while True: p = getPrime(nbit) middle = (2**nbit - 3) ^ p q = middle + MIDDLE if isPrime(q): return p,q p,q = rsarsa(NBIT) e = 0x10001 n = p * q m = bytes_to_long(flag) c = pow(m,e,n) print('n =', n) print('c =', c) ''' n = 692224041388945379000542945310902880889100544298206558809223921382304144887565486168738878540375370962131523216110266003450063038852597901973959069961409252090233088923246072020448653242413438525803983280986587695098100053523677324314279892099704680639276122605007782194993832619487191722743054531524695485466578897531910673635843617334895918839728199336965513679879931120369894252383320216068550188557341291620047417322944706390751843111508918089789408109422357563835039746241760245490926252447703597477533668752930171198897054058982716965576506579176144003183647342789557878319494827627831312013617439863026665812607443 c = 307197727308287745314426467002903248074969761558679046606456172330293223597622415661766314599586983706525802752702590834171088229466177584813058269117390420554764305566689318459776899180134066369190626054796865325243251558047293127988662783785017198221284274732844911397443405439812227924713443788235973809737857889544240278704700770780579167766105940360383012181564955578959555701526997721449721679761556310570137638766549920135248234070586743609456381815893734230223940645912347773433002389063138902856398043379520285872239709077175291162768996775352120726794354655215827681853155145863834324898022202315574453344333550 '''
思路:
還是考慮直接分解n,可以嘗試利用一元二次方程分解。原理如下:
因為\(x^2+bx+c=0\),所以如果找到一個\(b=a\sqrt{c}\),那麼就有:
\[x^2+2\sqrt{c}\ x+c=0 \\ (x+\sqrt{c})^2=0 \]這裡有個非常相似的題:Crypto CTF 2019-roXen
其它部分這裡就不再贅述,原文章寫的很詳盡,在這裡只記錄我在看的時候遇到的小小阻礙:
adlit函式實際上就是等式:\(p+adlit(p)=2^l-1\),其中\(l\)是p的二進位制長度
這個推論的過程如下:
因為\(adlit(p)=(2^l-1)\oplus p\),而其中\(2^l-1\)
而\(\neg p+p\)的結果可以參考下面的程式:
p=eval(bin(2**12-1))
q=0b110101001011
k=p^q
print(bin(2**12-1))
print(len(bin(2**12-1)))
print(bin(q))
print(len(bin(q)))
print(bin(k))
print(len(bin(k)))
print(bin(q+k))
print(len(bin(q+k)))
>>>0b111111111111
>>>14
>>>0b1010110100
>>>12
>>>0b111111111111
>>>14
所以有\(\neg p+p=2^n-1\),其中\(n\)是p的位數加一(2的n次方有n+1位)
而在這個題中,adlit函式就是middle,功能是一樣的(雖然我不理解為啥減三也可以……但是把上面那個程式碼改一改就會發現結果是一樣的。)所以這樣想的思路就明確了,有:
這裡加上一個MIDDLE(\(MIDDLE<4096\))也可以在一定程度上可以抵消後面那個減三,從而可以把一個推測值直接設成\(2^{nbits}\),不過如果MIDDLE小於3,那麼就可能會出現求不出來的情況~
而在這個題中我們無法完全肯定nbits的取值,所以在儘可能縮小取值之後可以進行爆破處理:
- 由於n的位數(二進位制下)為2063,所以可以嘗試將nbits設為1030或者1024等值
- 然後可以嘗試尋找一個\(\sqrt{(p+q)^2-4p*q}\)可以完全開放的nbits和MIDDLE,從步驟1中設的值開始(或者也可以先做一個迴圈,找到滿足\(4n-(2^{nbits}-3)<4096\)情況的nbits)
不過我也明確了一個問題:工具不是萬能的,不能完全依賴工具(尤其是不是自己寫的工具)