GHCTF

ouo

上周天打了GHCTF,题虽然不是特别难(毕竟说的是新生赛)不过也刚好巩固了一下基础

baby_signin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import getPrime, bytes_to_long
p=getPrime(128)
q=getPrime(128)
n=p*q
phi=(p-1)*(q-1)
flag="NSSCTF{xxxxxx}"
print("p=",p)
print("q=",q)
m=bytes_to_long(flag.encode())
e=4
c=pow(m,e,n)
print("c=",c)
print("n=",n)
'''
p= 182756071972245688517047475576147877841
q= 305364532854935080710443995362714630091
c= 14745090428909283741632702934793176175157287000845660394920203837824364163635
n= 55807222544207698804941555841826949089076269327839468775219849408812970713531
'''

看到e=4其实就大概有思路了,不是rabin就是e与phi不互素。首先尝试一下二次rabin发现出不来。那么就大致确定是e与phi不互素,最后验证一下发现确实是这样。对于不互素问题我们通常有两种解法。第一种是求gcd(e,phi)=t,把m$^t$看作整体去处理,尝试后发现这个方法在本题中不使用。那么我们就直接进行有限域开根。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Util.number import *
import gmpy2
e=4
p= 182756071972245688517047475576147877841
q= 305364532854935080710443995362714630091
c= 14745090428909283741632702934793176175157287000845660394920203837824364163635
n= 55807222544207698804941555841826949089076269327839468775219849408812970713531
print(gcd(e,((p-1)*(q-1))))
R.<x> = PolynomialRing(Zmod(p))
f = x^4 - c
res1 = f.roots()

R.<x> = PolynomialRing(Zmod(q))
f = x^4 - c
res2 = f.roots()

for i in res1:
for j in res2:
m = crt([int(i[0]),int(j[0])],[p,q])
print(long_to_bytes(m))

baby_factor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from Crypto.Util.number import *
def create():
pl = []
for i in range(3):
pl.append(getPrime(1024))
return sorted(pl)
pl = create()
m=b'NSSCTF{xxx}'
p,q,r = pl[0],pl[1],pl[2]
e = 65537
n = p*q*r
phi = (p-1)*(q-1)*(r-1)
c=pow(bytes_to_long(m),e,n)
print(f'n={n}')
print(f'phi={phi}')
print(f'c={c}')
"""
n=2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197846086151042512153782486075793224874304872205720564733574010669935992016367832666397263951446340260962650378484847385424893514879629196181114844346169851383460163815147712907264437435463059397586675769959094397311450861780912636566993749356097243760640620004707428340786147078475120876426087835327094386842765660642186546472260607586011343238080538092580452700406255443887820337778505999803772196923996033929998741437250238302626841957729397241851219567703420968177784088484002831289722211924810899441563382481216744212304879717297444824808184727136770899310815544776369231934774967139834384853322157766059825736075553
phi=2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197784246608456057052779643060628984335578973450260519106769911425793594847759982583376628098472390090331415895352869275325656949958242181688663465437185437198392460569653734315961071709533645370007008616755547195108861900432818710027794402838336405197750190466425895582236209479543326147804766393022786785337752319686125574507066082357748118175068545756301823381723776525427724798780890160482013759497102382173931716030992837059880049832065500252713739288235410544982532170147652055063681116147027591678349638753796122845041417275362394757384204924094885233281257928031484806977974575497621444483701792085077113227851520
c=2675023626005191241628571734421094007494866451142251352071850033504791090546156004348738217761733467156596330653396106482342801412567035848069931148880296036606611571818493841795682186933874790388789734748415540102210757974884805905578650801916130709273985096229857987312816790471330181166965876955546627327549473645830218664078284830699777113214559053294592015697007540297033755845037866295098660371843447432672454589238297647906075964139778749351627739005675106752803394387612753005638224496040203274119150075266870378506841838513636541340104864561937527329845541975189814018246183215952285198950920021711141273569490277643382722047159198943471946774301837440950402563578645113393610924438585345876355654972759318203702572517614743063464534582417760958462550905093489838646250677941813170355212088529993225869303917882372480469839803533981671743959732373159808299457374754090436951368378994871937358645247263240789585351233
"""

给了phi直接求解就行,没啥好说的。

1
2
3
4
5
6
7
8
9
10
from Cryptodome.Util.number import *
from gmpy2 import gmpy2, gcd
from sympy import isprime

n=2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197846086151042512153782486075793224874304872205720564733574010669935992016367832666397263951446340260962650378484847385424893514879629196181114844346169851383460163815147712907264437435463059397586675769959094397311450861780912636566993749356097243760640620004707428340786147078475120876426087835327094386842765660642186546472260607586011343238080538092580452700406255443887820337778505999803772196923996033929998741437250238302626841957729397241851219567703420968177784088484002831289722211924810899441563382481216744212304879717297444824808184727136770899310815544776369231934774967139834384853322157766059825736075553
phi=2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197784246608456057052779643060628984335578973450260519106769911425793594847759982583376628098472390090331415895352869275325656949958242181688663465437185437198392460569653734315961071709533645370007008616755547195108861900432818710027794402838336405197750190466425895582236209479543326147804766393022786785337752319686125574507066082357748118175068545756301823381723776525427724798780890160482013759497102382173931716030992837059880049832065500252713739288235410544982532170147652055063681116147027591678349638753796122845041417275362394757384204924094885233281257928031484806977974575497621444483701792085077113227851520
c=2675023626005191241628571734421094007494866451142251352071850033504791090546156004348738217761733467156596330653396106482342801412567035848069931148880296036606611571818493841795682186933874790388789734748415540102210757974884805905578650801916130709273985096229857987312816790471330181166965876955546627327549473645830218664078284830699777113214559053294592015697007540297033755845037866295098660371843447432672454589238297647906075964139778749351627739005675106752803394387612753005638224496040203274119150075266870378506841838513636541340104864561937527329845541975189814018246183215952285198950920021711141273569490277643382722047159198943471946774301837440950402563578645113393610924438585345876355654972759318203702572517614743063464534582417760958462550905093489838646250677941813170355212088529993225869303917882372480469839803533981671743959732373159808299457374754090436951368378994871937358645247263240789585351233
e=65537
d = gmpy2.invert(e,phi)
print(long_to_bytes(pow(c,d,n)))

EZ_Fermat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from Crypto.Util.number import getPrime, bytes_to_long
from secret import f

flag = b'NSSCTF{test_flag}'
p = getPrime(512)
q = getPrime(512)
n = p*q

m = bytes_to_long(flag)
e = 65537
c = pow(m,e,n)

R.<x> = ZZ[]
f = R(str(f))

w = pow(2,f(p),n)


print(f'{n = }\n')
print(f'{e = }\n')
print(f'{c = }\n')
print(f'{f = }\n')
print(f'{w = }\n')


'''
n = 101780569941880865465631942473186578520071435753163950944409148606282910806650879176280021512435190682009749926285674412651435782567149633130455645157688819845748439487113261739503325065997835517112163014056297017874761742768297646567397770742374004940360061700285170103292360590891188591132054903101398360047
e = 65537
c = 77538275949900942020886849496162539665323546686749270705418870515132296087721218282974435210763225488530925782158331269160555819622551413648073293857866671421886753377970220838141826468831099375757481041897142546760492813343115244448184595644585857978116766199800311200819967057790401213156560742779242511746
f = 2*x^332 - x^331 + x^329 + 3*x^328 - x^327 - 3*x^325 + x^323 - 3*x^322 - x^321 - 3*x^320 + x^319 + 2*x^318 - 4*x^317 - 3*x^315 - 2*x^314 + x^313 + x^312 + 2*x^311 + 2*x^309 + 2*x^308 + 5*x^307 + 2*x^306 + 3*x^305 + 5*x^304 + 4*x^303 + x^302 - x^301 - x^300 - 2*x^299 - 2*x^298 + x^297 + 3*x^296 - x^295 - 4*x^292 - x^290 + 4*x^289 - x^287 - 3*x^286 + x^285 - 2*x^284 + x^283 - x^282 - 2*x^281 + x^280 - 2*x^279 + x^278 + 2*x^277 - 3*x^276 - x^275 - 4*x^274 - 3*x^273 - 5*x^272 - 2*x^271 - 3*x^270 + 2*x^269 + 2*x^268 - x^267 - 2*x^266 + x^265 + x^264 - 3*x^262 - 3*x^259 + 2*x^258 - x^257 + 2*x^256 + 2*x^255 - x^254 - 2*x^253 - x^252 + 2*x^251 - x^250 + x^249 + 2*x^247 + 2*x^246 + 2*x^245 - 2*x^244 - 3*x^243 + 2*x^242 - 3*x^241 - x^240 - 3*x^239 - x^236 - 3*x^235 - 2*x^234 - x^233 - 2*x^232 - x^231 - 3*x^230 - 2*x^229 - 4*x^228 - 2*x^227 - 3*x^226 + 2*x^225 + x^224 - x^223 - 2*x^221 + 3*x^219 - x^217 - 2*x^216 + x^215 + 2*x^213 - x^212 + 3*x^211 + x^210 + 4*x^209 + x^208 - x^206 - x^205 - x^204 + 2*x^203 - 3*x^202 + 2*x^199 - x^198 + 2*x^196 - 2*x^195 + 3*x^194 + 3*x^193 - x^192 + 4*x^191 + 2*x^189 + x^186 - x^185 - x^184 + 3*x^183 + x^182 + 2*x^181 - 2*x^180 + x^177 + x^175 - x^173 + 3*x^172 + x^170 + x^169 - x^167 - 2*x^166 - x^165 - 4*x^164 - 2*x^163 + 2*x^162 + 4*x^161 - 2*x^160 - 3*x^159 - 2*x^158 - 2*x^157 + x^156 - x^155 + 3*x^154 - 4*x^153 + x^151 + 2*x^150 + x^149 - x^148 + 2*x^147 + 3*x^146 + 2*x^145 - 4*x^144 - 4*x^143 + x^142 - 2*x^140 - 2*x^139 + 2*x^138 + 3*x^137 + 3*x^136 + 3*x^135 + x^134 - x^133 + 2*x^132 + 3*x^130 - 3*x^129 - 2*x^128 - x^127 - 2*x^126 + x^125 + x^124 - 2*x^123 + x^122 - x^121 + 3*x^120 - x^119 - 2*x^118 - x^117 - x^116 - 2*x^115 + 2*x^114 + 2*x^113 - 3*x^112 - x^111 - 4*x^110 + x^109 + x^108 + x^106 - 4*x^105 + x^104 - x^103 - x^101 + x^100 - 2*x^99 + x^98 - x^97 + 3*x^96 + 3*x^94 - x^93 - x^92 + x^91 - 2*x^90 + x^89 - x^88 + x^87 - x^86 + x^85 + x^84 - x^83 + x^79 - 3*x^78 - 2*x^77 + x^74 + 3*x^73 - x^72 - 3*x^71 - 2*x^70 + x^69 - 3*x^66 + x^65 + x^64 - 4*x^62 - x^61 + x^60 - x^59 + 3*x^58 - x^57 - x^54 + 3*x^53 + x^51 - 3*x^50 - x^49 + 2*x^47 - x^46 - x^44 + x^43 - x^42 - 4*x^41 - 3*x^39 - x^37 - x^36 - 3*x^35 + x^34 + x^33 - 2*x^32 + 2*x^31 - x^30 + 2*x^29 - 2*x^28 - 2*x^27 - x^24 + x^22 - 5*x^21 + 3*x^20 + 2*x^19 - x^18 + 2*x^17 + x^16 - 2*x^15 - 2*x^14 + x^13 + x^12 + 2*x^11 - 3*x^10 + 3*x^9 + 2*x^8 - 4*x^6 - 2*x^5 - 4*x^4 + x^3 - x^2 - 1
w = 32824596080441735190523997982799829197530203904568086251690542244969244071312854874746142497647579310192994177896837383837384405062036521829088599595750902976191010000575697075792720479387771945760107268598283406893094243282498381006464103080551366587157561686900620059394693185990788592220509670478190685244
'''

