from Crypto.Util.number import * from pwn import *
sh = remote("xyctf.top",39233)
#part1 get data sh.recvuntil(b"> ") sh.sendline(b"1") temp = sh.recvline().strip().decode() iv = long_to_bytes(int(temp[:32],16)) enc = long_to_bytes(int(temp[32:],16))
defcomplex_pow(c, exp, n): result = Complex(1, 0) while exp > 0: if exp & 1: result = result * c result.re = result.re % n result.im = result.im % n c = c * c c.re = c.re % n c.im = c.im % n exp >>= 1 return result
m = bytes_to_long(flag) key = getRandomNBitInteger(m.bit_length()) c = m ^ key com = Complex(key, c) p = getPrime(512) q = getPrime(512) e = 9 enc = complex_pow(com, e, p * q) print(enc) print(Complex(p, q) * Complex(p, q)) # 66350931528185981323649477263900844564494528747802437244889229343520648562164950914433406604580038018765783183569276743239888668912948977370163046257917321742455772852779551569446155827368453262479370103326286297164105599131090881306108546341785251895116423206455175290083968296281375908109039893280371271943 + 65266730684129269806656018828265187384002656633231286337130178390517924611751697965395744944541329793503617856896706439809241745206839328124348693486741656130890593895436661857688522977866438805549144904296596887218275440542852887148071837153436265722614658566275517205322945316112048487893204059562830581004i # -28814875173103880290298835537218644402443395484370652510062722255203946330565951328874411874019897676900075613671629765922970689802650462822117767927082712245512492082864958877932682404829188622269636302484189627580600076246836248427780151681898051243380477561480415972565859837597822263289141887833338111120 + 235362412848885579543400940934854106052672292040465052424316433330114813432317923674803623227280862945857543620663672974955235166884830751834386990766053503640556408758413592161122945636548462064584183165189050320898315823173824074873376450569212651128285746330837777597290934043912373820690250920839961482862i
defcomplex_pow(c, exp, n): result = Complex(1, 0) while exp > 0: if exp & 1: result = result * c result.re = result.re % n result.im = result.im % n c = c * c c.re = c.re % n c.im = c.im % n exp >>= 1 return result
p = 10205509456040823453782883291824829705816298450992336115902525676510986341532486274067943978039013674207011185602314114359146043975207543018267242312660911 q = pq2 // 2 // p
com = Complex(66350931528185981323649477263900844564494528747802437244889229343520648562164950914433406604580038018765783183569276743239888668912948977370163046257917321742455772852779551569446155827368453262479370103326286297164105599131090881306108546341785251895116423206455175290083968296281375908109039893280371271943 , 65266730684129269806656018828265187384002656633231286337130178390517924611751697965395744944541329793503617856896706439809241745206839328124348693486741656130890593895436661857688522977866438805549144904296596887218275440542852887148071837153436265722614658566275517205322945316112048487893204059562830581004) re = int(complex_pow(com, inverse(3,(p^2-1)//3), p).re) im = int(complex_pow(com, inverse(3,(p^2-1)//3), p).im)
PR.<a,b> = PolynomialRing(Zmod(p)) f1 = a^3 - 3*a*b^2 - re f2 = 3*a^2*b - b^3 - im h = f1.sylvester_matrix(f2, a).det() res1 = h.univariate_polynomial().monic().roots() print(res1)
re = int(complex_pow(com, inverse(3,(q^2-1)//3), q).re) im = int(complex_pow(com, inverse(3,(q^2-1)//3), q).im) PR.<a,b> = PolynomialRing(Zmod(q)) f1 = a^3 - 3*a*b^2 - re f2 = 3*a^2*b - b^3 - im h = f1.sylvester_matrix(f2, a).det() res1 = h.univariate_polynomial().monic().roots() print(res1)
from Crypto.Util.number import * import hashlib import itertools
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree() R = f.base_ring() N = R.cardinality() f /= f.coefficients().pop(0) f = f.change_ring(ZZ) G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g) B, monomials = G.coefficient_matrix() monomials = vector(monomials) factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor) B = B.dense_matrix().LLL() B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor) H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots return []
#part1 get k,p3q3 e = 172005065945326769176157335849432320425605083524943730546805772515111751580759726759492349719668775270727323745284785341119685198468883978645793770975366048506237371435027612758232099414404389043740306443065413069994232238075194102578269859784981454218948784071599231415554297361219709787507633404217550013282713899284609273532223781487419770338416653260109238572639243087280632577902857385265070736208291583497988891353312351322545840742380550393294960815728021248513046077985900158814037534487146730483099151396746751774427787635287611736111679074330407715700153025952858666841328055071403960165321273972935204988906850585454805923440635864200149694398767776539993952528995717480620593326867245714074205285828967234591508039849777840636255379730281105670496110061909219669860172557450779495125345533232776767292561378244884362014224844319802810586344516400297830227894063759083198761120293919537342405893653545157892446163 n = 99075185389443078008327214328328747792385153883836599753096971412377366865826254033534293886034828804219037466246175526347014045811852531994537520303063113985486063022444972761276531422538694915030159420989401280012025249129111871649831185047820236417385693285461420040134313833571949090757635806658958193793
PR.<x,y> = PolynomialRing(Zmod(e)) f = 1 + x * (n^3 - y + 1) res = small_roots(f , bounds = (2^512,(2^512)^3) , m=7 , d=3) k = int(res[0][0]) p3q3 = int(res[0][1])
#part2 factor n p, q = var('p, q') res = solve([p*q == n, p^3 + q^3 == p3q3], p, q) #print(res) p = 9212046353930376594996890089494718736894378991991381248242532319628627449681664076081705664941905594411935750003102856235503684466394327681725704255564467 q = n // p assert p*q == n
#part3 get flag flag = "XYCTF{" + hashlib.md5(str(p + q).encode()).hexdigest() + "}" print(flag)
e = 65537 n = 942554394956393500634473023924044851150783066435925660508624376974971108656861080872622432250172571195245180102507380675343264066303507696268870722959770362631674931170602993210221083436437860191861911457384526742569208842886612504579678703976889217504241741044075116270718940025586448491942058697669033418724145042156461740336592337509609124425828725269151627786668070531098444935129266626770404736852607352075247856808563388127774523912002202264558855255067503 c = 91351185520045025851535940537599785616890151570421939971146348618267656786110090770321857244701820126026227283965934212135946431643320325513590505155214070540638751565105300361430272638957420276596026161454413739823593506516275224444666187442238624864548263927274591212614561916913851855552516864387460946267629794664216228596534684933791607740725160394841711539767932339281214673649553407414347293480522175832736301571839298158011533849603878482322619858083471 c1 = [6924229081976334180193477951417117275396656434968000032228908231511246053064833236257422745299036986875244562025221130619850904830372215788197314906896784,707045810464337488125013716300756405499020414540801863434513087687914538170573314824134496890600422837133767094273649381435979038909605432188919586751472,561487665739111774897165274560908487232457333748910467998343202097778699925650682704996443560224288857862513676706660506594465853704042586896087391214886,6498834369085375452441121562339384727357898216850540864190840194924515286757125433756518026123451611578553656133012172518080309106483207567929943790044792,5508345401684913940610183958526398635406187349043368834080838153611810896629693027245511688366776749176652858929409374912959736262162942801190344337268446,7604410082265211154108357446507297790451766698177313130672954202813796888988719242951127448112228332967892794819415211618572734294964346056056171483002307,7699815879242527638422887386550759485127768822609011364311314299885418068889791030639324882736871756700299169635780542149704586720216395186814592666988591,829748131720382599696653359722612708514830904084605048590882951300049701148883021283243506081300427041733299385325284399270633917941134488957784480285437,7084115400374950827522650500486495223539292992998875483730758098005030106055310282589342193536381973309924074043955222228738842206417828828756951777504457,7482796067314266426215648326036921955183807741134787613584977300821023398375789725848056657250086288687570875979072368004217788222537115232191230702833854] c2 = [12573984103581521249597169818949825744876735847170990673204303602848066091917704946653820386665801380026230957120354174481948164514637637956459534723582285, 6441954407109995413858792101472089558106780628459991101662507565699664222341697230094798036088532393057448200220905589679548875702178737462785403325555226, 11684244745641367106386196774447204674089853123966422387024948921795099192025069760680924547214190425118261001002764397184950251157744938735586522727499550, 10396243416373326695473843427139385116708652845789644861965876346553795313454773668473030130335970707089781482749749170266279229263892370064669233541305377, 9090748241360606371310281608818966855338110969397659720953951845805983771894064629343960530245792700858927510839835850767728294266738917884471006979663157, 11489848045104749332790333272128633885019156159805805159750174723808043569789257625027794186359921080743368220606914862583644262009648261345452266067697628, 649349258009900424806913260265314442160901414078390702088746248078789581041616487825633046538335114117254875547413590064940767523651802950986197978665018, 6302136940345077947382276151657194124073457559487274425879887978386901058162385833414602346299055653879087077862824771863209271498552774720708307840705334, 5844526398244645236473089500608731415060125566027525405618000580381149761653744142808567706048834618328671311836990498943019718294135733114642775270792763, 4834548043993868659061606699822957422840040425976833628462093089330507589865407793951971491111695171201542345470702059513427268037868859282999222070054388]
############################################# lcg1 PR.<a,b,x0> = PolynomialRing(ZZ) F = [a*x0 - c1[0]] for i inrange(9): f = a*c1[i] + b*(x0+sum(c1[:i])) - c1[i+1] F.append(f) res = Ideal(F).groebner_basis() p = ZZ(res[3].univariate_polynomial()(0))
############################################# lcg2 PR.<A,B,gx> = PolynomialRing(ZZ) F = [] for i inrange(1,10-1): f = (gx-c2[i])^2*(c2[i-1]+c2[i+1]) - 2*(gx^3+A*gx+B+c2[i]^3+A*c2[i]+B) + 2*(gx+c2[i])*(gx-c2[i])^2 F.append(f) res = Ideal(F).groebner_basis() q = ZZ(res[3].univariate_polynomial()(0))
############################################# decrypt r = n // p // q phi = (p-1)*(q-1)*(r-1) d = inverse(e,phi) print(long_to_bytes(int(pow(c,d,n))))
from Crypto.Util.number import * from hashlib import sha256
A = 1365855822212045061018261334821659180641576788523935479 B = 17329427219955161804703200105884322768704934833367341 p = 1365855822212045061018261334821659180641576788523935481
#part2 map to ECC F = GF(p) a = F(3-A^2) / F(3*B^2) b = F(2*A^3-9*A) / F(27*B^3)
m = bytes_to_long(pad(flag)) p = getStrongPrime(512) q = getStrongPrime(512) n = p * q e = 3 print(pow(m, e, n)) print(n) # 120440199294949712392334113337541924034371176306546446428347114627162894108760435789068328282135879182130546564535108930827440004987170619301799710272329673259390065147556073101312748104743572369383346039000998822862286001416166288971531241789864076857299162050026949096919395896174243383291126202796610039053 # 143413213355903851638663645270518081058249439863120739973910994223793329606595495141951165221740599158773181585002460087410975579141155680671886930801733174300593785562287068287654547100320094291092508723488470015821072834947151827362715749438612812148855627557719115676595686347541785037035334177162406305243
e = 3 c = 120440199294949712392334113337541924034371176306546446428347114627162894108760435789068328282135879182130546564535108930827440004987170619301799710272329673259390065147556073101312748104743572369383346039000998822862286001416166288971531241789864076857299162050026949096919395896174243383291126202796610039053 n = 143413213355903851638663645270518081058249439863120739973910994223793329606595495141951165221740599158773181585002460087410975579141155680671886930801733174300593785562287068287654547100320094291092508723488470015821072834947151827362715749438612812148855627557719115676595686347541785037035334177162406305243
PR.<x> = PolynomialRing(Zmod(n)) for length in trange(20,50): suffix = bytes_to_long(hash(str(length))) f = (256^32*x + suffix)^3 - c f = f.monic() res = f.small_roots(X=256^length,beta=1,epsilon=0.05) if(res != []): print(long_to_bytes(int(res[0]))) break
p = getStrongPrime(1024) q = getStrongPrime(1024) n = p * q e = 2 m = bytes_to_long(pad(flag)) print(pow(m, e, n)) print(n) # 3335299537518434350008670067273514020883265809787658909900831303201069228111667477512288715627313377374377192065531931991830331266940281529429758933125645068623703704431432931062515459304407129764836169638068667723468109909932687335727824459807903558617156661138991973933280805156893120951135488168923425258119689993859896540097318197048436676318334502053269738046279338047497258783747007084564814994803144049365117574904704816542523015746396519693505167963245600047742456478545640334467678554748227823020862550712083249012329745708139070338928730226897923885785783461594034339595106377701306570280371612953393097739 # 26278624299187148406559772770865336226934633734285979741424867540828670397865189685966828527168795621543490979182417570078991930822041468539855006585233692884235331084907340302530060261742100702658312435180527335101284800616106884692498603300926488358017928867672861988448488439356448543527810620591324774111321619391264173779312033252573140028630441135269056099074531502841259940379636699304810677716177080486265721322966814104627525953974143476452058638927511594884002185219080847495835727300670028011001853179659250270200020884333850083063514830095064730932997593930711871108436386821290545084229347398808220810263
from Crypto.Util.number import * import hashlib from tqdm import * import itertools
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree() R = f.base_ring() N = R.cardinality() f /= f.coefficients().pop(0) f = f.change_ring(ZZ) G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g) B, monomials = G.coefficient_matrix() monomials = vector(monomials) factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor) B = B.dense_matrix().LLL() B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor) H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots return []
c = 3335299537518434350008670067273514020883265809787658909900831303201069228111667477512288715627313377374377192065531931991830331266940281529429758933125645068623703704431432931062515459304407129764836169638068667723468109909932687335727824459807903558617156661138991973933280805156893120951135488168923425258119689993859896540097318197048436676318334502053269738046279338047497258783747007084564814994803144049365117574904704816542523015746396519693505167963245600047742456478545640334467678554748227823020862550712083249012329745708139070338928730226897923885785783461594034339595106377701306570280371612953393097739 n = 26278624299187148406559772770865336226934633734285979741424867540828670397865189685966828527168795621543490979182417570078991930822041468539855006585233692884235331084907340302530060261742100702658312435180527335101284800616106884692498603300926488358017928867672861988448488439356448543527810620591324774111321619391264173779312033252573140028630441135269056099074531502841259940379636699304810677716177080486265721322966814104627525953974143476452058638927511594884002185219080847495835727300670028011001853179659250270200020884333850083063514830095064730932997593930711871108436386821290545084229347398808220810263
head = bytes_to_long(b"XYCTF{") tail = bytes_to_long(b"}") PR.<x,y> = PolynomialRing(Zmod(n))
#len = 73 for length in trange(70,100): suffix = bytes_to_long(hash(str(length))) if(length % 2 == 0): f = (256^(128+length//2)*(256^(length//2-6)*head + x) + 256^(length//2)*suffix + 256*y + tail)^2 - c bounds = (256^(length//2-6),256^(length//2-1)) res = small_roots(f,bounds,1,4) if(res != []): print(res) break else: f = (256^(128+length//2+1)*(256^(length//2-6)*head + x) + 256^(length//2+1)*suffix + 256*y + tail)^2 - c bounds = (256^(length//2-6),256^(length//2)) res = small_roots(f,bounds,1,4) if(res != []): print(res) break
p = 183640370379099520304414468793633666661 a = 36108041497607074474855679331694767924 b = 65925932211985158779695144876342622462 out = [34, 95, 100, 114, 16, 23, 17, 118, 115, 29, 73, 47, 12, 133, 78, 30, 30, 73, 87, 15, 85, 47, 20, 136, 6, 106, 74, 27, 116, 8] c = 6003642257316152022364486167163125577018867662610595926973616937741281227891381713617380
nums = 30 L = Matrix(ZZ,2*nums,2*nums) for i inrange(nums-1): L[i,i] = 1 L[i,nums+1+i] = -a L[i+1,nums+1+i] = 1 L[nums,nums+1+i] = 2^120*out[i+1] - 2^120*a*out[i] - b L[nums+1+i,nums+1+i] = p L[nums-1,nums-1] = 1 L[nums,nums] = 2^120
L[:,nums+1:] *= p res = L.LLL()[0]
x = 2^120*out[-1] + abs(res[nums-1]) key = "" for i inrange(100): x = (a*x + b) % p key += str(x >> 120) flag = long_to_bytes(int(key) ^^ c) if(b"XYCTF"in flag): print(flag) break
#XYCTF{2h1_21_ZHi_5h0u_yU_zI_xI3_l@0}
happy_to_solve1
题目描述:
1
so happy
题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from Crypto.Util.number import * import sympy from secrets import flag
m = bytes_to_long(flag) p, q = get_happy_prime() n = p * q e = 65537 print(n) print(pow(m, e, n)) # 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 # 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287
from Crypto.Util.number import * from tqdm import *
n = 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c = 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287 e = 65537
PR.<x> = PolynomialRing(ZZ) for t in trange(2000): f = x*(2^512 - x + t) - n res = f.roots() if(res != []): p = int(res[0][0]) q = n // p print(long_to_bytes(pow(c,inverse(e,(p-1)*(q-1)),n))) break
if(pmin*qmin > n or pmax*qmax < n): return if(length == 502): for i inrange(2**10): pp = int(p + bin(i)[2:].zfill(10),2) if(n % pp == 0): qq = n // pp print(long_to_bytes(pow(c,inverse(e,(pp-1)*(qq-1)),n))) exit() find(p+"0" , q+"1" , length+1) find(p+"1" , q+"0" , length+1)
n = 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c = 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287 e = 65537
import random from Crypto.Util.number import * from secrets import flag
defget_happy_prime(): while1: p = int("".join([random.choice("123") for _ inrange(512)])) q = int("".join([random.choice("567") for _ inrange(512)])) if isPrime(p) and isPrime(q): return (p,q)
m = bytes_to_long(flag) p ,q= get_happy_prime() n = p * q e = 65537 print(n) print(pow(m, e, n)) # 697906506747097082736076931509594586899561519277373830451275402914416296858960649459482027106166486723487162428522597262774248272216088755005277069446993003521270487750989061229071167729138628583207229945902389632065500739730301375338674342457656803764567184544685006193130563116558641331897204457729877920989968662546183628637193220770495938729301979912328865798266631957128761871326655572836258178871966196973138373358029531478246243442559418904559585334351259080578222274926069834941166567112522869638854253933559832822899069320370733424453856240903784235604251466010104012061821038897933884352804297256364409157501116832788696434711523621632436970698827611375698724661553712549209133526623456888111161142213830821361143023186927163314212097199831985368310770663850851571934739809387798422381702174820982531508641022827776262236373967579266271031713520262606203067411268482553539580686495739014567368858613520107678565628269250835478345171330669316220473129104495659093134763261751546990704365966783697780787341963138501 # 153383826085102296581238539677668696644156148059026868813759015106139131297135097831661048493079405226972222492151356105759235749502324303047037349410709021152255315429280760639113724345836532087970918453353723090554450581657930847674930226113840172368662838756446364482977092478979838209396761279326533419699056209983721842484996150025403009644653678928025861445324715419893797015875541525590135843027312322236085581571452084477262582966972702577136904385741443870527205640874446616413917231260133364227248928492574610248881137364204914001412269740461851747883355414968499272944590071623223603501698004227753335552646715567802825755799597955409228004284739743749531270833084850113574712041224896044525292591264637452797151098802604186311724597450780520140413704697374209653369969451501627583467893160412780732575085846467289134920886789952338174193202234175299652687560232593212131693456966318670843605238958724126368185289703563591477049105538528244632434869965333722691837462591128379816582723367039674028619947057144546
from Crypto.Util.number import * from itertools import *
e = 65537 n = 697906506747097082736076931509594586899561519277373830451275402914416296858960649459482027106166486723487162428522597262774248272216088755005277069446993003521270487750989061229071167729138628583207229945902389632065500739730301375338674342457656803764567184544685006193130563116558641331897204457729877920989968662546183628637193220770495938729301979912328865798266631957128761871326655572836258178871966196973138373358029531478246243442559418904559585334351259080578222274926069834941166567112522869638854253933559832822899069320370733424453856240903784235604251466010104012061821038897933884352804297256364409157501116832788696434711523621632436970698827611375698724661553712549209133526623456888111161142213830821361143023186927163314212097199831985368310770663850851571934739809387798422381702174820982531508641022827776262236373967579266271031713520262606203067411268482553539580686495739014567368858613520107678565628269250835478345171330669316220473129104495659093134763261751546990704365966783697780787341963138501 c = 153383826085102296581238539677668696644156148059026868813759015106139131297135097831661048493079405226972222492151356105759235749502324303047037349410709021152255315429280760639113724345836532087970918453353723090554450581657930847674930226113840172368662838756446364482977092478979838209396761279326533419699056209983721842484996150025403009644653678928025861445324715419893797015875541525590135843027312322236085581571452084477262582966972702577136904385741443870527205640874446616413917231260133364227248928492574610248881137364204914001412269740461851747883355414968499272944590071623223603501698004227753335552646715567802825755799597955409228004284739743749531270833084850113574712041224896044525292591264637452797151098802604186311724597450780520140413704697374209653369969451501627583467893160412780732575085846467289134920886789952338174193202234175299652687560232593212131693456966318670843605238958724126368185289703563591477049105538528244632434869965333722691837462591128379816582723367039674028619947057144546
deffind(ph,qh): if(len(ph) == 512): p = int(ph) q = n // p if(p*q == n): d = inverse(e,(p-1)*(q-1)) print(long_to_bytes(pow(c,d,n))) exit() pmin = int(ph + (512-len(ph))*"1") qmin = int(qh + (512-len(qh))*"5") pmax = int(ph + (512-len(ph))*"3") qmax = int(qh + (512-len(qh))*"7")
if(pmin*qmin <= n and pmax*qmax >=n): for i in ("1","2","3"): for j in ("5","6","7"): find(ph+i,qh+j)
defget_happy_prime(): p = getPrime(n // 2) q = getPrime(n // 2) N = p * q if2 * q - p > gmpy2.iroot(N, 3)[0] and2 * q - p < int(N**gamma / 16): d = random.randint(int(N ** (delta - 0.001)), int(N**delta)) e = gmpy2.invert(d, (p - 1) * (q - 1)) return N, e
N, e = get_happy_prime() m = bytes_to_long(flag) print(N) print(e) print(pow(m, e, N)) # 262520792590557046276663232446026434827811478251833823563978322470880473096166170973396967071440576532100045206129176936699321058518888771220060450723297988984995658582283884954240129867538637146924315603797818982078845855992582229939200744016516540207525916858674450616913948112117516831530578235916528257187 # 202935305174706906986376186864051444100197589482194720650385604617995167023220940138899902073948844285283834058445151666398192104922822110762965750590312021079147170573038600118139119881722125346545331027913695559130179278058419339157557267195396326664433859683010193688491694572425231599139974726246205888139 # 66173406204647583141174847814283540389326401056490970592017577810775087017197392456634167609680060931553017712058528056769618111925816921272571306246667527546366331057781905353553621522209713637253380859235235590286779517552635935384231694255450099095196595516174794966487058693308544109311774074970769293357
题目基于RSA分解,其参数特殊性在于:
p和2q的差距是个350bit左右的小量
d仅有333bit左右,达到了N^0.324
所以应该是要完成诸如boneh and durfee之类的低解密指数攻击,但是d并不在0.292的理论上界之内,因此要想办法利用上第一个条件。
""" Setting debug to true will display more informations about the lattice, the bounds, the vectors... """ debug = False
""" Setting strict to true will stop the algorithm (and return (-1, -1)) if we don't have a correct upperbound on the determinant. Note that this doesn't necesseraly mean that no solutions will be found since the theoretical upperbound is usualy far away from actual results. That is why you should probably use `strict = False` """ strict = False
""" This is experimental, but has provided remarkable results so far. It tries to reduce the lattice as much as it can while keeping its efficiency. I see no reason not to use this option, but if things don't work, you should try disabling it """ helpful_only = True dimension_min = 7# stop removing if lattice reaches that dimension
# display stats on helpful vectors defhelpful_vectors(BB, modulus): nothelpful = 0 for ii inrange(BB.dimensions()[0]): if BB[ii,ii] >= modulus: nothelpful += 1
print (nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
# display matrix picture with 0 and X defmatrix_overview(BB, bound): for ii inrange(BB.dimensions()[0]): a = ('%02d ' % ii) for jj inrange(BB.dimensions()[1]): a += '0'if BB[ii,jj] == 0else'X' if BB.dimensions()[0] < 60: a += ' ' if BB[ii, ii] >= bound: a += '~' print (a)
# tries to remove unhelpful vectors # we start at current = n-1 (last vector) defremove_unhelpful(BB, monomials, bound, current): # end of our recursive function if current == -1or BB.dimensions()[0] <= dimension_min: return BB
# we start by checking from the end for ii inrange(current, -1, -1): # if it is unhelpful: if BB[ii, ii] >= bound: affected_vectors = 0 affected_vector_index = 0 # let's check if it affects other vectors for jj inrange(ii + 1, BB.dimensions()[0]): # if another vector is affected: # we increase the count if BB[jj, ii] != 0: affected_vectors += 1 affected_vector_index = jj
# level:0 # if no other vectors end up affected # we remove it if affected_vectors == 0: print ("* removing unhelpful vector", ii) BB = BB.delete_columns([ii]) BB = BB.delete_rows([ii]) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii-1) return BB
# level:1 # if just one was affected we check # if it is affecting someone else elif affected_vectors == 1: affected_deeper = True for kk inrange(affected_vector_index + 1, BB.dimensions()[0]): # if it is affecting even one vector # we give up on this one if BB[kk, affected_vector_index] != 0: affected_deeper = False # remove both it if no other vector was affected and # this helpful vector is not helpful enough # compared to our unhelpful one if affected_deeper andabs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]): print ("* removing unhelpful vectors", ii, "and", affected_vector_index) BB = BB.delete_columns([affected_vector_index, ii]) BB = BB.delete_rows([affected_vector_index, ii]) monomials.pop(affected_vector_index) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii-1) return BB # nothing happened return BB
""" Returns: * 0,0 if it fails * -1,-1 if `strict=true`, and determinant doesn't bound * x0,y0 the solutions of `pol` """ defboneh_durfee(pol, modulus, mm, tt, XX, YY): """ Boneh and Durfee revisited by Herrmann and May finds a solution if: * d < N^delta * |x| < e^delta * |y| < e^0.5 whenever delta < 1 - sqrt(2)/2 ~ 0.292 """
# x-shifts gg = [] for kk inrange(mm + 1): for ii inrange(mm - kk + 1): xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk gg.append(xshift) gg.sort()
# x-shifts list of monomials monomials = [] for polynomial in gg: for monomial in polynomial.monomials(): if monomial notin monomials: monomials.append(monomial) monomials.sort() # y-shifts (selected by Herrman and May) for jj inrange(1, tt + 1): for kk inrange(floor(mm/tt) * jj, mm + 1): yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk) yshift = Q(yshift).lift() gg.append(yshift) # substitution # y-shifts list of monomials for jj inrange(1, tt + 1): for kk inrange(floor(mm/tt) * jj, mm + 1): monomials.append(u^kk * y^jj)
# construct lattice B nn = len(monomials) BB = Matrix(ZZ, nn) for ii inrange(nn): BB[ii, 0] = gg[ii](0, 0, 0) for jj inrange(1, ii + 1): if monomials[jj] in gg[ii].monomials(): BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)
# Prototype to reduce the lattice if helpful_only: # automatically remove BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1) # reset dimension nn = BB.dimensions()[0] if nn == 0: print ("failure") return0,0
# check if vectors are helpful if debug: helpful_vectors(BB, modulus^mm) # check if determinant is correctly bounded det = BB.det() bound = modulus^(mm*nn) if det >= bound: print ("We do not have det < bound. Solutions might not be found.") print ("Try with highers m and t.") if debug: diff = (log(det) - log(bound)) / log(2) print ("size det(L) - size e^(m*n) = ", floor(diff)) if strict: return -1, -1 else: print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
# display the lattice basis if debug: matrix_overview(BB, modulus^mm)
# LLL if debug: print ("optimizing basis of the lattice via LLL, this can take a long time")
BB = BB.LLL()
if debug: print ("LLL is done!")
# transform vector i & j -> polynomials 1 & 2 if debug: print ("looking for independent vectors in the lattice") found_polynomials = False for pol1_idx inrange(nn - 1): for pol2_idx inrange(pol1_idx + 1, nn): # for i and j, create the two polynomials PR.<w,z> = PolynomialRing(ZZ) pol1 = pol2 = 0 for jj inrange(nn): pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY) pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)
# are these good polynomials? if rr.is_zero() or rr.monomials() == [1]: continue else: print ("found them, using vectors", pol1_idx, "and", pol2_idx) found_polynomials = True break if found_polynomials: break
ifnot found_polynomials: print ("no independant vectors could be found. This should very rarely happen...") return0, 0 rr = rr(q, q)
# solutions soly = rr.roots()
iflen(soly) == 0: print ("Your prediction (delta) is too small") return0, 0
soly = soly[0][0] ss = pol1(q, soly) solx = ss.roots()[0][0]
# return solx, soly
nbit = 1024 n = 262520792590557046276663232446026434827811478251833823563978322470880473096166170973396967071440576532100045206129176936699321058518888771220060450723297988984995658582283884954240129867538637146924315603797818982078845855992582229939200744016516540207525916858674450616913948112117516831530578235916528257187 e = 202935305174706906986376186864051444100197589482194720650385604617995167023220940138899902073948844285283834058445151666398192104922822110762965750590312021079147170573038600118139119881722125346545331027913695559130179278058419339157557267195396326664433859683010193688491694572425231599139974726246205888139 c = 66173406204647583141174847814283540389326401056490970592017577810775087017197392456634167609680060931553017712058528056769618111925816921272571306246667527546366331057781905353553621522209713637253380859235235590286779517552635935384231694255450099095196595516174794966487058693308544109311774074970769293357
#part1 boneh and durfee to get d if(1): m = 3 delta = 0.33 t = int((1-2*delta) * m) # optimization from Herrmann and May X = 2*floor(n^delta) # this _might_ be too much Y = 2^360# correct if p, q are ~ same size
A = (n+1)//2 - (ph+qh)//2 PR.<x,y> = PolynomialRing(ZZ) f = 1+x*(A+y) res = boneh_durfee(f, e, m, t, X, Y) print(res)
#part2 get d res = (11905625603785812461702294975756895543980946484478574101835243414442286593759448613358049647316155274, 152665725363549086276160040606397627101715395584023352342706962320368673856094243978666140464721353176202314) k2 = 11905625603785812461702294975756895543980946484478574101835243414442286593759448613358049647316155274 pl_ql = 152665725363549086276160040606397627101715395584023352342706962320368673856094243978666140464721353176202314 d = (1+k2*(A+pl_ql)) // e print(len(bin(d))) print(long_to_bytes(int(pow(c,d,n))))
X = [] Y = [] for line inopen(r'D:\CTF_challs\py\crypto\2024\XYCTF 2024\encoded.txt', 'r').read().strip().split('\n'): x, y = line.split(' ') X.append(int(x)) Y.append(int(y))
K = GF(p) R = PolynomialRing(K, 'x')
defcompZ(X): x = R.gen() Z = K(1) for xk in X: Z *= (x-xk) return Z
defcomp(X, Y, Xother): Z = compZ(Xother) Y = [y/Z(x) for x, y inzip(X, Y)] return Y, Z
defsolve(X, Y): n = len(Y) print("Solving for", n, "points...")
# just use lagrange interpolation if the degree is small enough if n <= 10: return R.lagrange_polynomial(list(zip(X, Y)))
# parallelize the computation of the two halves if nhalf > 10000: with mp.Pool(2) as pool: result1 = pool.apply_async(comp, (X1, Y1, X2)) result2 = pool.apply_async(comp, (X2, Y2, X1))
from random import randint flag=b'XYCTF{uuid}' flag = bytes_to_long(flag) n = 472993274721871037103726599805149366727531552333249750035977291933239067588481589544777397613192273114354221827196579379954069925604091911249655707080927769808587176515295614018992848517984372306879552247519117116110554431341268358177159108949791969262793325836353834899335531293329721598226413212541536002401507477776699642647348576111445702197483449777741566350285229621935507081895389023444249054515395783080003733803406382744631528246608154546123270319561514117323480441428953306734274538511770278887429407127143049023747710881993279361892937905382946820141513009017756811296722630617325141162244806884220212939955235410280899112731530527048274396186038160728562551536558223235783656985493518204710943916486379681906506757757594165379493317173050550893487151879681122510523721157284728808336110950008840684602353984682117748018347433177541603140491131603068512706893984834735290809952944273565203183330739252949245209529232254867201402656024997949207918675051941911990640248052951780195402390132237903538546705181463959793972284823588987652138458328270662652334799233015314673544813649692428544375538627858921763941533600553536579901589575693816746953261108022490849251974419402753031545629158199093099096735356165044275617408697 rr = 11898141078345200236264081467585899457224809417108457314508072413792599039332439547789237898270544336909458761754683941320649771736625000667170176071314483 defgenerate(): fw = open("random", "w") for i inrange(648): fw.write(str(random.getrandbits(32))+"\n") fw.close() generate() key = str(random.getrandbits(32)) key1= int(str(key)[0]) ks = [randint(0, rr**(i+key1-1)) for i inrange(16)] c1 = pow(sum(k*flag**i for i, k inenumerate(ks)), 127, n) c2 = pow(flag, 65537, n) ks = [pow(69, k+key, rr**(i+key1)) for i, k inenumerate(ks)] print(f"{ks = }") print(f"{c1 = }") print(f"{c2 = }")
defcomplex_pow(c, exp, n): result = Complex(1, 0) while exp > 0: if exp & 1: result = result * c result.re = result.re % n result.im = result.im % n c = c * c c.re = c.re % n c.im = c.im % n exp >>= 1 return result
flag = flag.strip(b"XYCTF{").strip(b"}") p = 1127236854942215744482170859284245684922507818478439319428888584898927520579579027 g = Complex(3, 7) x = bytes_to_long(flag) print(complex_pow(g, x, p)) # 5699996596230726507553778181714315375600519769517892864468100565238657988087817 + 198037503897625840198829901785272602849546728822078622977599179234202360717671908i
g = F(3 + 7*i) c = F(5699996596230726507553778181714315375600519769517892864468100565238657988087817 + 198037503897625840198829901785272602849546728822078622977599179234202360717671908*i)
m = discrete_log(F(c^(p+1)) , F(g^(p+1)) , operation="*" , ord=p-1) print(long_to_bytes(int(m)))
input_str = leak result = swap_bits(input_str) a=result
defcustom_add(input_str): input_list = list(input_str) length = len(input_list) for i inrange(length): input_list[i] = str((int(input_list[i]) + i + 1) % 10)
result = ''.join(input_list) return result
input_str = a result = custom_add(input_str) b=result print(b) #12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891134567799012455779902334677900124556899012356679001344567990233457780113445788911245667991134457799122355788001245578890223467799013445688902335578800123457889113346778902344567991223557880013355689911245667900124556789122355788001234678891133467799023445679902334568900123556899012456679001344578801233467789112355779912234577990233556780113
from Crypto.Util.number import * from tqdm import *
b = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891134567799012455779902334677900124556899012356679001344567990233457780113445788911245667991134457799122355788001245578890223467799013445688902335578800123457889113346778902344567991223557880013355689911245667900124556789122355788001234678891133467799023445679902334568900123556899012456679001344578801233467789112355779912234577990233556780113 c = list(map(int,str(b)))
#part1 reverse custom for i inrange(len(c)): c[i] = (c[i] - 1 - i) % 10
#part2 recover swap for i inrange(len(c)//2): temp = c[i] c[i] = c[511-i] c[511-i] = temp
#part3 get flag flag = "0" + "".join(list(map(str,c)))[:-1] print(long_to_bytes(int(flag,2)))
from Crypto.Util.number import * from gmpy2 import * from random import choice
flag = b'XYCTF{******}' e = '?' defgetBabyPrime(nbits): whileTrue: p = 1 while p.bit_length() <= nbits: p *= choice(sieve_base) if isPrime(p+1): return p+1
p = getBabyPrime(512) q = getBabyPrime(512) n = p*q gift1 = (pow(p,e,n)-pow(q,e,n)) % n gift2 = pow(p+q,e,n)
n = 39332423872740210783246069030855946244104982381157166843977599780233911183158560901377359925435092326653303964261550158658551518626014048783435245471536959844874036516931542444719549997971482644905523459407775392702211086149279473784796202020281909706723380472571862792003687423791576530085747716706475220532321 gift1 = 4549402444746338327349007235818187793950285105091726167573552412678416759694660166956782755631447271662108564084382098562999950228708300902201571583419116299932264478381197034402338481872937576172197202519770782458343606060544694608852844228400457232100904217062914047342663534138668490328400022651816597367310 gift2 = 111061215998959709920736448050860427855012026815376672067601244053580566359594802604251992986382187891022583247997994146019970445247509119719411310760491983876636264003942870756402328634092146799825005835867245563420135253048223898334460067523975023732153230791136870324302259127159852763634051238811969161011462 c = 16938927825234407267026017561045490265698491840814929432152839745035946118743714566623315033802681009017695526374397370343984360997903165842591414203197184946588470355728984912522040744691974819630118163976259246941579063687857994193309554129816268931672391946592680578681270693589911021465752454315629283033043 y = 1813650001270967709841306491297716908969425248888510985109381881270362755031385564927869313112540534780853966341044526856705589020295048473305762088786992446350060024881117741041260391405962817182674421715239197211274668450947666394594121764333794138308442124114744892164155894256326961605137479286082964520217
#part1 factor n(p-1 smooth) a = 2 m = 2 whileTrue: a = pow(a, m, n) p = GCD(a-1, n) if p != 1and p != n: break m += 1 q = n // p phi = (p-1)*(q-1)
#part2 get e e = pow(y,inverse(65537,phi),n) #print(long_to_bytes(e)) e = 4096
#part3 get flag res = Zmod(p)(c).nth_root(e, all=True) for i in res: temp = long_to_bytes(int(i)) if(b"XYCTF"in temp): print(temp)
from Crypto.Util.number import * from tqdm import * import itertools
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality() k = ZZ(f.coefficients().pop(0)) g = gcd(k, N) k = R(k/g)
f *= 1/k f = f.change_ring(ZZ)
vars = f.variables() G = Sequence([], f.parent()) for k inrange(m): for i inrange(m-k+1): for subvars in itertools.combinations_with_replacement(vars[1:], i): g = f**k * prod(subvars) * N**(max(d-k, 0)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL() B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, Integer(1)/factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B*monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots
from Crypto.Util.number import * from gmpy2 import * import itertools
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots
return []
n = 913125842482770239379848062277162627509794409924607555622246822717218133091223291889541294440266178282194506242444509803611492259403578922020590849630191477864719052980160940803309686069818208833547621252544423652489179493083138385424424384165228024273745733240109761707533778691158938848158094054261174692601673435971526522219273943464877956131040249169850420336023942653021547841666224446678539579529590840999008107782784268926145671962239929431694391039559247 e = 494518390582436635999115147756676313570637682518235195828939117782099618734167908630788943568232122157772909140885391963441876427590731524706959546524212914108888799081844320513851526790475333924396837458796755678072486028072639014677580265244176441153444956871730684233063789931539669072735599696830757690822185323538738397827461580678488181113667710378657058297572328491762536595872579603698945272140918157163640403488075948987156585480146162739943419183496337465468187233821931312507662218106713861638334075899266373256620752680354704533272722692596941861606161634082613228896420520465402725359166156632884432690715903666803067996854084671477445131853993177110154928274312496230096270510089973592664248613332000290545537840595645944390047611474888693558676781309912289044962293014118087259307560444929227407113819165713213046898243995956550944640168932947118400215917515277554126694376415569909534496134700668701465649939 c = 4450931337369461482106945992542133557585962894030505065110870389112565329875502952762182372926117037373210509516570958483606566274369840551132381128665744266165792377925899683228751870742727716
PR.<x,y>=PolynomialRing(Zmod(e)) f = 1 + x*(n^2-n+1 + (n+1)*y + y^2) res = small_roots(f, (2^320,2^769), m=2, d=3)
pplusq = int(res[0][1]) pminusq = iroot(pplusq^2-4*n,2)[0] p = (pplusq + pminusq) // 2 q = n // p
d = inverse(e,(p^2+p+1)*(q^2+q+1)) print(long_to_bytes(d^2 ^^ c))