SHCTF2023 Crypto
XOR
n = 20810298530643139779725379335557687960281905096107101411585220918672653323875234344540342801651123667553812866458790076971583539529404583369246005781146655852295475940942005806084842620601383912513102861245275690036363402134681262533947475193408594967684453091957401932685922178406769578067946779033282889429596341714417295489842047781388337010440309434639274398589029236213499110100040841426995862849012466514170374143655264739023758914247116354182164550612494432327931655944868705959874670536031052370968354394583880324756639698871918124498442308334232127034553164826483441746719644515097123067550594588348951855987
c = 15294238831055894095745317706739204020319929545635634316996804750424242996533741450795483290384329104330090410419090776738963732127756947425265305276394058773237118310164375814515488333015347737716139073947021972607133348357843542310589577847859875065651579863803460777883480006078771792286205582765870786584904810922437581419555823588531402681156158991972023042592179567351862630979979989132957073962160946903567157184627177910380657091234027709595863061642453096671316307805667922247180282486325569430449985678954185611299166777141304330040782500340791721548519463552822293017606441987565074653579432972931432057376
e = 65537
p⊕q = 66138689143868607947630785415331461127626263390302506173955100963855136134289233949354345883327245336547595357625259526618623795152771487180400409991587378085305813144661971099363267511657121911410275002816755637490837422852032755234403225128695875574749525003296342076268760708900752562579555935703659615570
利用dfs剪枝搜索p,q的值 这里写法一定要规范 不然很容易跑不出
尝试了两种约束条件
- len(p)==1024
- isPrime(int(p,2)) and n%int(p,2)==0
只有用len(p)bit数判断才不会递归溢出
import sys
from Crypto.Util.number import *
from primefac import *
from gmpy2 import *
from sympy import *
from libnum import *
n = 20810298530643139779725379335557687960281905096107101411585220918672653323875234344540342801651123667553812866458790076971583539529404583369246005781146655852295475940942005806084842620601383912513102861245275690036363402134681262533947475193408594967684453091957401932685922178406769578067946779033282889429596341714417295489842047781388337010440309434639274398589029236213499110100040841426995862849012466514170374143655264739023758914247116354182164550612494432327931655944868705959874670536031052370968354394583880324756639698871918124498442308334232127034553164826483441746719644515097123067550594588348951855987
c = 15294238831055894095745317706739204020319929545635634316996804750424242996533741450795483290384329104330090410419090776738963732127756947425265305276394058773237118310164375814515488333015347737716139073947021972607133348357843542310589577847859875065651579863803460777883480006078771792286205582765870786584904810922437581419555823588531402681156158991972023042592179567351862630979979989132957073962160946903567157184627177910380657091234027709595863061642453096671316307805667922247180282486325569430449985678954185611299166777141304330040782500340791721548519463552822293017606441987565074653579432972931432057376
e = 65537
p_xor_q = 66138689143868607947630785415331461127626263390302506173955100963855136134289233949354345883327245336547595357625259526618623795152771487180400409991587378085305813144661971099363267511657121911410275002816755637490837422852032755234403225128695875574749525003296342076268760708900752562579555935703659615570
sys.setrecursionlimit(3000)
# dfs
p = '1'
q = '1'
def dfs(p,q):
if(len(p)==1024):
pp = int(p,2)
if(n%pp==0):
print(' p= ',pp)
print(' q= ',n//pp)
else:
l = len(p)
pp = int(p,2)
qq = int(q,2)
if (pp^qq)%(2**l) == p_xor_q%(2**l) and (pp*qq)%(2**l) == n%(2**l):
dfs('1'+p,'1'+q)
dfs('1'+p,'0'+q)
dfs('0'+p,'0'+q)
dfs('0'+p,'1'+q)
print('-----Start------')
# dfs(p,q)
p= 121707024037268877853347577606022680727723421754483145354598542291389059730952536897407296725631390435306824149329251450428520017032068370905491236371588783551854860933656246846861645834009102275363106544337746297119821339365287420703692873394398852690091625453178968493127766149991473384937200789954598163517
q= 170986832479534233007906048950464510414382588164533889416767650420928742690929190093999799507883047422413122991286355305384227808800633111611572663168246588357071419165779511128259447564377245832827901688451015954867004306626552500789867499455455629032408110167560346510245108938981288797349665759162752876911
d = modinv(e,(p-1)*(q-1))
print(n2s(int(pow(c,d,n))))
print('------End-------')
easymath
chall.py
from Crypto.Util.number import *
from random import *
p = getPrime(128)
seed = randint(2, p - 1)
class prng:
n = p
a,b = [randint(2, p - 1) for _ in range(2)]
def __init__(self,seed):
self.state = seed
def next(self):
self.state = (self.state * self.a + self.b) % self.n
return self.state
def main():
gen = prng(seed)
s = [seed]
s.append(gen.next())
s.append(gen.next())
s.append(gen.next())
s.append(gen.next())
s.append(gen.next())
s.append(gen.next())
f = open("output.txt",'w')
json.dump(s,f)
f.close()
flag = "flag{"+str(gen.next())+"}"
return flag
main()
LCG恢复a,b,n
有篇很好的博客
solution.py
# a b n 都不知道
from primefac import *
from libnum import *
output = [288530505749272642500730917886204398531, 63547143998110685331032679758907988154, 15151206512028268617888756820805603406, 268092204209244869520724955865278855216, 261067075335188593563542448889694952077, 138067838531633886698552659065694918861, 201319433320428898153580935653793106657]
# 先恢复n
t = []
for i in range(len(output)-1):
t.append(output[i+1]-output[i])
T = []
for i in range(1,len(t)-1):
T.append(t[i-1]*t[i+1]-t[i]*t[i])
kn = T[0]
for i in range(len(T)):
kn = gcd(kn,T[i])
print(kn)
n = 312769358113056565136009929613710078319
# 恢复a
a = (output[2]-output[1])*modinv(output[1]-output[0],n)%n
# 恢复b
b = (output[1]-a*output[0])%n
print(a,b,n)
print((a*output[-1]+b)%n)
# flag{302184756857257140159769321021979097116}
撤退
chall.py
from Crypto.Util.number import *
flag = *******
p = getPrime(1024)
q = getPrime(1024)
n = p * q
hb = len(flag)//2
hb1 = bytes_to_long(flag[:hb])
hb2 = bytes_to_long(flag[hb:])
D = 117
x = *******
y = *******
assert x**2 - D * y**2 == 1
enc1 = pow(334 * n ** 2 + 1, hb1, n ** 3)
enc2 = pow(y * n + 1, hb2, n ** 3)
print(n)
print(enc1)
print(enc2)
'''
22970461944771505344360312103272646796516672838005008112295760406393062653512719537671401409823031480497512491850701737384621917068068328814717390355072928714618936469722031401433712342846780800586803218279291870162605299119904016959036663767093191710796830156169925350938267584422752300171293262391805105435418210827517225439398971437884496416502510866914857269951072184669675339439115587325754431761172634305242650221404868035624879538862880516438147301289746375407945908866907822940285764276956194031840381838253923392794376568293056359058519233175242523219646628321609305890926063856400793680641992567798104042179
26380574883568223071748995929433720836641856899148821439556557592284999544802260386919172895274884666117488851000353221957579311943624258651646692068406462392980585841604755021251430357273933800209194484692955106014890051223465745443628784077844452303995642424661442978294757109040081050794398646640530714904683097650259060507908334791761124660725589404056356987726993518057050112725483482660202442987346646160168856264312557595890710521723067518303906942469282527855551751244126251698491010628369012024332666619702895796133780038584346428759785302542637171018926824843416176876077558936427399803328577151066597396550597352625005028261156114571696860700477410270949916316951150072218466374341394892405947793726872954497972795793421222424616005278493704125169150432275472846871295341469911428057621028515874978272004775903906188556908968810828510069826724631700523623584802605889173266453916347583720706846630531082266742377818663000322817114065116737931523412220137972079139507877669106470150742546914051556747087768279286696519700220233815812834114117581332234344024169109786527295900675653245014343393093832478814567179131966404207553408747774003319241150221488231674711614902743345516888975702483348011349617017294004761259419165663633915672647187482242462163420462987034240805524991
21190674872507845600786632640969893237129139877891071648594239906632201421611954626926407751780936578853046780585253060958265549804784845192757301417173404074965693840282568701968464564320290763073618132775799910356101999797720378313304899173154753858674284071499775857913937184713024788245068426198878834805943703426673512761178072458895973672088230653246356764681418231485563287856188079274727706554037799748595877069143254516390328019381867648697880975670688337068196993846986940286056873616919629721264139576692806770826129279380704466982862393203486037890448173834315360975464927583664991534571518159777852793416869350127023692816051992183670690315184731534611966603509867722931839839084915943647295195314171688904055674915382434841320612108023531722571519492067471405656160804893645713608592561788743509876384862097871840094582513721456962354498561006793609200187065931433827465455037397503619844768415369973322759940610358415184510344945559838007474725413347675347453443583610217539704055467297318282309867987435252614428856515259899385689971172417660178761139941056839133998928898528744331662995956041897599276732929020537698559927654297185422925737241274711904687894411308774527520523946951208805307060323875839353707549772052299847176824964552693112658495961070555882583739017417359463576705453026824255338859618053086622031941
'''
首先解一个佩尔方程
这里直接暴力枚举求解
得到x,y
然后分析下enc1,enc2 由于n ^ 3超级大 不可能直接求离散对数吧。。。
注意到mod n ^ 3 考虑二项式展开
这样n的次数>=3的直接Mod意义下就消掉了
最后得到hb1,hb2的两个简单的<=2次的方程 考虑到模数3072bit
同余可以转等式 直接利用solve解方程即可(注意这里solve的用法 不是solve(...==0,x) 而是 solve(...,x))
from libnum import *
from sympy import *
from primefac import *
from gmpy2 import *
x ,y= 649 ,60
n = 22970461944771505344360312103272646796516672838005008112295760406393062653512719537671401409823031480497512491850701737384621917068068328814717390355072928714618936469722031401433712342846780800586803218279291870162605299119904016959036663767093191710796830156169925350938267584422752300171293262391805105435418210827517225439398971437884496416502510866914857269951072184669675339439115587325754431761172634305242650221404868035624879538862880516438147301289746375407945908866907822940285764276956194031840381838253923392794376568293056359058519233175242523219646628321609305890926063856400793680641992567798104042179
enc1 = 26380574883568223071748995929433720836641856899148821439556557592284999544802260386919172895274884666117488851000353221957579311943624258651646692068406462392980585841604755021251430357273933800209194484692955106014890051223465745443628784077844452303995642424661442978294757109040081050794398646640530714904683097650259060507908334791761124660725589404056356987726993518057050112725483482660202442987346646160168856264312557595890710521723067518303906942469282527855551751244126251698491010628369012024332666619702895796133780038584346428759785302542637171018926824843416176876077558936427399803328577151066597396550597352625005028261156114571696860700477410270949916316951150072218466374341394892405947793726872954497972795793421222424616005278493704125169150432275472846871295341469911428057621028515874978272004775903906188556908968810828510069826724631700523623584802605889173266453916347583720706846630531082266742377818663000322817114065116737931523412220137972079139507877669106470150742546914051556747087768279286696519700220233815812834114117581332234344024169109786527295900675653245014343393093832478814567179131966404207553408747774003319241150221488231674711614902743345516888975702483348011349617017294004761259419165663633915672647187482242462163420462987034240805524991
enc2 = 21190674872507845600786632640969893237129139877891071648594239906632201421611954626926407751780936578853046780585253060958265549804784845192757301417173404074965693840282568701968464564320290763073618132775799910356101999797720378313304899173154753858674284071499775857913937184713024788245068426198878834805943703426673512761178072458895973672088230653246356764681418231485563287856188079274727706554037799748595877069143254516390328019381867648697880975670688337068196993846986940286056873616919629721264139576692806770826129279380704466982862393203486037890448173834315360975464927583664991534571518159777852793416869350127023692816051992183670690315184731534611966603509867722931839839084915943647295195314171688904055674915382434841320612108023531722571519492067471405656160804893645713608592561788743509876384862097871840094582513721456962354498561006793609200187065931433827465455037397503619844768415369973322759940610358415184510344945559838007474725413347675347453443583610217539704055467297318282309867987435252614428856515259899385689971172417660178761139941056839133998928898528744331662995956041897599276732929020537698559927654297185422925737241274711904687894411308774527520523946951208805307060323875839353707549772052299847176824964552693112658495961070555882583739017417359463576705453026824255338859618053086622031941
var('x')
ans = solve([334*x*n^2 + 1 - enc1],x)
print(ans)
var('x')
f = 1800*x*(x-1)*n*n+60*x*n+1-enc2
ans = solve(f,x)
print(ans)
hb1 = 149691910197777805350862530703771372803641869951585
hb2 = 149371042625025154522769720206540986718252215526781
flag = b''
flag += n2s(int(hb1))
flag += n2s(int(hb2))
print(flag)
最后补充一下用连分数解佩尔方程
x ^ 2 - D * y ^ 2 = 1
可以近似等价为 D=x^2 / y^2
那么对sqrt(D)连分数展开 就能找到渐进分数逼近x/y check一下即可
from math import *
D = 117
def Pell(D):
sq_D = sqrt(D)
c = continued_fraction(sq_D)
c = c.convergents()
print(c)
for i in c:
a = str(i).split('/')
if(len(a)>1):
x = int(a[0])
y = int(a[1])
if(x*x-D*y*y==1):
print(f'x={x}, y={y}')
Pell(D)
实验一下发现连分数求解要快得多且更为准确
3!!!
chall.py
from Crypto.Util.number import *
import random
from secret import flag
M = 2**54
k = 6
def gen_prime(M, k):
while True:
prime = sum([random.getrandbits(16) * M**i for i in range(k)])
if isPrime(prime) and (prime-1) % 3 == 0:
return prime
p, q, r = [gen_prime(M, k) for i in range(3)]
N = p * q * r
e = 3
m = bytes_to_long(flag)
c = pow(m, e, N)
print(f'N = {N}')
print(f'c = {c}')
"""
N = 3298593732762513945346583663585189774036688951059270517149719979434109398447628726951796006700754759352430339647168415338320547665794785951232342902233013221132246450312038122695046634624323814318286314664160113738299465643128504110932989263063331290006313
c = 869489491924953293290699796392271834401780578884556874640489836779925847562085802848542382525324081900560761299059365684697233025590164192409062717942292142906458498707677300694595072310705415037345581289469698221468377159605973403471463296806900975548438
"""
分析一下所给条件
(prime-1) % 3 == 0 这个可以推出(e,phi)=3 所以需要有限域开方
然而直接对n开的话显然跑不出来 所以必须得分解出p,q,r
这里有个特别巧的想法
题目给得构造p,q,r的形式特别像是M进制下的数的构造
所以将N写成M进制 再将M换为变量'x' 进行多项式分解
得到 p(x),q(x),r(x) 再反代入x=M即可解出p,q,r
这里用sage自带的Integer(N).digits(M)
和poly.factor_list()实现
本地的好像又跑不起来 用sage在线跑
N = 3298593732762513945346583663585189774036688951059270517149719979434109398447628726951796006700754759352430339647168415338320547665794785951232342902233013221132246450312038122695046634624323814318286314664160113738299465643128504110932989263063331290006313
c = 869489491924953293290699796392271834401780578884556874640489836779925847562085802848542382525324081900560761299059365684697233025590164192409062717942292142906458498707677300694595072310705415037345581289469698221468377159605973403471463296806900975548438
M = 2^54
poly = sum(e * x^i for i,e in enumerate(Integer(N).digits(M)))
print(poly)
assert poly(x=M)==N
print(poly.factor_list())
(p,_),(q,_),(r,_) = poly.factor_list()
print(f'p= {p(x=M)}\nq= {q(x=M)}\nr= {r(x=M)}')
得到p,q,r后分别以p,q,r为模数开3次方 再CRT合并结果
M = 2**54
N = 3298593732762513945346583663585189774036688951059270517149719979434109398447628726951796006700754759352430339647168415338320547665794785951232342902233013221132246450312038122695046634624323814318286314664160113738299465643128504110932989263063331290006313
c = 869489491924953293290699796392271834401780578884556874640489836779925847562085802848542382525324081900560761299059365684697233025590164192409062717942292142906458498707677300694595072310705415037345581289469698221468377159605973403471463296806900975548438
e = 3
p= 103574226729554375480512668967949133854292403117507474988278388756193462602107352821951
q= 47963432552002818180880760250824590058982930733941748241661938238195705638187268342813
r= 663998156522471100999941798165706402858681862228017448075268472245282758965006970051
P.<a>=PolynomialRing(Zmod(p),implementation='NTL')
f=a^e-c
mps=f.monic().roots()
P.<a>=PolynomialRing(Zmod(q),implementation='NTL')
f=a^e-c
mqs=f.monic().roots()
P.<a>=PolynomialRing(Zmod(r),implementation='NTL')
f=a^e-c
mrs=f.monic().roots()
# print(mps,mqs,mrs)
flag = []
for mp in mps:
x = mp[0]
for mq in mqs:
y = mq[0]
for mr in mrs:
z = mr[0]
posans = CRT_list([int(x),int(y),int(z)],[p,q,r])
flag.append(posans)
print(flag)
from libnum import *
flag = [1229542991822673155823831728564360985400525920406596525982980307135948743629544646080065773249565679616270970791123564701594680629796733964245890251007275977572599838928291269111351317202410731474379674588094469917299761018140497581750082862134793455368222, 8863920835279653454144601612937106353991656065595807095907732743149565292419689746454978180994153726024905990729324029905419999859808796981737419505360308732687821313735267154503670675024267221314190635267740942618952227698496407536581535172552698910840, 1970925157201234979871759823394864682563208308947585681682237661504946396767557117404839002173933040850837015096270441869435104907420023638596392117766527923016975290152638122511705119092809044260908837169248223536602351631340586417971300904880205367169482, 76808143072488021277008229628982925718812098828290691746797464367957806100377839029519538545709282891292949132897804565813780791139120210164935503557328404073049522618095213429287213793317737992091411669237847368894736401788943677023627948961026743620716, 2154722804847608464253904766262748820708966785546560490009444869409268026210881609647704750177892516353477223979671979232445067826996980994133125574288425956365383955315577334167486201890255088057312242380571232132513393254475446613743115885062117277169647, 818190308451049845324936324459486622881494487369279847446054818736955459238390310354292767470076644125858993438044681733654205068762409884515437370316580349517424973842442066829641015683716050778620574250391600988197327014989032513244845991706438655421976, 229600466452046757641086161363066126944704695769994835292399976908673822250877521395298834113538588009776897744565883781819618904527976078166958049228920952301816090722639051187741027375457305555196625409204794285845436218600916308106423531182853818877097, 2307515128227167200617982697996832021934859382488264633555047381949984042361381292013484045745721821471961172591340058448450905940385836862135148119960018504594150523420121171925940015472394655620417456120538179049464093071287419244825911467283944352426028, 970982631830608581689014256193569824107387084310983990991657331277671475388889992720072063037905949244342942049712760949660043182151265752517459915988172897746191541946985904588094829265855618341725787990358547905148026831801005144327641573928265730678357, 2220621596358019900552432694152718737502355488977602409577652904620074099715792081018377734204598617496740137846951921591464322355205683053343085033280270750117088559249628637891263952436342391888791049613140945777746284879592730879779495872394876091496600, 999942525370626398182745567201294858455821224636601690690580330227274921378667124684766939136027091606494073046557680919775061725268757886078932201778355081277176541635072635934416305908955927635725565660314216803065476089150729705565994545432635335039218, 2962003761736581724600360788983222434665037877518591565276910258989071752853804552343150963128965978731306182152098798759304746632828972727693586900039522695561464010473975491291617754326740704675320212194294699397048875492792819716000713915140288003297860, 1067886747607834766005609195217340677820641667399296575341470061852083162186625273967831499500742220771762116188726161455683422516548069299262130285830323176617538242939432582209199849027249398406502786694284323229341260263241176975053040959221109379749094, 3145801409382955208982505731851106572810796354117566373604117466893393382297129044586016711132925454233946391035500336122314709552405930083230320356561420728909872675636914702947398837124186748471723617405617707992959917115927679911772528895322199913298025, 1809268912986396590053537290047844374983324055940285731040727416221080815324637745292604728425109582006328160493873038623523846794171358973612632152589575122061913694163779435609553650917647711193031949275438076848643850876441265811274259001966521291550354, 1220679070987393502369687126951423879046534264341000718887072574392799178337124956333610795068571525890246064800394240671689260629936925167264152831501915724846304811043976419967653662609388965969608000434251270146291960080053149606135836541442936455005475, 56006392793429420418010806016082002501716542516481424541171611151289611148431922335214480695698548093, 1962061236365955326417615221781927576209216652881989874586329928761796831475137427658384023992938887124812109105541117839529684907560214841614654698261167670290680262268323273368007464499787278756137163015405023765594550693253238442357054584188348366806735, 2480403424311464100021647339125703151155194463689990669703665160697153939209238416597503239230678115226571346209123733604666342597032376066716905531916432815608428683040175637854599602858605261823123223932343971578490987338528323165765808056876196936036244, 1259724353324070597651960212174279272108660199348989950816592586304354760872113460263892444162106589336325281408729492932977081967095450899452752700414517146768516665425619635897751956331218797570057739979517242603810178548086321991552306729913956179578862, 3221785589690025924069575433956206848317876852230979825402922515066151592347250887922276468155045476461137390514270610772506766874655665741067407398675684761052804134264522491254953404749003574609652386513497725197793577951728412001987026099621608847837504, 1327668575561278965474823840190325091473480642111684835467482317929163001680071609546957004526821718501593324550897973468885442758374762312635950784466485242108878366729979582172535499449512268340834961013487349030085962722176769261039353143702430224288738, 106989504573885463105136713238901212426946377770684116580409743536363823342946653213346209458250192611347259750503732797196182128437837145371797952964569573268966349115423580215687852922125804087769477060660620055405153931734768086825851816740189467831356, 2069050740939840789522751935020828788636163030652673991166739672298160654818084080871730233451189079736159368856044850636725867035998051986986452651225737187553253817954326435572889301339910581127364123594641102649388553335376858097260571186447842136089998, 1480460898940837701838901771924408292699373239053388979013084830469879017830571291912736300094651023620077273162566052684891280871763618180637973330138077790337644934834523419930989313031651835903940174753454295947036662538988741892122148725924257299545119, 259781827953444199469214644972984413652838974712388260126012256077079839493446335579125505026079497729831208362171812013202020241826693013373820498636162121497732917219967417974141666504265371650874690800627566972355853748546740717908647398962016543087737, 2221843064319399525886829866754911989862055627594378134712342184838876670968583763237509529019018384854643317467712929852731705149386907854988475196897329735782020386058870273331343114922050148690469337334608049566339253152188830728343366768669669211346379]
for f in flag:
s = n2s(int(f))
if(b'flag' in s):
print(s)
# b'flag{e1b7d2c2-e265-11eb-b693-98fa9b5bc5fe}'
easyrsa
chall.py
from Crypto.Util.number import *
from flag import flag
p1 = getPrime(512)
q1 = getPrime(512)
n1 = p1 * q1
e = 65537
p2 = getPrime(1024)
q2 = getPrime(1024)
n2 = p2 * q2
leak1 = (p2+q2) >> 400
leak2 = (p1 & ((1 << 350) - 1)) >> 5
enc = pow(leak2,e,n2)
c = pow(bytes_to_long(flag),e,n1)
f = open(f'output.txt','w')
f.write(f'n1 = {n1}\n')
f.write(f'n2 = {n2}\n')
f.write(f'leak1 = {leak1}\n')
f.write(f'enc = {enc}\n')
f.write(f'c = {c}')
f.close()
由于没找到数据(...)大致分析一下思路:
首先注意到leak2 = (p1 & ((1 << 350) - 1)) >> 5
这里相当于泄露了p1的5~350位 我们只用爆破低5位的bit然后用copper即可解出p1
那么现在就需要得到leak2
题目给了leak1 leak1 = (p2+q2) >> 400
这里怎么还原p2呢?
其实 由于p2,q2都是1024bits 而我们只有p2+q2的低400位不知道
如果我们以 p2'+q2'=leak1<<400 和p2' * q2' = n联立求解的话
得到的p2'其实跟p2只有低位不同(其实这里不一定恰好是低400位不同) 这是因为我们考虑的位数都是二进制下的 而二进制下两个400bit的低位相乘对高位的影响位数不会很大(担心的话将X放到beta计算出来的上界即可)
那么就可以copper求解了
这里用另一道一模一样的题来说明
chall.py
from Crypto.Util.number import *
flag = b'xxx'
p = getPrime(512)
q = getPrime(512)
n = p * q
P = getPrime(1024)
Q = getPrime(1024)
N = P * Q
e = 65537
gift = (P+Q) >> 400
hint = (p & ((1 << 350) - 1)) >> 5
enc_hint = pow(hint,e,N)
c = pow(bytes_to_long(flag),e,n)
f = open(f'out{i+1}.txt','w')
f.write(f'N = {N}\n')
f.write(f'n = {n}\n')
f.write(f'gift = {gift}\n')
f.write(f'enc_hint = {enc_hint}\n')
f.write(f'c = {c}')
N = 19913283586978731272870374837854045562790864804312115658302463830117436116219931849180682454814957654994095500743161455669517742683196683945049694888375426558735311269294662060482717191409995553476857418604462748567614908456839975140435522714312533340013676955820372105156740228641356206825881138276471973278761948406726062399175269553184359236859175084438349221553915085882218661560890322526503741457647907788204833926214096369428913779871365689037671018942683561649187089844083798834324075157252488088496084629641115161544547506935703532950490109236586524242732310854674446718076810611730874295399180178401471353663
n = 98394377912970161077976095071716071520245470884522650898371541866651139965831581427336428521179335097560338145643418890363050369233502530295868251106114979969844387393758147627569985743852463470545138002189902685566590889175140517151122304528973863485700142820829052897139853465497289644064298161242772703289
gift = 112012823249741273956420414320152024086394551241563686416444057368708038459572554871491781707278127933195689073127882065060125127295041489653572915729848455155059117821290550157606860744547
enc_hint = 13605762329549698957586626266580933128225639142810971158632386694900212152297364700673906983331081843360581227221052403163762155206266035280442283924005142717129467351643173282810669982201476798388553001056498736307588260706475327062302787323877507524036357644241120006072323797778327893834792299939570334886948188364597473931268889437417695532862093912649528155151390080600081199337965649892379699786628095487656690228838497716512853509768997296826487263776776447496125752546322173589223915740715451543895861668143819159937998988611022766833424669076863898157258297885102980961819003128529680884480390557024888414518
c = 73440769815335471983607426365687905918721184275652299429416892828899873930224614597826204961136670712832234285387297735959592122505613951335959593105045789810808172640134939607018894726831927984520480432707238536268054572649912957275921796939059679116900910403261478040783178268712136617053467195749630152736
按照上面的分析
先解P高位(注意这里由于是近似开根(不是整数) 所以用RealField 生成方法与PolynomialRing不同 注意规范)
RF = RealField(2048)
x = polygen(RF)
f = x*((gift<<400)-x)-N
f = f.monic()
print(f.roots())
for i in f.roots():
print(int(i[0]))
再copper解P
"""
Ps = [
112961875828607551060984650305450182210327591439870339348232669537033668993023777213823130103997354038633132241084090135131919602424749538384583821022489740672146383187216215728437700031367443734385496675259716944440109324744626491354552870863879084541563742319876060970312637717407118684703532804936980680424,
176283223352207293636559308903776794802241816833487708609505595165122810331828456380777192941829816139723941644466148654805963412864986845410672667622849172455457261836539651547261887774606665011806403295046738282963388064679054163117313781164348268270831635419714706011384513859647899983830253850450329940247
]
"""
for Phigh in Ps:
PR.<x> = PolynomialRing(Zmod(N))
f = Phigh+x
f = f.monic()
P = Phigh + f.small_roots(X=2^410,beta=0.4)[0]
if is_prime(P) and N%P==0:
print(P)
# P= 112961875828607551060984650305450182210327591439870339348232669537033668993023777213823130103997354038633132241084090135131919602424749538384583821022489740672146383187216215728437700031364931698746655847035538847193290003834069025142196383579427993632529030752437701976589064125591744562505229359012910444759
解出P后就能得到hint 最后解p
hint = 52025683076044044599992400773221280746229263847635117575567345877303750178218448109638198217351426116857
for low in range(2**5):
PR.<x> = PolynomialRing(Zmod(n))
f = (x*2^350) + (hint*2^5) + low
f = f.monic()
roots = f.small_roots(X=2^170,beta=0.4)
if roots:
p = (roots[0]*2**350) + (hint*2**5) + low
if n%p==0:
print('p= '+p)
# p= 12875389203118258668614951298149797909799840999471786801115807021855220020135243368328555419081024867855094746702504569598236375581106125211941848589901621
写这道题时sage出现了一些杂七杂八的错误 解决方法就是用在线sage来跑
把需要依赖库的和不需要的分开 解出关键数据后再本地跑