题目给出提示,其实就是考察费马小定理。题目给出了2$^{f(p)}$mod n=w,根据中国剩余定理,很明显对于模p和模q同样成立。同时根据费马小定理2$^{p-1}$=1 mod p,我们可以化简为2$^{f(p)mod(p-1)}$mod p =w那么如何求f(p) mod (p-1)呢。

p≡1mod(p−1),即 p 除以 p−1的余数为 1。因此,对于任意正整数 k,有:p$^k$≡1$^k$≡1mod  (p−1),将 p≡1mod  (p−1) 代入 f(p),得到的正是f(1)的值。即f(p) mod (p-1)=f(1) mod (p-1)再将指数转为f(1),即可得到2$^{f(1)}$mod n=w,即2$^{f(1)}$-w=0 mod n,将1代入多项式求解后取gcd(2$^{f(1)}$-w,n)即可得到p。随后正常求解rsa即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

from Cryptodome.Util.number import *
def f(x):
return (
2 * x**332 - x**331 + x**329 + 3 * x**328 - x**327 - 3 * x**325 + x**323
- 3 * x**322 - x**321 - 3 * x**320 + x**319 + 2 * x**318 - 4 * x**317
- 3 * x**315 - 2 * x**314 + x**313 + x**312 + 2 * x**311 + 2 * x**309
+ 2 * x**308 + 5 * x**307 + 2 * x**306 + 3 * x**305 + 5 * x**304
+ 4 * x**303 + x**302 - x**301 - x**300 - 2 * x**299 - 2 * x**298 + x**297
+ 3 * x**296 - x**295 - 4 * x**292 - x**290 + 4 * x**289 - x**287
- 3 * x**286 + x**285 - 2 * x**284 + x**283 - x**282 - 2 * x**281
+ x**280 - 2 * x**279 + x**278 + 2 * x**277 - 3 * x**276 - x**275
- 4 * x**274 - 3 * x**273 - 5 * x**272 - 2 * x**271 - 3 * x**270
+ 2 * x**269 + 2 * x**268 - x**267 - 2 * x**266 + x**265 + x**264
- 3 * x**262 - 3 * x**259 + 2 * x**258 - x**257 + 2 * x**256 + 2 * x**255
- x**254 - 2 * x**253 - x**252 + 2 * x**251 - x**250 + x**249 + 2 * x**247
+ 2 * x**246 + 2 * x**245 - 2 * x**244 - 3 * x**243 + 2 * x**242
- 3 * x**241 - x**240 - 3 * x**239 - x**236 - 3 * x**235 - 2 * x**234
- x**233 - 2 * x**232 - x**231 - 3 * x**230 - 2 * x**229 - 4 * x**228
- 2 * x**227 - 3 * x**226 + 2 * x**225 + x**224 - x**223 - 2 * x**221
+ 3 * x**219 - x**217 - 2 * x**216 + x**215 + 2 * x**213 - x**212
+ 3 * x**211 + x**210 + 4 * x**209 + x**208 - x**206 - x**205 - x**204
+ 2 * x**203 - 3 * x**202 + 2 * x**199 - x**198 + 2 * x**196 - 2 * x**195
+ 3 * x**194 + 3 * x**193 - x**192 + 4 * x**191 + 2 * x**189 + x**186
- x**185 - x**184 + 3 * x**183 + x**182 + 2 * x**181 - 2 * x**180
+ x**177 + x**175 - x**173 + 3 * x**172 + x**170 + x**169 - x**167
- 2 * x**166 - x**165 - 4 * x**164 - 2 * x**163 + 2 * x**162 + 4 * x**161
- 2 * x**160 - 3 * x**159 - 2 * x**158 - 2 * x**157 + x**156 - x**155
+ 3 * x**154 - 4 * x**153 + x**151 + 2 * x**150 + x**149 - x**148
+ 2 * x**147 + 3 * x**146 + 2 * x**145 - 4 * x**144 - 4 * x**143 + x**142
- 2 * x**140 - 2 * x**139 + 2 * x**138 + 3 * x**137 + 3 * x**136 + 3 * x**135
+ x**134 - x**133 + 2 * x**132 + 3 * x**130 - 3 * x**129 - 2 * x**128
- x**127 - 2 * x**126 + x**125 + x**124 - 2 * x**123 + x**122 - x**121
+ 3 * x**120 - x**119 - 2 * x**118 - x**117 - x**116 - 2 * x**115 + 2 * x**114
+ 2 * x**113 - 3 * x**112 - x**111 - 4 * x**110 + x**109 + x**108 + x**106
- 4 * x**105 + x**104 - x**103 - x**101 + x**100 - 2 * x**99 + x**98
- x**97 + 3 * x**96 + 3 * x**94 - x**93 - x**92 + x**91 - 2 * x**90
+ x**89 - x**88 + x**87 - x**86 + x**85 + x**84 - x**83 + x**79
- 3 * x**78 - 2 * x**77 + x**74 + 3 * x**73 - x**72 - 3 * x**71
- 2 * x**70 + x**69 - 3 * x**66 + x**65 + x**64 - 4 * x**62 - x**61
+ x**60 - x**59 + 3 * x**58 - x**57 - x**54 + 3 * x**53 + x**51
- 3 * x**50 - x**49 + 2 * x**47 - x**46 - x**44 + x**43 - x**42
- 4 * x**41 - 3 * x**39 - x**37 - x**36 - 3 * x**35 + x**34 + x**33
- 2 * x**32 + 2 * x**31 - x**30 + 2 * x**29 - 2 * x**28 - 2 * x**27
- x**24 + x**22 - 5 * x**21 + 3 * x**20 + 2 * x**19 - x**18 + 2 * x**17
+ x**16 - 2 * x**15 - 2 * x**14 + x**13 + x**12 + 2 * x**11 - 3 * x**10
+ 3 * x**9 + 2 * x**8 - 4 * x**6 - 2 * x**5 - 4 * x**4 + x**3
- x**2 - 1
)

# 计算 f(1)
result = f(1)
print(f"f(1) = {result}")
k=result
w = 32824596080441735190523997982799829197530203904568086251690542244969244071312854874746142497647579310192994177896837383837384405062036521829088599595750902976191010000575697075792720479387771945760107268598283406893094243282498381006464103080551366587157561686900620059394693185990788592220509670478190685244
n = 101780569941880865465631942473186578520071435753163950944409148606282910806650879176280021512435190682009749926285674412651435782567149633130455645157688819845748439487113261739503325065997835517112163014056297017874761742768297646567397770742374004940360061700285170103292360590891188591132054903101398360047
e = 65537
c = 77538275949900942020886849496162539665323546686749270705418870515132296087721218282974435210763225488530925782158331269160555819622551413648073293857866671421886753377970220838141826468831099375757481041897142546760492813343115244448184595644585857978116766199800311200819967057790401213156560742779242511746
d = (pow(2, k,n) - w)%n
p = gcd(d, n)
print(p)
q=n//p
phi=(p-1)*(q-1)
d=inverse(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))

baby_factor_revenge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import *
def create():
pl = []
for i in range(3):
pl.append(getPrime(1024))
return sorted(pl)
pl = create()
m=b'NSSCTF{xxxxxx}'
p,q,r = pl[0],pl[1],pl[2]
n = p*q*r
phi = (p-1)*(q-1)*(r-1)
e=65537
phi_2=(p-1)*(q-1)
n2=p*q
c=pow(bytes_to_long(m),e,n2)
print(f'n={n}')
print(f'phi={phi}')
print(f'c={c}')
"""
n=3191868707489083296976422171754481125088448532695639929013026951283334085716937496519972309690132954050242378974370025245594553866043111294840209514577676946872746793700126873931085112786381515154186105142460622301297252278473097650013016482539838576476763183025029834004241446095147665598581368214114851984460699747964946764645986828307675081596907634022110868102739948513844625534865764252668312850364286204872187001344218083941399088833989233474318289529103178632284291007694811574023047207470113594082533713524606268388742119103653587354956091145288566437795469230667897089543048576812362251576281067933183713438502813206542834734983616378764909202774603304124497453696792428111112644362307853143219890039129054302905340695668256116233515323529918746264727874817221051242387145263342018617858562987223211598238069486447049955021864781104312134816578626968386395835285074116149472750100154961405785440009296096563521430833
phi=3191868707489083296976422171754481125088448532695639929013026951283334085716937496519972309690132954050242378974370025245594553866043111294840209514577676946872746793700126873931085112786381515154186105142460622301297252278473097650013016482539838576476763183025029834004241446095147665598581368214114851984394758254181484105857103844940487787404078873566779953101987404891507588290232992132681729619718279684673827347612899406697514777723904351697638562060304399923174376216080338949397741477013367831377040866937433520175862575061413321076151761545984886547872427147498175814451096795344136954743868643889768901204954902708679102384061694877757565486240670882343628571424084461972849147495569088820011108794930593172573959423278140327579049114196086428504291102619820322231225943837444001821535593671764186251713714593498207219093585758479440828038119079608764008747539277397742897542501803218788455452391287578171880267200
c=8847973599594272436100870059187158819529199340583461915617467299706215012295598155778224026186157290320191983062022702191439286020733625396165573681688842631368993650799220713225485752608650482408353598320160571916055498330875851476520668973214124194890108144336715482373743731578734960096351460142579903010557821654345995923836938260379746304222820835040419844947019844885128550552066290798665884099701340641403329066058638137944934073185448687990744852400616823426082588916251127609191094346267837812018236673478691437630461425526779014305216914035039981685211625653600564431704400207095883904994772993227506462664
"""

一开始以为要根据phi和phi_2的关系分解n之类的,后来发现自己想多了,直接已知phi和n分解n就行,也有现成的板子,也有具体的论文link.springer.com/content/pdf/10.1007/3-540-36492-7_25.pdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from math import gcd
from math import isqrt
from random import randrange


