# TODO: not work for gcd(e//r, phi) \ne 1 defroot1(n, p, k=1): F = Zmod(p^k) P = Integer(pow(p, k)) phi = euler_phi(P) assert phi % n == 0 whileTrue: g = F.random_element() u0 = Integer(pow(g, phi//n, P)) ifpow(u0, n, P) == 1: return u0
defnth_p(y, n, p, k=1): assert is_prime(p) F = Zmod(p^k) x0 = F(y).nth_root(n) try: u0 = F(1).nth_root(n) except: # if NotImplementedError... u0 = root1(n, p, k) x = [] u = [] for i inrange(n): u += [u0^(i+1)] x += [Integer(x0 * u[i])] returnlist(set(x))
defnthRSA_p(c, e, p, k=1): assert is_prime(p) P = Integer(pow(p, k)) phi = euler_phi(P)
rs = [] ei = e whileTrue: r = gcd(phi, ei) if r == 1: break rs += [r] ei //= r r = product(rs) dr = (e // r).inverse_mod(phi) cr = pow(c, dr, P) return nth_p(cr, r, p, k)
defnthRSA_n(c, e, ps, ks=None, checker=None, ret1=False): # ps: p, q, ... assertisinstance(ps, list) if ks == None: ks = [1] * len(ps) else: assertlen(ps) == len(ks) ms = [] for i inrange(len(ps)): mp = nthRSA_p(c, e, ps[i], ks[i]) ms += [mp] total = product([len(x) for x in ms]) print('[Log] Complexity = %d: %s' % (total, str([len(x) for x in ms])))
res = [] Ps = [ps[i]^ks[i] for i inrange(len(ps))] for msi in tqdm(itertools.product(*ms), total=total): m = crt(list(msi), Ps) if checker == None: res += [m] continue if checker(m): ifnot ret1: res += [m] continue return m return res
defgenHeaderChecker(hd): ifisinstance(hd, str): hd = hd.encode() assertisinstance(hd, bytes) defcheckHeader(m): try: flag = libnum.n2s(int(m)) if hd in flag: print(flag) returnTrue returnFalse except: returnFalse return checkHeader
defgenStrChecker(dict, n=65537): defcheckStr(m): try: flag = libnum.n2s(int(m)).decode() for fi in flag[:n]: ifnot fi indict: returnFalse print(flag) returnTrue except: returnFalse return checkStr
deftest(t): if t == 0: # 2019 NCTF easyRSA e = 0x1337 p = 199138677823743837339927520157607820029746574557746549094921488292877226509198315016018919385259781238148402833316033634968163276198999279327827901879426429664674358844084491830543271625147280950273934405879341438429171453002453838897458102128836690385604150324972907981960626767679153125735677417397078196059 q = 112213695905472142415221444515326532320352429478341683352811183503269676555434601229013679319423878238944956830244386653674413411658696751173844443394608246716053086226910581400528167848306119179879115809778793093611381764939789057524575349501163689452810148280625226541609383166347879832134495444706697124741 c = 10562302690541901187975815594605242014385201583329309191736952454310803387032252007244962585846519762051885640856082157060593829013572592812958261432327975138581784360302599265408134332094134880789013207382277849503344042487389850373487656200657856862096900860792273206447552132458430989534820256156021128891296387414689693952047302604774923411425863612316726417214819110981605912408620996068520823370069362751149060142640529571400977787330956486849449005402750224992048562898004309319577192693315658275912449198365737965570035264841782399978307388920681068646219895287752359564029778568376881425070363592696751183359 ps = [p, q] checker = genStrChecker(string.printable) res = nthRSA_n(c, e, ps, checker=checker) # 11215150it print(res) for r in res: flag = libnum.n2s(int(r)) print(flag) elif t == 1: # 2023 YCB Danger_RSA e = 11079917583 p = 5213351003420231819415242686664610206224730148063270274863722096379841592931572096469136339538500817713355302889731144789372844731378975059329731297860686270736540109105854515590165681366189003405833252270606896051264517339339578167231093908235856718285980689179840159807651185918046198419707669304960745217 q = 3891889986375336330559716098591764128742918441309724777337583126578227827768865619689858547513951476952436981068109005313431255086775128227872912287517417948310766208005723508039484956447166240210962374423348694952997002274647622939970550008327647559433222317977926773242269276334110863262269534189811138319 c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766 ps = [p, q] checker = genHeaderChecker('DASCTF') res = nthRSA_n(c, e, ps, checker=checker) print(res) for r in res: flag = libnum.n2s(int(r)) print(flag) elif t == 2: # 2022 QWB ASR e = 3 c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149 ps = [ 218566259296037866647273372633238739089, 223213222467584072959434495118689164399, 225933944608558304529179430753170813347, 260594583349478633632570848336184053653 ] ks = [2] * 4 checker = genStrChecker(string.printable, 48) res = nthRSA_n(c, e, ps, ks, checker=checker) print(res) for r in res: flag = libnum.n2s(int(r)) print(flag) elif t == 3: # 2023 HWS random pr = [47890485652059026823698344598447161988085597568251161, 47890485652059026823698344598447161988085597568297951, 47890485652059026823698344598447161988085597568338059, 47890485652059026823698344598447161988085597568363667, 47890485652059026823698344598447161988085597568398337, 47890485652059026823698344598447161988085597568433917, 47890485652059026823698344598447161988085597568484111, 47890485652059026823698344598447161988085597568667099, 47890485652059026823698344598447161988085597568729849] upper = [5, 4, 3, 4, 3, 5, 1, 2, 3] n = 255550794734774347335455038653204099810524562323968101081052744238324333979282590769066826059535810339765419405089707653972316828518446466787073982991340735273047955757161722774546888128720663627716647123110956021905275918358574092054477588935546729192812379266210918802470144452212508255209922150559524376661512464064852413804511191503030046546647554981646983220695416838829085308878177824361071544916728725428437436959573167863053126718594118224053088660739173865895266537548733106779437480905737491231720771570860988017959907437998012442781279100256862684919251885437194156545435396952798548033193683684362049646718627530076461463826459504520525895649547513376441325848313193080013281816762156916219271109726593135112626577858906494025788770088106285316571255392298608980679161123528759865796345121056864973189231253364595956642612401745212207858555858704724770456899071144650909246822311039572915447866615638976747716646382091135281119109866295649034560378368202797914202112090339159898226929176034503535419893300159083361891627300767030933209665917744361038219820997348160094737332979677839131999258559999565207302339242257832022939036526481610130970477187338439181123984340269665409009894192138483254592729253191096427332283419085864095600303323775372526431524911842065699875575955728772820558157791292247976982470646890930951250598649964200733076634093613078091713383782021194766013790646324780327618195433827227105459480409797466859653960886570869469172506894631937612508518886406112758352094014377947728184352908630672750330561369500089138179794848896959683336195170519521 c = 29259244746260903447574448389058952310000390135231599667104954615635954705912759181552349897154663199516384757779582324312559110410628822220097857204989378367616522573650610718867075518776621505865327181301059226036067398269476892575801933638458560523584293063843890012581096233699743704556897984235725492806550009731913445801481786988321848320254380607620726887530437151238556482879159888862341096974129499878601309077513908335631417136332585391767849651968095851808312565329858938394084369711172343300695636449663297542069122814607488273607842533010193498547579501368165500427762712900139188279259336486273788664239339542187191374015805659616093967428577968683677885747775540903578723024681500272919689849253480672194507905399890280339044782040395397922973935735424691828624724029439840506402735626398047317544972966643810550593849196291833043243448655939654884418027006572740130515844853007135331296523599052132266288322473865775521953742444721612389547052020839760259179074124960827686670217980159612966767064088131176654212504654177367329044762238432531402899949096987765334061101859346928585114984440559379578507872401025874782849854603895110182401204202962118890563473961321104811452539667609870771280348801335004559132482743318366689808669972965573335905879806817618597010442262336079838039317609336210571773187461470707420797827741277982208089496339300646565067740673242728353659143107970717482392927903021102141779217003523105389389513154792904745687959335115429159530013641777064904216646895961910784920181748841104318013067029395394948190384737300533803009402182800702 e = 57564 assert product([pr[i]^upper[i] for i inrange(len(pr))]) == n checker = genHeaderChecker('flag') res = nthRSA_n(c, e, pr, upper, checker=checker) # 825403/5971968 print(res) for r in res: flag = libnum.n2s(int(r)) print(flag)
if __name__ == '__main__': t = 2 print('Testing: %d' % t) test(t)