# sage: e = ... pq = ... pqx = pq ^ 3 fra = (e/pqx).continued_fraction() for i inrange(1, len(fra)): k, d = fra.numerator(i), fra.denominator(i) if (e*d - 1) % k == 0and d > 2^250: break
temp = (e*d - 1) // k pq3 = pqx - temp + 1 x = PolynomialRing(RationalField(), 'x').gen() f = x^3-3*pq*x-pq3 p_q = int(f.roots()[0][0])
from Crypto.Util.number import * from gmpy2 import iroot import hashlib
flag = "XYCTF{" + hashlib.md5(str(p_q).encode()).hexdigest() + "}" print(flag)
debug = True strict = False helpful_only = True dimension_min = 7# stop removing if lattice reaches that dimension
############################################ # Functions ########################################## # 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")
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)
defremove_unhelpful(BB, monomials, bound, current): if current == -1or BB.dimensions()[0] <= dimension_min: return BB
for ii inrange(current, -1, -1): 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 BB[jj, ii] != 0: affected_vectors += 1 affected_vector_index = jj
defattack(N, e, m, t, X, Y): modulus = e PR.<x, y> = PolynomialRing(ZZ) a = N + 1 b = N * N - N + 1 f = x * (y * y + a * y + b) + 1 gg = []
for k inrange(0, m+1): for i inrange(k, m+1): for j inrange(2 * k, 2 * k + 2): gg.append(x^(i-k) * y^(j-2*k) * f^k * e^(m - k)) for k inrange(0, m+1): for i inrange(k, k+1): for j inrange(2*k+2, 2*i+t+1): gg.append(x^(i-k) * y^(j-2*k) * f^k * e^(m - k))
deforder_gg(idx, gg, monomials): if idx == len(gg): return gg, monomials for i inrange(idx, len(gg)): polynomial = gg[i] non = [] for monomial in polynomial.monomials(): if monomial notin monomials: non.append(monomial) iflen(non) == 1: new_gg = gg[:] new_gg[i], new_gg[idx] = new_gg[idx], new_gg[i] return order_gg(idx + 1, new_gg, monomials + non) gg, monomials = order_gg(0, gg, [])
nn = len(monomials) BB = Matrix(ZZ, nn) for ii inrange(nn): BB[ii, 0] = gg[ii](0, 0) for jj inrange(1, nn): if monomials[jj] in gg[ii].monomials(): BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](X, Y)
if helpful_only: # automatically remove BB = remove_unhelpful(BB, monomials, modulus^m, nn-1) # reset dimension nn = BB.dimensions()[0] if nn == 0: print("failure") return0,0
if debug: helpful_vectors(BB, modulus^m) # check if determinant is correctly bounded det = BB.det() bound = modulus^(m*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)")
if debug: matrix_overview(BB, modulus^m) 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!") if debug: print("looking for independent vectors in the lattice")
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 definthroot(a, n): return a.nth_root(n, truncate_mode=True)[0] N = 913125842482770239379848062277162627509794409924607555622246822717218133091223291889541294440266178282194506242444509803611492259403578922020590849630191477864719052980160940803309686069818208833547621252544423652489179493083138385424424384165228024273745733240109761707533778691158938848158094054261174692601673435971526522219273943464877956131040249169850420336023942653021547841666224446678539579529590840999008107782784268926145671962239929431694391039559247
e = 494518390582436635999115147756676313570637682518235195828939117782099618734167908630788943568232122157772909140885391963441876427590731524706959546524212914108888799081844320513851526790475333924396837458796755678072486028072639014677580265244176441153444956871730684233063789931539669072735599696830757690822185323538738397827461580678488181113667710378657058297572328491762536595872579603698945272140918157163640403488075948987156585480146162739943419183496337465468187233821931312507662218106713861638334075899266373256620752680354704533272722692596941861606161634082613228896420520465402725359166156632884432690715903666803067996854084671477445131853993177110154928274312496230096270510089973592664248613332000290545537840595645944390047611474888693558676781309912289044962293014118087259307560444929227407113819165713213046898243995956550944640168932947118400215917515277554126694376415569909534496134700668701465649939
X = 1 << 469
Y = 2 * inthroot(Integer(2 * N), 2)
res = attack(N, e, 4, 2, X, Y)
print(res)
b, c = res[1], N
Dsqrt = inthroot(Integer(b^2-4*c),2)
p, q = (b + Dsqrt) // 2, (b - Dsqrt) // 2
assert p * q == N print(p) print(q)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import gmpy2 from Crypto.Util.number import * p = 1079692686288325812308630934214667048073665141240195252583556389192093937087035206847129125872559936616225942097278411602071282941911673739879515157769270737229378250560113256396308250699296075273110248314981762673299506406938725953 q = 845727542734252771097508620366884787581346823455578404917525769041539439746914530374958818236462967773717478357930648479282951655380705183747821800053493097745787392338644671787997907165214166274630065657567039034950440073852768399 c = 4450931337369461482106945992542133557585962894030505065110870389112565329875502952762182372926117037373210509516570958483606566274369840551132381128665744266165792377925899683228751870742727716 N = p * q phi = (p ** 2 + p + 1) * (q ** 2 + q + 1) e = 494518390582436635999115147756676313570637682518235195828939117782099618734167908630788943568232122157772909140885391963441876427590731524706959546524212914108888799081844320513851526790475333924396837458796755678072486028072639014677580265244176441153444956871730684233063789931539669072735599696830757690822185323538738397827461580678488181113667710378657058297572328491762536595872579603698945272140918157163640403488075948987156585480146162739943419183496337465468187233821931312507662218106713861638334075899266373256620752680354704533272722692596941861606161634082613228896420520465402725359166156632884432690715903666803067996854084671477445131853993177110154928274312496230096270510089973592664248613332000290545537840595645944390047611474888693558676781309912289044962293014118087259307560444929227407113819165713213046898243995956550944640168932947118400215917515277554126694376415569909534496134700668701465649939
d = gmpy2.invert(e, phi) m = d**2^c print(long_to_bytes(m))
n = 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879 c = 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287
import gmpy2 from Crypto.Util.number import * e=65537 t1=1<<1024 p=(2**512+gmpy2.iroot((2**1024-4*n,2)[0])//2 p=int(p) while n%p!=0: p=gmpy2.next_prime(p) q=n//p phi=(p-1)*(q-1) d=gmpy2.invert(e,phi) m=pow(c,d,n) print(long_to_bytes(m))
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))
import gmpy2 from itertools import product from Crypto.Util.number import long_to_bytes
n = 697906506747097082736076931509594586899561519277373830451275402914416296858960649459482027106166486723487162428522597262774248272216088755005277069446993003521270487750989061229071167729138628583207229945902389632065500739730301375338674342457656803764567184544685006193130563116558641331897204457729877920989968662546183628637193220770495938729301979912328865798266631957128761871326655572836258178871966196973138373358029531478246243442559418904559585334351259080578222274926069834941166567112522869638854253933559832822899069320370733424453856240903784235604251466010104012061821038897933884352804297256364409157501116832788696434711523621632436970698827611375698724661553712549209133526623456888111161142213830821361143023186927163314212097199831985368310770663850851571934739809387798422381702174820982531508641022827776262236373967579266271031713520262606203067411268482553539580686495739014567368858613520107678565628269250835478345171330669316220473129104495659093134763261751546990704365966783697780787341963138501 c = 153383826085102296581238539677668696644156148059026868813759015106139131297135097831661048493079405226972222492151356105759235749502324303047037349410709021152255315429280760639113724345836532087970918453353723090554450581657930847674930226113840172368662838756446364482977092478979838209396761279326533419699056209983721842484996150025403009644653678928025861445324715419893797015875541525590135843027312322236085581571452084477262582966972702577136904385741443870527205640874446616413917231260133364227248928492574610248881137364204914001412269740461851747883355414968499272944590071623223603501698004227753335552646715567802825755799597955409228004284739743749531270833084850113574712041224896044525292591264637452797151098802604186311724597450780520140413704697374209653369969451501627583467893160412780732575085846467289134920886789952338174193202234175299652687560232593212131693456966318670843605238958724126368185289703563591477049105538528244632434869965333722691837462591128379816582723367039674028619947057144546 e = 65537
defbase10(ss): r = 0 for x in ss[::-1]: r = r * 10 + x return r
defdfs(ps, qs, mod): if base10(ps) * base10(qs) == n: yield base10(ps), base10(qs) return for pp, qq in product((1, 2, 3), (5, 6, 7)): p = base10(ps + [pp]) q = base10(qs + [qq]) if p * q % mod == n % mod: yieldfrom dfs(ps + [pp], qs + [qq], mod * 10)
b = 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891134567789113445678012235677900133457889012456679901245577801223567790012355788911245667890134456789122355788001245578891223566790113445778902335578800123457889122346778011344567991223557880012346788912335667991134457789122355788001244578891223467799012455688912234667900133557889022356678901344578801233467789112355779912234577990233556780113 b = str(b) print(b)
from Crypto.Util.number import *
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[[扩展维纳攻击]]
from Crypto.Util.number import * from gmpy2 import * from random import choice
n = 39332423872740210783246069030855946244104982381157166843977599780233911183158560901377359925435092326653303964261550158658551518626014048783435245471536959844874036516931542444719549997971482644905523459407775392702211086149279473784796202020281909706723380472571862792003687423791576530085747716706475220532321 g1 = 4549402444746338327349007235818187793950285105091726167573552412678416759694660166956782755631447271662108564084382098562999950228708300902201571583419116299932264478381197034402338481872937576172197202519770782458343606060544694608852844228400457232100904217062914047342663534138668490328400022651816597367310 g2 = 111061215998959709920736448050860427855012026815376672067601244053580566359594802604251992986382187891022583247997994146019970445247509119719411310760491983876636264003942870756402328634092146799825005835867245563420135253048223898334460067523975023732153230791136870324302259127159852763634051238811969161011462 c = 16938927825234407267026017561045490265698491840814929432152839745035946118743714566623315033802681009017695526374397370343984360997903165842591414203197184946588470355728984912522040744691974819630118163976259246941579063687857994193309554129816268931672391946592680578681270693589911021465752454315629283033043 y = 1813650001270967709841306491297716908969425248888510985109381881270362755031385564927869313112540534780853966341044526856705589020295048473305762088786992446350060024881117741041260391405962817182674421715239197211274668450947666394594121764333794138308442124114744892164155894256326961605137479286082964520217
pe = ((g1+g2)//2)%n qe = ((g2-g1)//2)%n p = gmpy2.gcd(pe,n) q = gmpy2.gcd(qe,n) print(p,q) print(p*q==n) phi=(p-1)*(q-1) t = 65537 x = pow(y,gmpy2.invert(t,phi),n) e = x
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 = }")
其次,如果对于某个整数幂$s \geq 1$,存在解$a^{x} \equiv b \pmod{p^s}$,那么解也存在于$p^{s-1}$ 中,一直回溯到 ( p ),也就是 $a^{x} \equiv b \pmod{p^s}⟹a^{x} \equiv b \pmod{p^{s-1}}⟹…⟹a^{x} \equiv b \pmod{p}$
Eric Bach(1984年)提出了一个类似于多项式的 Hensel 提升算法的算法,用于在上述同余方程链中向后推进。他的目的是比较对于一般模数$n$求解离散对数问题和因数分解问题的难度,所以这里我们只关注他的工作的一部分。
out.insert(0,0) for i inrange(len(out)): out[i] <<= 120 A = [1] B = [0] for i inrange(1, len(out)-1): A.append(a*A[i-1] % p) B.append((a*B[i-1]+a*out[i]+b-out[i+1]) % p) A = A[1:] B = B[1:]
Ai = matrix(A) Bi = matrix(B) Mi = matrix.identity(len(out)-2)*p K = ZZ(pow(2,128-8)) M = matrix.block([[Mi,ZZ(0),ZZ(0)],[Ai,ZZ(1),ZZ(0)],[Bi,ZZ(0),K]])
out = [] lcg = LCG(seed, a, b, p) for i inrange(30): out.append(lcg.next()) key = "" while1: key += str(lcg.next()) ifint(key) >= c: break
print(long_to_bytes(c^int(key)))
""" b'XYCTF{2h1_21_ZHi_5h0u_yU_zI_xI3_l@0}'
九转第八层压缩包密码
题目:
1 2 3 4 5 6 7 8 9 10
from Crypto.Util.number import bytes_to_long, getPrime flag=b"password{xxxxx}" p,q= getPrime(1024),getPrime(1024) n = p * q e = 65537 m = bytes_to_long(flag) c = pow(m,e,n) print("n=",n) print("c=",c) print("p^q=",p^q)
from Crypto.Util.number import * import gmpy2 import math n = 107803636687595025440095910573280948384697923215825513033516157995095253288310988256293799364485832711216571624134612864784507225218094554935994320702026646158448403364145094359869184307003058983513345331145072159626461394056174457238947423145341933245269070758238088257304595154590196901297344034819899810707 c = 46049806990305232971805282370284531486321903483742293808967054648259532257631501152897799977808185874856877556594402112019213760718833619399554484154753952558768344177069029855164888168964855258336393700323750075374097545884636097653040887100646089615759824303775925046536172147174890161732423364823557122495 list = [618066045261118017236724048165995810304806699407382457834629201971935031874166645665428046346008581253113148818423751222038794950891638828062215121477677796219952174556774639587782398862778383552199558783726207179240239699423569318, 837886528803727830369459274997823880355524566513794765789322773791217165398250857696201246137309238047085760918029291423500746473773732826702098327609006678602561582473375349618889789179195207461163372699768855398243724052333950197] ab = list[1]-list[0] l0 = list[0] l1 = list[1]
for i inrange(1,2**8): t1=l1*i for j inrange(1,2**8): t0 = l0*j if gmpy2.gcd(abs(t1-t0),n) != 1: p = gmpy2.gcd(abs(t1-t0),n) break
e = 65537 q = n//p phi = (p-1)*(q-1) d = gmpy2.invert(e,phi) print(long_to_bytes(pow(c,d,n)))