def factorize_multi_prime(N, phi):
"""
Recovers the prime factors from a modulus if Euler's totient is known.
This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize.
More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3)
:param N: the modulus
:param phi: Euler's totient, the order of the multiplicative group modulo N
:return: a tuple containing the prime factors
"""
prime_factors = set()
factors = [N]
while len(factors) > 0:
# Element to factorize.
N = factors[0]

w = randrange(2, N - 1)
i = 1
while phi % (2 ** i) == 0:
sqrt_1 = pow(w, phi // (2 ** i), N)
if sqrt_1 > 1 and sqrt_1 != N - 1:
# We can remove the element to factorize now, because we have a factorization.
factors = factors[1:]

p = gcd(N, sqrt_1 + 1)
q = N // p

if isprime(p):
prime_factors.add(p)
elif p > 1:
factors.append(p)

if isprime(q):
prime_factors.add(q)
elif q > 1:
factors.append(q)

# Continue in the outer loop
break

i += 1

return tuple(prime_factors)
n=3191868707489083296976422171754481125088448532695639929013026951283334085716937496519972309690132954050242378974370025245594553866043111294840209514577676946872746793700126873931085112786381515154186105142460622301297252278473097650013016482539838576476763183025029834004241446095147665598581368214114851984460699747964946764645986828307675081596907634022110868102739948513844625534865764252668312850364286204872187001344218083941399088833989233474318289529103178632284291007694811574023047207470113594082533713524606268388742119103653587354956091145288566437795469230667897089543048576812362251576281067933183713438502813206542834734983616378764909202774603304124497453696792428111112644362307853143219890039129054302905340695668256116233515323529918746264727874817221051242387145263342018617858562987223211598238069486447049955021864781104312134816578626968386395835285074116149472750100154961405785440009296096563521430833
phi=3191868707489083296976422171754481125088448532695639929013026951283334085716937496519972309690132954050242378974370025245594553866043111294840209514577676946872746793700126873931085112786381515154186105142460622301297252278473097650013016482539838576476763183025029834004241446095147665598581368214114851984394758254181484105857103844940487787404078873566779953101987404891507588290232992132681729619718279684673827347612899406697514777723904351697638562060304399923174376216080338949397741477013367831377040866937433520175862575061413321076151761545984886547872427147498175814451096795344136954743868643889768901204954902708679102384061694877757565486240670882343628571424084461972849147495569088820011108794930593172573959423278140327579049114196086428504291102619820322231225943837444001821535593671764186251713714593498207219093585758479440828038119079608764008747539277397742897542501803218788455452391287578171880267200
print(factorize_multi_prime(n, phi))
p=177161320761695019215027450645114399072824136106796362891135280161503389503472113661790284346462113619617781651103105272149164401936630771895089936212673886987337552041566541830687513838748962966300768220005116250783079381135938459491010257996349274618491301060545101347741119007695583141027530048807773438431
q=118589237846929157177145636173700007714734296636618078863121028787719233856255349991676793277685489964300857832756581934799294586957137083742162225794737817065789645999587706703620635609191140301627049542092790079764008202073952667787393392675044942337058473033104592846222792727822005560480411401441075365471
r=151925555068309740027629873616844956416777676942104988548600500604734980705751500202455811525437316981852933269865712140204105818819734994452674160925578679385681053244060180042799265901275164392807664922780095166647350519792074240010137576702747299629682862274167454415537848662371715182873269954851056702833
phi_2=(q-1)*(r-1)
n2=q*r
d=inverse(e,phi_2)
c=8847973599594272436100870059187158819529199340583461915617467299706215012295598155778224026186157290320191983062022702191439286020733625396165573681688842631368993650799220713225485752608650482408353598320160571916055498330875851476520668973214124194890108144336715482373743731578734960096351460142579903010557821654345995923836938260379746304222820835040419844947019844885128550552066290798665884099701340641403329066058638137944934073185448687990744852400616823426082588916251127609191094346267837812018236673478691437630461425526779014305216914035039981685211625653600564431704400207095883904994772993227506462664
m=pow(c,d,n2)
print(long_to_bytes(m))

baby_lattice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from Crypto.Util.number import *
from Crypto.Cipher import AES
import os
from Crypto.Util.Padding import pad
from secret import flag
miku = 30
p = getPrime(512)
key = getPrime(512)
while key> p:
key= getPrime(512)
ts = []
gs = []
zs = []
for i in range(miku):
t = getPrime(512)
z = getPrime(400)
g= (t * key + z) % p
ts.append(t)
gs.append(g)
zs.append(z)
print(f'p = {p}')
print(f'ts = {ts}')
print(f'gs = {gs}')
iv= os.urandom(16)
cipher = AES.new(str(key).encode()[:16], AES.MODE_CBC,iv)
ciphertext=cipher.encrypt(pad(flag.encode(),16))
print(f'iv={iv}')
print(f'ciphertext={ciphertext}')

从题目代码不难看出是一个LHNP问题。

OQX2DC.png

我们可以据此构造矩阵M。
$$
\left[
\begin{matrix}
p & & & & & \
& p & & \
& &\ddots & & & \
& & & p & & \
-r_1 & -r_2 &\cdots &-r_n & k/p \
c_1 & c_2 & \cdots & c_n& &k \
\end{matrix}
\right]
$$
满足以下等式

(k$_1$,k$_2$,……k$_t$,x,1)M=(e$_1$,e$_2$,…..e$_t$,kx/p,k),LLL求解即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Util.number import *

t=30
p = 13401991645840298882794100147034379521242237285821020793208518466205688272722127694554243298223159648613332253774886696888511245155898681828972316158766813
ts = [8016983781273189754281912962247057409930227455812224730112055674262101679986538896353333785641031178561641562965339977035588567181180100475283408488320671, 12980173980684618239567238092970002844391225790428809984588444288874980047043175328056782109973890659670718383856150425014293022930574469326618263083648099, 8109856702010014482292978050018141635784057812487351143916154508689142112615449144377702002382005662470835964315028619291602564624893518861557701327890923, 12785373226115694299429762427866573289359143336748874789256870948157808484043436344897926547699412946084053665605873366419653263394817308889578649556482317, 12293720016807713691819354075258380849321736691923473670291035750221768289875347194928451102365603432383881559318603460687890903510706219895796459019974867, 9784378896444105030039569921777285228994264456281120536753266782980679466146906618674672118057906497814953677764528302638725540882074537262487534252076829, 9241433814815706758885649801540944918822400007457713603674159882791199750057709773097552334465041959969676782253637817171507122904345522225398825682237481, 11204803848333722110323297716136514262820561394355433234423667799557561253910421337700868735544193790444406938869863716247161888020220901893711513603634809, 10851090251796215969502640347727949807230163009657915435491546953253351810608099195268759626721620529756828379004467476267712531905975334082089231769707617, 11250957460128461102060212243723539805901629603092001540925013383541943835129096257407578679799378517176957440298695788786794500447140718667332595080944869, 12248623923069220370917375593286718711586079377902376988707257328512455851210970182518826733646869485671374318338949112466814956514662420760908691130244383, 11061068271412202445428992286301637014530049371871820612053163253748795430394720967354122057185625710764847486790478210908967065668096047462000900877243843, 9250800791153158078642768324800520716511537203538708124830844957330029236789799844775267058446261708862442981956837389747149720449997356553753692631237873, 11442112467994330302413453979716258058149104607244851803491048585747359474970005873336772224480265499136742622823880716879860377641238675210553131052206691, 8851268226889934481971979527547782930762103134830344221114784617526682434893736517219781937490279514229768881864475696389373739501629994242420024622585309, 8761826274329402585517262093482651333161640060627583337505498299736119877176278155436111156185319629046980645810012652601825582701466570339570478108791887, 8173260008522260126563915135008278248111293487661172115633899079869720932758788675224579864948752039769531398938248083971071345978173279466336354696742377, 11733325877716881936637372036969125985631514189799569847189115606745019694984456424617859168884541552882900918661071180298079869943357668081866511603361429, 12798678249651545625305346509566263707129030745621625744465668772298872710674031103310015594375483838020916596533864897632924958154707810583510669376046159, 11972367565183102195894957634073708898746516169055154830786380821612631063771935949099855541345280195465211676841845799521135332692746439801114025346776451, 8309485355838062558333744941897142201736283502970173073711189070760311131678107029730686549988329677109870570827466668034034377094834508445549924223585219, 10037957030668927878463105058548635761147918169468443696251870837018029994579358415317101911755591591785037623566701920710453008930531891302329922308475079, 13221078857886779075714191159549244640144219704164657103905516889650093241197471185563906205007376146027157620524696025494715411571586859030421582641250071, 13377141034964464295846379646837504968557246139611266461228568513844912255762222441387410898249170108735540582627742796017922462329606088337301365183628591, 11503417590216916228951909788782481610038959664264972733435373475346403291387209063270057139621628854733942831548624992555175497319058962145185736395531609, 10682562966818807073688884352394574841623385668134186058213080078637580526582062737913378756835873195913042020318042792997704842570481165538229628253983417, 7009494733984067792833862756223517770477471938386639921019003601598472840183655333614008677846799784155444425042016748876974547683111073376705004070094301, 9396274922380984183217450286560296708001013262936289587249206096013034374236192395477584831821730898646879768741299571262843654547918064041618890696711333, 9055143657462834722016836241561857041386247088507191351272758917384350750091500866289528933248085632291073921554368989805281660196853938630560350667255913, 7075881589550115729079726581415060529537262743216265811601339312252250745864621882784185460812341989475906020671174894015501378625757286896275136526488817]
gs = [3547025130757031371763547817278671805806523773597386380426228204353325314755125874825372064344551510783942287325061869515563511720377069479838665918916338, 561524185998066303459395863084068415723518371857539287162474295289737845979144864495515229777991463363132381517905379393086271602757286846999926034367409, 10630918988200018501478600883655233518093875635494077893436132190015060760951001030031068630865667129447250982542911493607849695255758299063471724885107320, 5385738167688714294394456876987750423263279740302210790063861475593679005286633965917637168163655774852001750955925563171806165861440634515967640179944804, 3686451063569312252337028014973428925521749963152262622523483348285262144703447272544972123815729823760936936761643322992469583780002855185407873398768127, 9596580956215126253893458055745193704575088913515678341231900675542245449333964660007025564677263334281046226112471415925784249910282102204627251580303047, 9656829597739031272294632966205884640125918053307645634673206826103547310810254891833432384622548154588598670746803614688469837172848481449498079690935715, 9907308304392368929600091658386459655450451232070442677496713774343506026327224070703486188335961098033888098971263207077722473044862118000082007110037557, 7839372385123283975949639433665292734490760458360682832497005213559939527031767909811695257768341209806346811519315554587887588294359891829457980910373676, 9524560447616291402016995361580593070951296833074538783490159546001656765257005901587161833656370873513309819850104060230660386406669378214335512722509152, 8734422874517209772760818316188000967216535009508164549745674472106165337990045713973843427581730460676070294620298664038968581128044873585552989614725336, 5148158222052082942951739997892280954937954769195857112271289335776175568625514426629773392655353554820374445881301175856523121361252868192790918069469104, 3405639365216597742633558534342314393231966921971024333387009357007031255109911181571542920889177048552084631482291912851876735480121959418518626599223928, 6965895908963098896413697893751255263053889382630643791713636829201586125658579731479485123904224727756791164618191156426250811133029277086293720268527300, 515472047175628755463279789359658211455570096067652817360508027869002916852457796014115363850477155232728049656195126940493402028508630979737222916876246, 8377848726362282033165443045774756072489017398005262818165334796393061408947900148462399707261050565348807577258621241416711089587307194346694505937252864, 1178755053483981880338850194698011124968424379914871101461970724324613752209283539401502897388962321646518511682063263530792638817282211333222820982688221, 6409725586399153562174435158247599193499008381130383743433623949976530392240171542527657077771723107664747118903213393154893390715457247849808357209465942, 3372824803484968486680937546271819996332625362891283809637871759604598252172343794474197823370030403360262989580844260103083478034905726890611202238641340, 13221067729455004299677399984872603663881675510140157358091630484387026309376774076498558628883879446483977202290444900329681753187886973457338777404374837, 7168388056726802823482632673894477305062116631923141017136239676696007696629606782541016490173953868270727600022309320772114799519383514048456314407549126, 5250230933448962245502125593869313477032913928941516938273943408457441209365441112912617832856547549404891414953525445963675011329667621804152746371657313, 8511291855606246692070730459514263912089592580342504124890734122750181111943376656479213361961009582891618556261302703133404839204999651359329176948170842, 10576966024912004586600985705328475294820172279541596349092328002861342696932964481093301707680584309062968518297314914578723605267596141569538103299931592, 12610576251820483830699440118009518195547953924641848179631259695652398482759919292823264035055444639679877606276670927735340951916197191958922906156370663, 3742260845065949575192054445757226288737527960324254459850715703182879384214273141678432129201712761002566924178045796602250837169613100836509080462118064, 11563799338655584285772430060426469486983276581413105960901201146319641194721216394735314795999096052047566733050321685673448559752053334666493545565267458, 2135904971793751083168704063674429207856744601756475004904460101727999030934815461118290836502605293753384609825541213034656253854812143724421464450937515, 3115138049292154301818359336614981367419382594686950083225042221335435796679806070685800479754927915293066789893346628151325862299622031407323031470432866, 11834987428374239733081967249175125232293539826462896997963240557834259212701171232384194311849363016441847536816726226234955703291712817155658535826680986]
# Calculate A & B
p = p
rs = ts
cs = gs
t = 30
kbits = 400
K = 2 ** kbits
iv=b'\x88\x0c\x7f\x92\xd7\xb7\xaf4\xe4\xfb\xd1_\xab\xff)\xb8'
ciphertext=b'\x94\x198\xd6\xa2mK\x00\x06\x7f\xad\xa0M\xf7\xadV;EO$\xee\xcdB0)\xfb!&8%,M'
P = identity_matrix(t) * p
print(P)
RC = matrix([[-1, 0], [0, 1]]) * matrix([rs, cs])
print(RC)
KP = matrix([[K / p, 0], [0, K]])
print(KP)
M = block_matrix([[P, 0], [RC, KP]], subdivide=False)
print(M)
shortest_vector = M.LLL()
key = shortest_vector[1, -2] / K * p % p
print(key)
key_bytes = str(key).encode()[:16] # 截取或填充为 16 字节

# 创建 AES 解密器
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)

# 解密并去除填充
try:
decrypted = unpad(cipher.decrypt(ciphertext), 16) # 解密并去除填充
flag = decrypted.decode() # 解码为字符串

print("Recovered flag:", flag)
except ValueError as e:
print("Incorrect decryption:", e)

RSA_and_DSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from random import getrandbits, randint
from secrets import randbelow
from Crypto.Util.number import*
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
import hashlib
import random
import gmpy2
ink=getPrime(20)
p1= getPrime(512)
q1= getPrime(512)
N = p1* q1
phi = (p1-1) * (q1-1)
while True:
d1= getRandomNBitInteger(200)
if GCD(d1, phi) == 1:
e = inverse(d1, phi)
break
c_ink = pow(ink, e, N)
print(f'c_ink=',c_ink)
print(f'e=',e)
print(f'N=',N)

k= getPrime(64)
q = getPrime(160)
def sign(msg, pub, pri, k):
(p,q,g,y) = pub
x = pri
r = int(pow(g, k, p) % q)
h = int(hashlib.sha256(msg).digest().hex(),16)
s = int((h + x * r) * gmpy2.invert(k, q) % q)
return (r, s)

while True:
temp = q * getrandbits(864)
if isPrime(temp + 1):
p = temp + 1
break
assert p % q == 1
h = randint(1, p - 1)
g = pow(h, (p - 1) // q, p)
y = pow(g, k, p)
pub = (p,q,g,y)
pri = random.randint(1, q-1)
print(f"(r1,s1)=",sign(b'GHCTF-2025', pub, pri, k))
print(f"(r2,s2)=",sign(b'GHCTF-2025', pub, pri, k+ink))
print(f"{g= }")
print(f"{q= }")
print(f"{p= }")
print(f"{y= }")
key = hashlib.sha1(str(pri).encode()).digest()[:16]
cipher = AES.new(key, AES.MODE_ECB)
flag="NSSCTF{xxxxxxxxx}"
ciphertext = cipher.encrypt(pad(flag.encode(), 16))
print(f"{ciphertext = }")
'''
c_ink= 84329531596553394336538987023357227935440127545924398750500007122949822951975451942488164538560925222694222413022235832336439700420379598454619959178424907616592885325169668838139433265501326382467741883799799897305247164532663683724926267222341485376684034461780316163663624769479766276645610470850267093664
e= 100797590979191597676081881632112443200677974501832055481332601002844223186483558337099380805371010917502984674789369037985572270571944684404114475915036053451756526659905789324413633016308331745100752282051937597697581233757669107763643041665187533373053952694612521031477624363476981177214961821456672635823
N= 133020919573254586736009662994351483197630110046444622015176359062686053521475990861985101412597512894313048001198942449066636145265799205815566892581351543233960812384316942438814742826123037762680960898927252792974233266551853930274479435403549161383103059746381782668941421906340168652870371226382805032027
(r1,s1)= (105538622724986198173818280402723234123231812870, 165871242333491991006684781121637801537623792920)
(r2,s2)= (895673018852361693797535983771888430717799939767, 511956887428148277909616673338517730698888202223)
g= 97444164915108666817264719918456841236668149777715575246719562319277238318814584882880249446488655758781498681349330709135670188875982069778879957837454582916193915374305422049064769688749957611500682447936476425649642359105731049262259786188565867271216015835626264543593116387612078934710741467063982007499
q= 974306102330898613562307019447798934376234044213
p= 113996945917185663452903189185812083054654586038361814576057637684218572059191009152754335053396974825607186512631652893899380922217026759410880236546966561476761050482902589270845489570126254333374605973087540746242818447451510386137109253463070487353845675998098620056687507969012229115435439218407426962991
y= 8015503667614219250943034151839311927430676423719991507127801373333532219335171760992873121586820712328636972152697436159934583810723294897449200937370031784164230148453787378834760102389031574149857480339843366568164403131143385627621208571673677878768568991050568882099039880976450795530322753270408770484
ciphertext = b'\xb0\ra\x9c\xeb9y\xd5k\xfde\xdfJ\xba\n\xce^u\xae\x81J8\xe4\x8da\xdf;H@WV5'
'''

不难看出是一个RSA和DSA的拼接,前半部分是一个RSA的维纳攻击,用正常连分数展开去打就可以,后半部分是一个DSA签名的线性K问题,具体的推导过程可以参考另一篇博客DSA签名 | 浮白载笔,这里就不过多赘述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from Cryptodome.Cipher import AES
from Cryptodome.Util.number import *
import hashlib
import gmpy2

c= 84329531596553394336538987023357227935440127545924398750500007122949822951975451942488164538560925222694222413022235832336439700420379598454619959178424907616592885325169668838139433265501326382467741883799799897305247164532663683724926267222341485376684034461780316163663624769479766276645610470850267093664
e= 100797590979191597676081881632112443200677974501832055481332601002844223186483558337099380805371010917502984674789369037985572270571944684404114475915036053451756526659905789324413633016308331745100752282051937597697581233757669107763643041665187533373053952694612521031477624363476981177214961821456672635823
n= 133020919573254586736009662994351483197630110046444622015176359062686053521475990861985101412597512894313048001198942449066636145265799205815566892581351543233960812384316942438814742826123037762680960898927252792974233266551853930274479435403549161383103059746381782668941421906340168652870371226382805032027
(r1,s1)= (105538622724986198173818280402723234123231812870, 165871242333491991006684781121637801537623792920)
(r2,s2)= (895673018852361693797535983771888430717799939767, 511956887428148277909616673338517730698888202223)
g= 97444164915108666817264719918456841236668149777715575246719562319277238318814584882880249446488655758781498681349330709135670188875982069778879957837454582916193915374305422049064769688749957611500682447936476425649642359105731049262259786188565867271216015835626264543593116387612078934710741467063982007499
q= 974306102330898613562307019447798934376234044213
p= 113996945917185663452903189185812083054654586038361814576057637684218572059191009152754335053396974825607186512631652893899380922217026759410880236546966561476761050482902589270845489570126254333374605973087540746242818447451510386137109253463070487353845675998098620056687507969012229115435439218407426962991
y= 8015503667614219250943034151839311927430676423719991507127801373333532219335171760992873121586820712328636972152697436159934583810723294897449200937370031784164230148453787378834760102389031574149857480339843366568164403131143385627621208571673677878768568991050568882099039880976450795530322753270408770484
ciphertext = b'\xb0\ra\x9c\xeb9y\xd5k\xfde\xdfJ\xba\n\xce^u\xae\x81J8\xe4\x8da\xdf;H@WV5'
msg = b'GHCTF-2025'
import gmpy2
def continuedFra(x, y):
"""计算连分数
:param x: 分子
:param y: 分母
:return: 连分数列表
"""
cf = []
while y:
cf.append(x // y)
x, y = y, x % y
return cf


def gradualFra(cf):
"""计算传入列表最后的渐进分数
:param cf: 连分数列表
:return: 该列表最后的渐近分数
"""
numerator = 0
denominator = 1
for x in cf[::-1]:
# 这里的渐进分数分子分母要分开
numerator, denominator = denominator, x * denominator + numerator
return numerator, denominator


def solve_pq(a, b, c):
"""使用韦达定理解出pq,x^2−(p+q)∗x+pq=0
:param a:x^2的系数
:param b:x的系数
:param c:pq
:return:p,q
"""
par = gmpy2.isqrt(b * b - 4 * a * c)
return (-b + par) // (2 * a), (-b - par) // (2 * a)


def getGradualFra(cf):
"""计算列表所有的渐近分数
:param cf: 连分数列表
:return: 该列表所有的渐近分数
"""
gf = []
for i in range(1, len(cf) + 1):
gf.append(gradualFra(cf[:i]))
return gf


def wienerAttack(e, n):
"""
:param e:
:param n:
:return: 私钥d
"""
cf = continuedFra(e, n)
gf = getGradualFra(cf)
for d, k in gf:
if k == 0: continue
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return d
d = wienerAttack(e, n)
print(d)
ink = pow(c, d, n)
print(ink)

h = int(hashlib.sha256(b'GHCTF-2025').digest().hex(),16)
k = (h*r2-h*r1+ink*s2*r1)*pow(s1*r2-s2*r1, -1, q) % q
pri = (k*s1-h) * pow(r1, -1, q) % q
key = hashlib.sha1(str(pri).encode()).digest()[:16]
print(key)
cipher = AES.new(key, AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
k= ((h*(r2 - r1) + ink*r1*s2)*gmpy2.invert((r2*s1-1*r1*s2),q)) % q

m1 = (k*s1 - h)*gmpy2.invert(r1,q) % q
print(hashlib.sha1(str(m1).encode()).digest()[:16])

MIMT_RSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Crypto.Util.number import *
from hashlib import md5
from secret import KEY, flag


assert int(KEY).bit_length() == 36
assert not isPrime(KEY)

p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001

ck = pow(KEY, e, n)


assert flag == b'NSSCTF{' + md5(str(KEY).encode()).hexdigest().encode() + b'}'

print(f"{n = }")
print(f"{e = }")
print(f"{ck = }")

'''
n = 26563847822899403123579768059987758748518109506340688366937229057385768563897579939399589878779201509595131302887212371556759550226965583832707699167542469352676806103999861576255689028708092007726895892953065618536676788020023461249303717579266840903337614272894749021562443472322941868357046500507962652585875038973455411548683247853955371839865042918531636085668780924020410159272977805762814306445393524647460775620243065858710021030314398928537847762167177417552351157872682037902372485985979513934517709478252552309280270916202653365726591219198063597536812483568301622917160509027075508471349507817295226801011
e = 65537
ck = 8371316287078036479056771367631991220353236851470185127168826270131149168993253524332451231708758763231051593801540258044681874144589595532078353953294719353350061853623495168005196486200144643168051115479293775329183635187974365652867387949378467702492757863040766745765841802577850659614528558282832995416523310220159445712674390202765601817050315773584214422244200409445854102170875265289152628311393710624256106528871400593480435083264403949059237446948467480548680533474642869718029551240453665446328781616706968352290100705279838871524562305806920722372815812982124238074246044446213460443693473663239594932076

'''

一个很基本的RSA加密系统,并且给出了

1
assert int(KEY).bit_length() == 36

说明key的大小不大,结合题目MIMT(其实应该是MITM)也就是中间相遇攻击,说明爆破是可行的。并且KEY并不是一个素数,所以我们可以通过爆破其因子来间接得到KEY.

稍微推导一下

KEY$^e$≡ck(mod n)

(a∗b)$^e$≡ck (modn)

b$^e$≡ck*a$^{−e}$(modn)

所以分别爆破a和b即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from tqdm import trange


n = 26563847822899403123579768059987758748518109506340688366937229057385768563897579939399589878779201509595131302887212371556759550226965583832707699167542469352676806103999861576255689028708092007726895892953065618536676788020023461249303717579266840903337614272894749021562443472322941868357046500507962652585875038973455411548683247853955371839865042918531636085668780924020410159272977805762814306445393524647460775620243065858710021030314398928537847762167177417552351157872682037902372485985979513934517709478252552309280270916202653365726591219198063597536812483568301622917160509027075508471349507817295226801011
e = 65537
ck = 8371316287078036479056771367631991220353236851470185127168826270131149168993253524332451231708758763231051593801540258044681874144589595532078353953294719353350061853623495168005196486200144643168051115479293775329183635187974365652867387949378467702492757863040766745765841802577850659614528558282832995416523310220159445712674390202765601817050315773584214422244200409445854102170875265289152628311393710624256106528871400593480435083264403949059237446948467480548680533474642869718029551240453665446328781616706968352290100705279838871524562305806920722372815812982124238074246044446213460443693473663239594932076

fa = {}
fb = {}
for a in trange(1, 2**20):
fa[ck * pow(a, -65537, n) % n] = a
for b in trange(1, 2**20):
fb[pow(b, 65537, n)] = b
results = set(fa.keys()).intersection(set(fb.keys()))
for result in results:
a = fa[result]
b = fb[result]
key = a*b
print(k)
break

EZ_Fermat_bag_PRO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from Crypto.Util.number import getPrime, bytes_to_long
from random import *
from secret import f, flag

assert len(flag) == 88
assert flag.startswith(b'NSSCTF{')
assert flag.endswith(b'}')

p = getPrime(512)
q = getPrime(512)
n = p*q

P.<x,y> = ZZ[]
f = P(str(f))

w = pow(2,f(p,q),n)
assert all(chr(i) in ''.join(list(set(str(p)))) for i in flag[7:-1:])
c = bytes_to_long(flag) % p



print(f'{n = }\n')
print(f'{f = }\n')
print(f'{w = }\n')
print(f'{c = }\n')
n = 95656952327201449381426394713246214670537600365883923624876350719801926817916514429721785287844335184715049179879891389941974481490433975689601829920289485889138252888029716516069912637121531561601839948367426922036690701168975937162280451323099126372019216020898338909808577022618554997063496690156977790629
e = 65537
c = 32384071331939239285992149489589967884022349189352515487950255250160126611084915524664364190130039873461090810189570222748422757594726643684332100753373557666031160718150203596579825955216919802911458293840557069152132506518827761626306871971480050052005979083878379439210757328323337697175682026549870910934
f = x^31 - x^30*y - 2*x^29*y^2 + 7*x^28*y^3 + 2*x^27*y^4 - 4*x^24*y^7 + 3*x^23*y^8 - x^20*y^11 - 4*x^19*y^12 + x^18*y^13 - 5*x^17*y^14 - 4*x^16*y^15 - x^15*y^16 + x^14*y^17 + x^13*y^18 + x^12*y^19 - 2*x^11*y^20 - 3*x^9*y^22 + 5*x^7*y^24 + x^6*y^25 + 6*x^4*y^27 + x^3*y^28 + 2*x*y^30 + y^31 - 2*x^30 - 3*x^29*y + 2*x^28*y^2 + 2*x^27*y^3 - x^26*y^4 - x^25*y^5 - 2*x^24*y^6 - 3*x^23*y^7 - 3*x^22*y^8 - 3*x^20*y^10 - 4*x^19*y^11 + 2*x^18*y^12 + x^15*y^15 - x^14*y^16 - 2*x^12*y^18 - 3*x^11*y^19 - x^10*y^20 + x^9*y^21 + 2*x^8*y^22 + x^7*y^23 + x^5*y^25 - x^4*y^26 - 2*x^3*y^27 - 2*x^2*y^28 - y^30 - 2*x^29 - x^28*y + 3*x^26*y^3 - x^25*y^4 - 2*x^24*y^5 + x^23*y^6 - x^22*y^7 - x^20*y^9 + 2*x^19*y^10 + 2*x^18*y^11 + x^16*y^13 + x^15*y^14 + x^14*y^15 + x^13*y^16 + x^12*y^17 + 5*x^11*y^18 - x^9*y^20 - 2*x^8*y^21 - 5*x^7*y^22 - 2*x^6*y^23 + 3*x^5*y^24 - 5*x^3*y^26 - x^2*y^27 + 2*x*y^28 - y^29 + 3*x^28 + 3*x^27*y - 2*x^26*y^2 + x^25*y^3 + 2*x^24*y^4 - x^23*y^5 - 2*x^22*y^6 - 3*x^20*y^8 - 3*x^19*y^9 + 4*x^17*y^11 - x^16*y^12 - 3*x^15*y^13 - 2*x^14*y^14 + x^13*y^15 + 2*x^12*y^16 - 2*x^11*y^17 + x^10*y^18 - 2*x^9*y^19 + x^8*y^20 - 2*x^7*y^21 - x^6*y^22 + x^5*y^23 - x^4*y^24 + x^3*y^25 + x^2*y^26 - x*y^27 - y^28 + x^27 + x^26*y - 2*x^24*y^3 + x^23*y^4 - 3*x^22*y^5 - 2*x^21*y^6 - 2*x^20*y^7 - 5*x^19*y^8 + 2*x^18*y^9 - 5*x^17*y^10 + x^16*y^11 - 3*x^15*y^12 - 4*x^14*y^13 - x^13*y^14 + x^12*y^15 + 3*x^11*y^16 + 2*x^10*y^17 - 4*x^9*y^18 - 2*x^6*y^21 + x^5*y^22 + 4*x^3*y^24 + 2*x^2*y^25 + 2*x*y^26 - 2*y^27 + x^25*y + x^24*y^2 + x^23*y^3 + 5*x^22*y^4 + x^20*y^6 - 3*x^19*y^7 + x^18*y^8 - x^17*y^9 + 2*x^15*y^11 - x^14*y^12 + 2*x^13*y^13 - x^12*y^14 + 4*x^11*y^15 - x^10*y^16 - 2*x^6*y^20 - x^5*y^21 + 3*x^3*y^23 + x^2*y^24 - 3*x*y^25 - 3*y^26 + 3*x^25 - 2*x^23*y^2 - x^21*y^4 + x^17*y^8 + 2*x^16*y^9 - x^15*y^10 - 2*x^14*y^11 - x^13*y^12 + 2*x^12*y^13 - 2*x^11*y^14 - x^9*y^16 - x^8*y^17 - x^6*y^19 - x^5*y^20 + x^4*y^21 + x^3*y^22 + 5*x*y^24 - 2*y^25 - x^24 + 2*x^23*y + x^22*y^2 - x^21*y^3 - x^19*y^5 + x^18*y^6 - x^17*y^7 + 2*x^16*y^8 - 4*x^15*y^9 - x^14*y^10 - x^13*y^11 - x^12*y^12 + 4*x^10*y^14 + 2*x^9*y^15 - x^8*y^16 - 2*x^7*y^17 - 2*x^6*y^18 + 4*x^5*y^19 + x^4*y^20 + 2*x^2*y^22 - 5*x*y^23 - y^24 + x^23 - x^22*y + 2*x^21*y^2 - x^20*y^3 - x^18*y^5 - x^17*y^6 - 5*x^15*y^8 + x^14*y^9 - 3*x^13*y^10 + 3*x^12*y^11 + 2*x^11*y^12 - 2*x^10*y^13 - 2*x^9*y^14 - x^8*y^15 + 2*x^7*y^16 - 2*x^6*y^17 - 4*x^5*y^18 - 5*x^3*y^20 - x^2*y^21 - x*y^22 - 4*y^23 - x^22 + 2*x^21*y - 2*x^20*y^2 - 2*x^19*y^3 - 3*x^17*y^5 - x^16*y^6 - x^15*y^7 + 4*x^13*y^9 + 2*x^12*y^10 + 3*x^11*y^11 + 2*x^10*y^12 - x^9*y^13 - x^7*y^15 + 2*x^6*y^16 + x^3*y^19 + 2*x^2*y^20 + 2*x*y^21 + 3*y^22 - 3*x^21 - x^20*y - x^19*y^2 + 2*x^17*y^4 - x^16*y^5 - x^15*y^6 + x^14*y^7 - 5*x^12*y^9 - 2*x^11*y^10 + x^10*y^11 + x^6*y^15 + x^5*y^16 + x^4*y^17 - 3*x^2*y^19 - 2*x*y^20 - 2*y^21 + x^20 + 2*x^19*y - 2*x^17*y^3 + 2*x^16*y^4 - 3*x^15*y^5 + 4*x^14*y^6 + 2*x^13*y^7 - x^12*y^8 - 2*x^11*y^9 + x^10*y^10 + 6*x^9*y^11 + x^8*y^12 + x^7*y^13 + 2*x^5*y^15 + 4*x^4*y^16 + x^3*y^17 - x^2*y^18 + 3*x*y^19 - x^17*y^2 + 2*x^16*y^3 + 3*x^14*y^5 - x^13*y^6 + 2*x^11*y^8 + x^10*y^9 + 3*x^9*y^10 - x^7*y^12 - x^6*y^13 + 3*x^5*y^14 - 4*x^4*y^15 + x^2*y^17 + 2*y^19 - x^18 - x^16*y^2 - 2*x^14*y^4 - 2*x^13*y^5 - 2*x^12*y^6 + 2*x^11*y^7 + 3*x^9*y^9 + 3*x^8*y^10 + x^6*y^12 - x^4*y^14 + 2*x^3*y^15 + 2*x^2*y^16 - 2*x*y^17 - x^17 - 4*x^16*y - 2*x^15*y^2 + 2*x^14*y^3 - x^13*y^4 + x^12*y^5 - 2*x^11*y^6 - 3*x^10*y^7 - x^9*y^8 - 5*x^8*y^9 + 2*x^7*y^10 + 2*x^6*y^11 - x^5*y^12 + x^4*y^13 - 3*x^2*y^15 + x*y^16 - 3*x^16 + x^15*y - 3*x^14*y^2 - x^13*y^3 - x^12*y^4 + 2*x^11*y^5 - x^10*y^6 + 5*x^8*y^8 + 3*x^7*y^9 + 3*x^6*y^10 + 2*x^5*y^11 + 4*x^4*y^12 + 2*x^3*y^13 + x^2*y^14 - 3*x*y^15 - x^15 + 3*x^14*y + x^13*y^2 - x^12*y^3 - 3*x^11*y^4 + x^10*y^5 - x^9*y^6 + 2*x^8*y^7 - x^7*y^8 + 4*x^5*y^10 - 2*x^4*y^11 + x^3*y^12 - x^14 + x^13*y + 2*x^12*y^2 + x^11*y^3 - 5*x^10*y^4 - x^9*y^5 - 3*x^8*y^6 - 2*x^7*y^7 + x^6*y^8 + 3*x^5*y^9 + x^4*y^10 + 2*x^3*y^11 - x^2*y^12 - 4*x*y^13 + 3*y^14 + x^12*y - 2*x^11*y^2 - x^9*y^4 - x^8*y^5 + 5*x^7*y^6 - 4*x^6*y^7 + 3*x^5*y^8 + 4*x^4*y^9 - 3*x^3*y^10 - x^2*y^11 - 2*x*y^12 - 3*y^13 + 3*x^12 + x^11*y + x^10*y^2 + x^9*y^3 + x^8*y^4 - x^6*y^6 - x^5*y^7 - 4*x^3*y^9 - x^2*y^10 - 3*x*y^11 - 2*y^12 + x^10*y + 5*x^9*y^2 + x^8*y^3 + 3*x^5*y^6 + x^4*y^7 + 2*x^3*y^8 - 4*x^2*y^9 + 2*x*y^10 + 3*y^11 - x^10 - 2*x^9*y - 2*x^7*y^3 - x^6*y^4 + x^5*y^5 + 3*x^4*y^6 - 2*x^2*y^8 - x*y^9 + 4*x^9 - 3*x^8*y - 3*x^6*y^3 + x^5*y^4 - x^4*y^5 - 2*x^3*y^6 - 2*x^2*y^7 + x*y^8 + 4*y^9 + 2*x^8 - x^7*y - 2*x^5*y^3 - 4*x^4*y^4 + 3*x^3*y^5 + 4*x^2*y^6 + 2*x*y^7 - 2*y^8 + 2*x^7 + 3*x^5*y^2 + 3*x^2*y^5 - x*y^6 - 4*x^6 + 6*x^3*y^3 + 2*x^2*y^4 - 2*x*y^5 - 3*y^6 + x^5 - 3*x^4*y + x^3*y^2 + x^2*y^3 - 2*x*y^4 + 2*x^4 - 2*x^3*y + 6*x^2*y^2 - 3*x*y^3 - 2*y^4 - 5*x^3 - 2*x^2*y - 2*x*y^2 + 3*y^3 + 2*x^2 - x*y + y^2 - 2*x + 2*y - 2
w = 12796020294902567574981427270787776254781813995526831579805652479456168245098217943847166109912113827479436654134179666391771173421469188197935460525521295192736123648410762964187396897298542198935971755852754544978564521188423737649175136194386664628304164316905741781089536713701674793641345344818309314224


这次的多项式中既有p也有q,所以我们要想办法消去一个。只要给原版的多项式乘上p$^{32}$,就可以消掉全部的q.

消去后的多项式如下。

1
n**31*p + 2*n**30*p**3 - n**30*p**2 - n**29*p**3 + n**28*p**7 - 2*n**28*p**6 + 2*n**28*p**5 - n**28*p**4 + 6*n**27*p**9 - 2*n**27*p**8 - n**27*p**7 - n**27*p**6 - 2*n**27*p**5 - n**26*p**10 - 5*n**26*p**9 + n**26*p**8 + 2*n**26*p**7 - 3*n**26*p**6 + n**25*p**13 + n**25*p**12 + n**25*p**10 + 2*n**25*p**9 - 3*n**25*p**8 - 2*n**25*p**7 + 5*n**24*p**15 + 3*n**24*p**13 - n**24*p**12 + 4*n**24*p**11 + n**24*p**10 + 5*n**24*p**9 - n**24*p**8 + n**23*p**16 - 2*n**23*p**15 + n**23*p**14 + 3*n**23*p**12 - 5*n**23*p**10 - 4*n**23*p**9 - 3*n**22*p**19 + 2*n**22*p**18 - 5*n**22*p**17 - n**22*p**16 + n**22*p**15 + n**22*p**13 + 2*n**22*p**12 - n**22*p**11 + 3*n**22*p**10 + n**21*p**20 - 2*n**21*p**19 - 2*n**21*p**18 - 2*n**21*p**17 - n**21*p**16 + n**21*p**15 - n**21*p**13 + 2*n**21*p**12 - 2*n**21*p**11 - 2*n**20*p**23 - n**20*p**22 - n**20*p**21 + n**20*p**20 - 2*n**20*p**18 - n**20*p**17 + n**20*p**16 - 5*n**20*p**15 + 2*n**20*p**14 - 2*n**20*p**13 + n**19*p**25 - 3*n**19*p**24 - 2*n**19*p**22 - n**19*p**19 + 4*n**19*p**18 + n**19*p**16 - 3*n**19*p**15 + 3*n**19*p**14 + 2*n**19*p**13 + n**18*p**27 - 2*n**18*p**26 + 5*n**18*p**25 + n**18*p**24 - 4*n**18*p**23 - 2*n**18*p**20 - 4*n**18*p**19 - n**18*p**16 + n**17*p**29 + n**17*p**27 - 2*n**17*p**26 + 2*n**17*p**25 - n**17*p**23 - 2*n**17*p**22 - 2*n**17*p**21 + n**17*p**19 + n**17*p**18 + n**17*p**17 - 2*n**17*p**16 - n**16*p**31 - n**16*p**30 + n**16*p**29 + 2*n**16*p**28 + 3*n**16*p**27 - n**16*p**26 - n**16*p**25 - n**16*p**24 + 2*n**16*p**23 + 2*n**16*p**22 + n**16*p**21 + 4*n**16*p**20 + 2*n**16*p**18 + n**16*p**17 - 4*n**15*p**33 + n**15*p**32 + n**15*p**31 + n**15*p**30 + n**15*p**29 + 4*n**15*p**28 + 2*n**15*p**26 - n**15*p**25 - n**15*p**24 + n**15*p**23 + 2*n**15*p**22 - 4*n**15*p**21 + 2*n**15*p**20 - 3*n**15*p**19 - 3*n**15*p**18 - 5*n**14*p**35 + n**14*p**33 - 2*n**14*p**32 - n**14*p**31 - n**14*p**30 - 2*n**14*p**29 + 4*n**14*p**28 - 2*n**14*p**27 + 3*n**14*p**23 - n**14*p**22 + n**14*p**20 + 3*n**14*p**18 + n**13*p**37 + n**13*p**35 - 3*n**13*p**34 - 4*n**13*p**33 + 2*n**13*p**32 + 2*n**13*p**31 - 2*n**13*p**29 - n**13*p**28 + n**13*p**26 - n**13*p**25 + n**13*p**23 + 2*n**13*p**22 - 4*n**13*p**20 - 3*n**13*p**19 - 4*n**12*p**39 + 2*n**12*p**38 - n**12*p**36 - 3*n**12*p**35 - n**12*p**34 - n**12*p**33 - n**12*p**32 + 2*n**12*p**31 + 2*n**12*p**30 + n**12*p**28 - n**12*p**27 + n**12*p**26 - n**12*p**25 + 4*n**12*p**24 + n**12*p**23 - n**12*p**22 - 2*n**12*p**21 - 2*n**12*p**20 - n**11*p**41 - 4*n**11*p**40 + 2*n**11*p**39 + 4*n**11*p**38 + n**11*p**37 + 2*n**11*p**36 - 2*n**11*p**35 - n**11*p**34 + 3*n**11*p**33 + 3*n**11*p**32 + n**11*p**31 + 6*n**11*p**30 + 2*n**11*p**27 + 2*n**11*p**26 - 2*n**11*p**25 + 2*n**11*p**24 - n**11*p**23 - 3*n**11*p**22 + 3*n**11*p**21 - 3*n**10*p**42 + 2*n**10*p**41 - 5*n**10*p**39 - n**10*p**37 - n**10*p**36 - 3*n**10*p**35 + 2*n**10*p**34 - 2*n**10*p**33 + n**10*p**32 + 3*n**10*p**31 + 3*n**10*p**30 + 2*n**10*p**29 + 3*n**10*p**28 + 4*n**10*p**27 + n**10*p**26 - 3*n**10*p**25 - n**10*p**24 + 2*n**10*p**23 - n**9*p**43 - 3*n**9*p**42 + 2*n**9*p**41 - n**9*p**40 + 2*n**9*p**39 - 4*n**9*p**38 + n**9*p**37 + 4*n**9*p**36 - 5*n**9*p**35 - 2*n**9*p**34 + n**9*p**33 + 3*n**9*p**32 - 5*n**9*p**31 + 3*n**9*p**30 + 3*n**9*p**28 + 4*n**9*p**27 - 4*n**9*p**26 - 4*n**9*p**25 - n**9*p**24 + 4*n**9*p**23 + 3*n**8*p**47 - 3*n**8*p**46 - 3*n**8*p**44 - 5*n**8*p**43 + n**8*p**42 + n**8*p**41 + 2*n**8*p**40 - 5*n**8*p**39 - n**8*p**36 + 2*n**8*p**35 - n**8*p**33 + 5*n**8*p**32 - n**8*p**31 + n**8*p**30 + 3*n**8*p**29 + 2*n**8*p**27 - 2*n**8*p**26 + n**8*p**25 - 2*n**8*p**24 - 4*n**7*p**49 - 3*n**7*p**48 - n**7*p**47 - 2*n**7*p**45 - 3*n**7*p**44 - n**7*p**42 - n**7*p**40 + n**7*p**39 + 2*n**7*p**38 + 2*n**7*p**36 - 3*n**7*p**35 + 2*n**7*p**33 - 2*n**7*p**32 - 4*n**7*p**31 - n**7*p**30 + n**7*p**29 - 2*n**7*p**27 + 2*n**7*p**26 - 2*n**6*p**50 + n**6*p**49 - 2*n**6*p**48 - 2*n**6*p**47 + n**6*p**46 + n**6*p**44 - n**6*p**43 - n**6*p**42 - n**6*p**41 + 4*n**6*p**40 - n**6*p**39 - 2*n**6*p**38 - 2*n**6*p**37 - n**6*p**36 - n**6*p**35 - 3*n**6*p**34 + 5*n**6*p**33 - n**6*p**32 + 3*n**6*p**31 + 3*n**6*p**30 - 2*n**6*p**29 + 4*n**6*p**28 - n**6*p**27 - 3*n**6*p**26 - n**5*p**52 - 2*n**5*p**51 - n**5*p**50 - 3*n**5*p**49 - n**5*p**46 - n**5*p**45 - 3*n**5*p**44 - n**5*p**43 - 3*n**5*p**42 + 3*n**5*p**41 - 2*n**5*p**40 + n**5*p**39 + 2*n**5*p**38 + n**5*p**37 - n**5*p**36 - n**5*p**35 + n**5*p**32 - n**5*p**31 + 3*n**5*p**30 + 3*n**5*p**29 - 2*n**5*p**28 + 2*n**4*p**55 - n**4*p**54 - n**4*p**53 + 2*n**4*p**52 + n**4*p**51 + 5*n**4*p**50 - n**4*p**49 + 2*n**4*p**45 + 2*n**4*p**44 - 2*n**4*p**42 - n**4*p**41 - n**4*p**40 - 3*n**4*p**39 - 5*n**4*p**38 - n**4*p**37 + n**4*p**36 - n**4*p**34 + n**4*p**33 - 4*n**4*p**32 + 2*n**4*p**30 - 2*n**4*p**29 - 2*n**4*p**28 + 7*n**3*p**57 + 2*n**3*p**56 + 3*n**3*p**55 + n**3*p**54 - 2*n**3*p**53 + n**3*p**52 - n**3*p**50 - n**3*p**49 - 2*n**3*p**48 - 2*n**3*p**46 + 2*n**3*p**45 + 2*n**3*p**43 - n**3*p**42 - n**3*p**41 + n**3*p**40 + n**3*p**38 + n**3*p**37 - 2*n**3*p**36 - 3*n**3*p**35 - 2*n**3*p**34 + 6*n**3*p**32 + n**3*p**31 - 3*n**3*p**30 + 3*n**3*p**29 - 2*n**2*p**59 + 2*n**2*p**58 - 2*n**2*p**56 + n**2*p**54 - 2*n**2*p**53 + n**2*p**52 + 2*n**2*p**51 - 2*n**2*p**50 - n**2*p**49 - n**2*p**47 - n**2*p**46 - 2*n**2*p**45 - 3*n**2*p**44 + n**2*p**43 + 2*n**2*p**42 - 2*n**2*p**41 + n**2*p**40 + 5*n**2*p**39 + 3*n**2*p**35 + n**2*p**33 + 6*n**2*p**32 - 2*n**2*p**31 + n**2*p**30 - n*p**61 - 3*n*p**60 - n*p**59 + 3*n*p**58 + n*p**57 + n*p**56 + 2*n*p**54 - n*p**53 + 2*n*p**52 - n*p**51 + 2*n*p**50 - 4*n*p**47 + n*p**46 + 3*n*p**45 + n*p**44 + n*p**43 + n*p**42 + n*p**41 - 2*n*p**40 - 3*n*p**39 - n*p**38 - 3*n*p**35 - 2*n*p**34 - 2*n*p**33 - n*p**32 + 2*n*p**31 + p**63 - 2*p**62 - 2*p**61 + 3*p**60 + p**59 + 3*p**57 - p**56 + p**55 - p**54 - 3*p**53 + p**52 - p**50 - p**49 - 3*p**48 - p**47 - p**46 + 3*p**44 - p**42 + 4*p**41 + 2*p**40 + 2*p**39 - 4*p**38 + p**37 + 2*p**36 - 5*p**35 + 2*p**34 - 2*p**33 - 2*p**32

但这里的推导与EZ_Fermat有所不同。消去q后,我们有2$^{f(p)*p^{32}}$$\equiv$w$^{p^{32}}$mod(n),由费马小定理可以推得2$^{f(p)p^{32}}$$\equiv$w mod(p).需要将指数换元为(x-1)的形式才能应用费马小定理进行化简。比如2$^{pn^{32}}$化为2$^{(p-1)n^{32}}$此时等式右边就要乘一个2$^{-1n^{32}}$,以此类推即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
N = 95656952327201449381426394713246214670537600365883923624876350719801926817916514429721785287844335184715049179879891389941974481490433975689601829920289485889138252888029716516069912637121531561601839948367426922036690701168975937162280451323099126372019216020898338909808577022618554997063496690156977790629
e = 65537
c = 32384071331939239285992149489589967884022349189352515487950255250160126611084915524664364190130039873461090810189570222748422757594726643684332100753373557666031160718150203596579825955216919802911458293840557069152132506518827761626306871971480050052005979083878379439210757328323337697175682026549870910934
w = 12796020294902567574981427270787776254781813995526831579805652479456168245098217943847166109912113827479436654134179666391771173421469188197935460525521295192736123648410762964187396897298542198935971755852754544978564521188423737649175136194386664628304164316905741781089536713701674793641345344818309314224

P.<n,p> = PolynomialRing(ZZ)
n, p = P.gens()
f = n**31*p + 2*n**30*p**3 - n**30*p**2 - n**29*p**3 + n**28*p**7 - 2*n**28*p**6 + 2*n**28*p**5 - n**28*p**4 + 6*n**27*p**9 - 2*n**27*p**8 - n**27*p**7 - n**27*p**6 - 2*n**27*p**5 - n**26*p**10 - 5*n**26*p**9 + n**26*p**8 + 2*n**26*p**7 - 3*n**26*p**6 + n**25*p**13 + n**25*p**12 + n**25*p**10 + 2*n**25*p**9 - 3*n**25*p**8 - 2*n**25*p**7 + 5*n**24*p**15 + 3*n**24*p**13 - n**24*p**12 + 4*n**24*p**11 + n**24*p**10 + 5*n**24*p**9 - n**24*p**8 + n**23*p**16 - 2*n**23*p**15 + n**23*p**14 + 3*n**23*p**12 - 5*n**23*p**10 - 4*n**23*p**9 - 3*n**22*p**19 + 2*n**22*p**18 - 5*n**22*p**17 - n**22*p**16 + n**22*p**15 + n**22*p**13 + 2*n**22*p**12 - n**22*p**11 + 3*n**22*p**10 + n**21*p**20 - 2*n**21*p**19 - 2*n**21*p**18 - 2*n**21*p**17 - n**21*p**16 + n**21*p**15 - n**21*p**13 + 2*n**21*p**12 - 2*n**21*p**11 - 2*n**20*p**23 - n**20*p**22 - n**20*p**21 + n**20*p**20 - 2*n**20*p**18 - n**20*p**17 + n**20*p**16 - 5*n**20*p**15 + 2*n**20*p**14 - 2*n**20*p**13 + n**19*p**25 - 3*n**19*p**24 - 2*n**19*p**22 - n**19*p**19 + 4*n**19*p**18 + n**19*p**16 - 3*n**19*p**15 + 3*n**19*p**14 + 2*n**19*p**13 + n**18*p**27 - 2*n**18*p**26 + 5*n**18*p**25 + n**18*p**24 - 4*n**18*p**23 - 2*n**18*p**20 - 4*n**18*p**19 - n**18*p**16 + n**17*p**29 + n**17*p**27 - 2*n**17*p**26 + 2*n**17*p**25 - n**17*p**23 - 2*n**17*p**22 - 2*n**17*p**21 + n**17*p**19 + n**17*p**18 + n**17*p**17 - 2*n**17*p**16 - n**16*p**31 - n**16*p**30 + n**16*p**29 + 2*n**16*p**28 + 3*n**16*p**27 - n**16*p**26 - n**16*p**25 - n**16*p**24 + 2*n**16*p**23 + 2*n**16*p**22 + n**16*p**21 + 4*n**16*p**20 + 2*n**16*p**18 + n**16*p**17 - 4*n**15*p**33 + n**15*p**32 + n**15*p**31 + n**15*p**30 + n**15*p**29 + 4*n**15*p**28 + 2*n**15*p**26 - n**15*p**25 - n**15*p**24 + n**15*p**23 + 2*n**15*p**22 - 4*n**15*p**21 + 2*n**15*p**20 - 3*n**15*p**19 - 3*n**15*p**18 - 5*n**14*p**35 + n**14*p**33 - 2*n**14*p**32 - n**14*p**31 - n**14*p**30 - 2*n**14*p**29 + 4*n**14*p**28 - 2*n**14*p**27 + 3*n**14*p**23 - n**14*p**22 + n**14*p**20 + 3*n**14*p**18 + n**13*p**37 + n**13*p**35 - 3*n**13*p**34 - 4*n**13*p**33 + 2*n**13*p**32 + 2*n**13*p**31 - 2*n**13*p**29 - n**13*p**28 + n**13*p**26 - n**13*p**25 + n**13*p**23 + 2*n**13*p**22 - 4*n**13*p**20 - 3*n**13*p**19 - 4*n**12*p**39 + 2*n**12*p**38 - n**12*p**36 - 3*n**12*p**35 - n**12*p**34 - n**12*p**33 - n**12*p**32 + 2*n**12*p**31 + 2*n**12*p**30 + n**12*p**28 - n**12*p**27 + n**12*p**26 - n**12*p**25 + 4*n**12*p**24 + n**12*p**23 - n**12*p**22 - 2*n**12*p**21 - 2*n**12*p**20 - n**11*p**41 - 4*n**11*p**40 + 2*n**11*p**39 + 4*n**11*p**38 + n**11*p**37 + 2*n**11*p**36 - 2*n**11*p**35 - n**11*p**34 + 3*n**11*p**33 + 3*n**11*p**32 + n**11*p**31 + 6*n**11*p**30 + 2*n**11*p**27 + 2*n**11*p**26 - 2*n**11*p**25 + 2*n**11*p**24 - n**11*p**23 - 3*n**11*p**22 + 3*n**11*p**21 - 3*n**10*p**42 + 2*n**10*p**41 - 5*n**10*p**39 - n**10*p**37 - n**10*p**36 - 3*n**10*p**35 + 2*n**10*p**34 - 2*n**10*p**33 + n**10*p**32 + 3*n**10*p**31 + 3*n**10*p**30 + 2*n**10*p**29 + 3*n**10*p**28 + 4*n**10*p**27 + n**10*p**26 - 3*n**10*p**25 - n**10*p**24 + 2*n**10*p**23 - n**9*p**43 - 3*n**9*p**42 + 2*n**9*p**41 - n**9*p**40 + 2*n**9*p**39 - 4*n**9*p**38 + n**9*p**37 + 4*n**9*p**36 - 5*n**9*p**35 - 2*n**9*p**34 + n**9*p**33 + 3*n**9*p**32 - 5*n**9*p**31 + 3*n**9*p**30 + 3*n**9*p**28 + 4*n**9*p**27 - 4*n**9*p**26 - 4*n**9*p**25 - n**9*p**24 + 4*n**9*p**23 + 3*n**8*p**47 - 3*n**8*p**46 - 3*n**8*p**44 - 5*n**8*p**43 + n**8*p**42 + n**8*p**41 + 2*n**8*p**40 - 5*n**8*p**39 - n**8*p**36 + 2*n**8*p**35 - n**8*p**33 + 5*n**8*p**32 - n**8*p**31 + n**8*p**30 + 3*n**8*p**29 + 2*n**8*p**27 - 2*n**8*p**26 + n**8*p**25 - 2*n**8*p**24 - 4*n**7*p**49 - 3*n**7*p**48 - n**7*p**47 - 2*n**7*p**45 - 3*n**7*p**44 - n**7*p**42 - n**7*p**40 + n**7*p**39 + 2*n**7*p**38 + 2*n**7*p**36 - 3*n**7*p**35 + 2*n**7*p**33 - 2*n**7*p**32 - 4*n**7*p**31 - n**7*p**30 + n**7*p**29 - 2*n**7*p**27 + 2*n**7*p**26 - 2*n**6*p**50 + n**6*p**49 - 2*n**6*p**48 - 2*n**6*p**47 + n**6*p**46 + n**6*p**44 - n**6*p**43 - n**6*p**42 - n**6*p**41 + 4*n**6*p**40 - n**6*p**39 - 2*n**6*p**38 - 2*n**6*p**37 - n**6*p**36 - n**6*p**35 - 3*n**6*p**34 + 5*n**6*p**33 - n**6*p**32 + 3*n**6*p**31 + 3*n**6*p**30 - 2*n**6*p**29 + 4*n**6*p**28 - n**6*p**27 - 3*n**6*p**26 - n**5*p**52 - 2*n**5*p**51 - n**5*p**50 - 3*n**5*p**49 - n**5*p**46 - n**5*p**45 - 3*n**5*p**44 - n**5*p**43 - 3*n**5*p**42 + 3*n**5*p**41 - 2*n**5*p**40 + n**5*p**39 + 2*n**5*p**38 + n**5*p**37 - n**5*p**36 - n**5*p**35 + n**5*p**32 - n**5*p**31 + 3*n**5*p**30 + 3*n**5*p**29 - 2*n**5*p**28 + 2*n**4*p**55 - n**4*p**54 - n**4*p**53 + 2*n**4*p**52 + n**4*p**51 + 5*n**4*p**50 - n**4*p**49 + 2*n**4*p**45 + 2*n**4*p**44 - 2*n**4*p**42 - n**4*p**41 - n**4*p**40 - 3*n**4*p**39 - 5*n**4*p**38 - n**4*p**37 + n**4*p**36 - n**4*p**34 + n**4*p**33 - 4*n**4*p**32 + 2*n**4*p**30 - 2*n**4*p**29 - 2*n**4*p**28 + 7*n**3*p**57 + 2*n**3*p**56 + 3*n**3*p**55 + n**3*p**54 - 2*n**3*p**53 + n**3*p**52 - n**3*p**50 - n**3*p**49 - 2*n**3*p**48 - 2*n**3*p**46 + 2*n**3*p**45 + 2*n**3*p**43 - n**3*p**42 - n**3*p**41 + n**3*p**40 + n**3*p**38 + n**3*p**37 - 2*n**3*p**36 - 3*n**3*p**35 - 2*n**3*p**34 + 6*n**3*p**32 + n**3*p**31 - 3*n**3*p**30 + 3*n**3*p**29 - 2*n**2*p**59 + 2*n**2*p**58 - 2*n**2*p**56 + n**2*p**54 - 2*n**2*p**53 + n**2*p**52 + 2*n**2*p**51 - 2*n**2*p**50 - n**2*p**49 - n**2*p**47 - n**2*p**46 - 2*n**2*p**45 - 3*n**2*p**44 + n**2*p**43 + 2*n**2*p**42 - 2*n**2*p**41 + n**2*p**40 + 5*n**2*p**39 + 3*n**2*p**35 + n**2*p**33 + 6*n**2*p**32 - 2*n**2*p**31 + n**2*p**30 - n*p**61 - 3*n*p**60 - n*p**59 + 3*n*p**58 + n*p**57 + n*p**56 + 2*n*p**54 - n*p**53 + 2*n*p**52 - n*p**51 + 2*n*p**50 - 4*n*p**47 + n*p**46 + 3*n*p**45 + n*p**44 + n*p**43 + n*p**42 + n*p**41 - 2*n*p**40 - 3*n*p**39 - n*p**38 - 3*n*p**35 - 2*n*p**34 - 2*n*p**33 - n*p**32 + 2*n*p**31 + p**63 - 2*p**62 - 2*p**61 + 3*p**60 + p**59 + 3*p**57 - p**56 + p**55 - p**54 - 3*p**53 + p**52 - p**50 - p**49 - 3*p**48 - p**47 - p**46 + 3*p**44 - p**42 + 4*p**41 + 2*p**40 + 2*p**39 - 4*p**38 + p**37 + 2*p**36 - 5*p**35 + 2*p**34 - 2*p**33 - 2*p**32
for i, j in zip(f.monomials(), f.coefficients()):
w *= pow(2, -ZZ(j) * i.subs(p = 1, n = N), N)
w %= N


p = gcd(w - 1, N)

多嘴解释几句

  1. **zip(f.monomials(), f.coefficients())**:

    • **f.monomials()**:这个方法返回多项式 f 的所有单项式(monomials)。例如,如果 ( f(n, p) = 2n^2p + 3np^2 + 5 ),f.monomials() 返回 [n^2*p, n*p^2, 1]
    • **f.coefficients()**:这个方法返回与多项式中每一个单项式对应的系数。例如,对应于上述多项式,f.coefficients() 可能返回 [2, 3, 5]
    • **zip(...)**:这两个列表会被结合,形成一个迭代器。如此一来,我们在遍历时能同时得到单项式 i 和其系数 j,例如:
      1
      [(n^2*p, 2), (n*p^2, 3), (1, 5)]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   
2. **for i, j in ...**:

- 开始了一个循环,每次循环取出一个单项式 `i` 和其对应的系数 `j`。

3. **i.subs(p = 1, n = N)**:
- `i.subs(...)` 方法用于替换单项式 `i` 中的变量。这里将单项式 `i` 中的变量 `p` 替换为 `1`,将 `n` 替换为 `N`。这一步的目的是计算单项式在特定值下的表现。
- 例如,如果 `i` 是 `n^2 * p`,替换后得到了 `N^2 * 1 = N^2`。


主要来看看第二部分,首先我们来复习一下python中bytes_to_long的原理,bytes_to_long(b'123')=bytes_to_long(b'1')$*$256$^2$+bytes_to_long(b'2')$*$256$^1$+bytes_to_long(b'3')$*$256$^0$

​```python
print(bytes_to_long(b'123'))
print(bytes_to_long(b'1'))
print(bytes_to_long(b'2'))
print(bytes_to_long(b'3'))
print(49*256**2+50*256**1+51*256**0)

3224115
49
50
51
3224115

那么对于本题来说,c≡256$^{81}$$$pre+256$$m+suf (mod p),其中pre指‘NSSCTF{’,suf指‘}’。我们中间填充b’0‘那么就可得到m≡(c−256$^{81}$$*$pre−b’0’*80-suf)(mod p),

有了这点就可以造格了。(懒得latex了,手写一下)

OSRrvj.jpg

加强了解的话可以去做一下鸡块师傅的ezmod系列。2024-NSSCTF-密码工坊非官方dlc-wp-crypto | 糖醋小鸡块的blog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from Crypto.Util.number import *
p = 12887845651556262230127533819087214645114299622757184262163859030601366568025020416006528177186367994745018858915213064803349065489849643880676026721892753
c = 10266913434526071998707605266130137733134248608585146234981245806763995653822203763396430876254213500327272952979577138542487120755771047170064775346450942
prefix = b"NSSCTF{"
suffix = b"}"
length = 88 - len(prefix) - len(suffix)

#part1 remove prefix and suffix
m0 = bytes_to_long(prefix)*256**81+bytes_to_long(b'0'*80)*256+bytes_to_long(suffix)
c0 = (c-m0)%p
print(c0)
L = Matrix(ZZ,length+2)
for i in range(length):
L[i,i] = 1
L[i,-1] = 256^(i+1)
L[-2,-2] = 1
L[-2,-1] = -c0
L[-1,-1] = p
RES = L.BKZ()
for i in RES:
if abs(i[-2]) == 1 and i[-1] == 0:
m = b'NSSCTF{' + b"".join(str(j).encode() for j in i[:-2][::-1]) + b'}'
if bytes_to_long(m) % p == c:
print(m)
break