#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
from uuid import uuid1 flag="flag{"+str(uuid1())+"}" print(flag)
pubkey = rsa.PublicKey(n , e ) print(pubkey) pub=rsa.PublicKey.save_pkcs1(pubkey) with open("pub.pem","wb") as f: f.write(pub)
私钥生成
1 2 3 4 5 6 7 8 9 10 11 12
import rsa
p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 prikey = rsa.PrivateKey(n , e , d , p , q) print(prikey) pri=rsa.PrivateKey.save_pkcs1(prikey) with open("pri.pem","wb") as f: f.write(pri)
公钥读取
1 2 3 4 5 6 7
import rsa with open('2.pem','rb') as f: keydata= f.read() pubckey = rsa.PublicKey.load_pkcs1(keydata) #pubckey = rsa.PublicKey.load_pkcs1_openssl_pem(keydata) print(pubckey.n) print(pubckey.e)
私钥读取
1 2 3 4 5 6 7 8 9
import rsa with open('1.pem','rb') as f: keydata= f.read() pubckey = rsa.PrivateKey.load_pkcs1(keydata) print(pubckey.n) print(pubckey.e) print(pubckey.d) print(pubckey.q) print(pubckey.p)
出题脚本
随机生成flag
1 2 3 4 5 6 7 8 9 10 11 12 13
import random import hashlib import string
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
基于N分解的题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import libnum import gmpy2 from Crypto.PublicKey import RSA
p=libnum.generate_prime(1024) #下一个素数 q=int(gmpy2.next_prime(p)) e=65537 m="flag{a272722c1db834353ea3ce1d9c71feca}" m=libnum.s2n(m) n=p*q c=pow(m,e,n) flag_c=libnum.n2s(c) rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey1.pem', 'wb') as f : f.write(keypair.exportKey()) with open("flag.txt","wb") as f: f.write(flag_c)
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
with open("pubkey1.pem","rb") as f: key = RSA.import_key(f.read()) n1=key.n e1=key.e
with open("pubkey2.pem","rb") as f: key = RSA.import_key(f.read()) n2=key.n e2=key.e
with open("c1.enc","rb") as f: c1=f.read() c1=base64.b64decode(c1) c1=libnum.s2n(c1) with open("c2.enc","rb") as f: c2=f.read() c2=base64.b64decode(c2) c2=libnum.s2n(c2)
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}") import libnum import random import gmpy2 #生成随机素数 p=libnum.generate_prime(512) q=libnum.generate_prime(512) m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" #字符串转数字 m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1)
#计算d while True: nbits=1024 d = random.getrandbits(nbits // 4) if (libnum.gcd(d, phi_n) == 1 and 36 * pow(d, 4) < n): break #计算e e = libnum.invmod(d,phi_n)
def continuedFra(x, y): """计算连分数 :param x: 分子 :param y: 分母 :return: 连分数列表 """ cf = [] while y: cf.append(x // y) x, y = y, x % y return cf def gradualFra(cf): """计算传入列表最后的渐进分数 :param cf: 连分数列表 :return: 该列表最后的渐近分数 """ numerator = 0 denominator = 1 for x in cf[::-1]: # 这里的渐进分数分子分母要分开 numerator, denominator = denominator, x * denominator + numerator return numerator, denominator def solve_pq(a, b, c): """使用韦达定理解出pq,x^2−(p+q)∗x+pq=0 :param a:x^2的系数 :param b:x的系数 :param c:pq :return:p,q """ par = gmpy2.isqrt(b * b - 4 * a * c) return (-b + par) // (2 * a), (-b - par) // (2 * a) def getGradualFra(cf): """计算列表所有的渐近分数 :param cf: 连分数列表 :return: 该列表所有的渐近分数 """ gf = [] for i in range(1, len(cf) + 1): gf.append(gradualFra(cf[:i])) return gf
def wienerAttack(e, n): """ :param e: :param n: :return: 私钥d """ cf = continuedFra(e, n) gf = getGradualFra(cf) for d, k in gf: if k == 0: continue if (e * d - 1) % k != 0: continue phi = (e * d - 1) // k p, q = solve_pq(1, n - phi + 1, n) if p * q == n: return d
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
#/usr/bin/python # coding=utf-8 import gmpy2 from Crypto.PublicKey import RSA from multiprocessing import Pool pool = Pool(4)
with open('./pubkey.pem', 'r') as f: key = RSA.importKey(f) N = key.n e = key.e with open('flag.enc', 'r') as f: cipher = f.read().encode('hex') cipher = int(cipher, 16)
def calc(j): print j a, b = gmpy2.iroot(cipher + j * N, 3) if b == 1: m = a print '{:x}'.format(int(m)).decode('hex') pool.terminate() exit()
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
import libnum from gmpy2 import invert, gcd, iroot
def op(x): res = 1 for i in x: res *= i return res
def CRT(m, a): assert (len(m) == len(a)) M = op(m) sum = 0 for m, a in zip(m, a): Mi = M // m ti = invert(Mi, m) sum += a * ti * Mi return sum % M def GCRT(m, a): assert (len(m) == len(a)) curm, cura = m[0], a[0] for m, a in zip(m[1:], a[1:]): d = gcd(curm, m) c = a - cura assert (c % d == 0) K = c // d * invert(curm // d, m // d) cura += curm * K curm = curm * m // d return cura % curm
e= 23 n=[] c=[]
m = CRT(n, c) m1 = iroot(m, e) # 开e次方 print(m1) print(libnum.n2s(int(m1[0])))
import binascii,gmpy2 from functools import reduce
import libnum
def CRT(mi, ai): assert(reduce(gmpy2.gcd,mi)==1) assert (isinstance(mi, list) and isinstance(ai, list)) M = reduce(lambda x, y: x * y, mi) ai_ti_Mi = [a * (M // m) * gmpy2.invert(M // m, m) for (m, a) in zip(mi, ai)] return reduce(lambda x, y: x + y, ai_ti_Mi) % M
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
def put_flag(): # 字符串列表 a = string.printable flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = r"flag{%s}"%(hashlib.md5(flag.encode()).hexdigest()) print(flag) return flag
for i in range(1,65535): p=(dp*e-1)//i+1 if n%p==0: q=n//p break print(p) print(q) phi_n= (p-1)*(q-1) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) flag=libnum.n2s(int(m)).decode() print(flag)
题目解析
已知公钥n,e以及dp
其中,dp = d mod (p-1)
已知:
1 2 3 4 5
c = m^e mod n m = c^d mod n ϕ(n)=(p−1)*(q−1) d∗e ≡ 1 mod ϕ(n) dp = d mod (p−1)
def put_flag(): # 字符串列表 a = string.printable flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = r"flag{%s}"%(hashlib.md5(flag.encode()).hexdigest()) print(flag) return flag #生成素数 p=libnum.generate_prime(1024) q=libnum.generate_prime(1024) e=65537 n=p*q phi_n=(p-1)*(q-1) d=libnum.invmod(e,phi_n) dp=d%(p-1) dq=d%(q-1) m=put_flag() m=libnum.s2n(m) n=p*q c=pow(m,e,n)
利用中国剩余定理,得: m1=c^d mod p m2=c^d mod q m=c^d mod n m=c^d+k∗n
n=p∗q m=c^d+p∗q∗k
同时取余q和p
m1≡c^d mod q m2≡c^d mod p
c^d=kp+m1
式1带入式2 m2≡(kp+m1) mod q
等式两边同时减去m1, (m2−m1)≡kp mod q
gcd(p,q)=1
所以可以求p的逆元,得到 (m2−m1)∗p1≡k mod q
得到如下两个式子 k≡(m2−m1)∗p1mod q c^d=kp+m1 m≡c^d mod n
上下两个式子合并
c^d = ((m2−m1)∗p1 mod q)p+m1 m ≡ c^d mod n
最后可以有
m≡(((m2−m1)∗p1 mod q)p+m1) mod n
只剩最后一步了
m1≡cd mod q m2≡cd mod p
m1和m2怎么求
d≡dp mod (p−1) d≡dq mod (q−1)
那么分别带入
m1≡cdq mod (q−1) mod q m2≡cdp mod (p−1) mod p
费马小定理即假如p是质数,且gcd(a,p)=1 a(p−1)≡1 mod p
所以如果我们有等式
d=dp+k∗(p−1)
直接带入 m2≡c^dp+k∗(p−1) mod p
这里的指数,我们拆开,为 m2≡c^dp∗ck∗(p−1) mod p
ck∗(p−1)≡1 mod p
因为p是大素数,显然和c互素所以可以直接得到 m2≡cdp mod p
那么m1根据对称性也可以同理得到
m1≡cdq mod q
故此,我们现在拥有了所有条件,下面归纳一下为
m1≡cdq mod q m2≡cdp mod p m≡(((m2−m1)∗p1 mod q)p+m1) mod n
P14.n是p的r次方
ctf中,遇到过这样的题目:
1
n = p^r ,p为素数,没有q了。因为p=q。
那么计算n的欧拉函数φ(n)就是
1
φ(n)=p^r-p^{r-1}
推导过程为:
1 2 3 4 5 6 7 8 9
欧拉函数φ(n)的定义是小于n的自然数中与n互质的数的个数。
p^r 质因数就只有p,那么不与它互质的数都含有p,
和它不互质的数的个数:p^r/p=p^r-1/p=p^{r-1}
剩下就是互质的数,其个数就是:p^r-p^{r-1}
则有 φ(n)=p^r-p^{r-1}
出题脚本
随机生成flag
1 2 3 4 5 6 7 8 9 10 11 12 13
import random import hashlib import string
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
def gcd(a, b): if a < b: a, b = b, a while b != 0: temp = a % b a = b b = temp return a
def getpq(n, e, d): p = 1 q = 1 while p == 1 and q == 1: k = d * e - 1 g = random.randint(0, n) while p == 1 and q == 1 and k % 2 == 0: k //= 2 y = pow(g, k, n) if y != 1 and gmpy2.gcd(y - 1, n) > 1: p = gmpy2.gcd(y - 1, n) q = n // p return p, q
def main(): n = 16352578963372306131642407541567045533766691177138375676491913897592458965544068296813122740126583082006556217616296009516413202833698268845634497478988128850373221853516973259086845725813424850548682503827191121548693288763243619033224322698075987667531863213468223654181658012754897588147027437229269098246969811226129883327598021859724836993626315476699384610680857047403431430525708390695622848315322636785398223207468754197643541958599210127261345770914514670199047435085714403641469016212958361993969304545214061560160267760786482163373784437641808292654489343487613446165542988382687729593384887516272690654309 e = 65537 d = 9459928379973667430138068528059438139092368625339079253289560577985304435062213121398231875832264894458314629575455553485752685643743266654630829957442008775259776311585654014858165341757547284112061885158006881475740553532826576260839430343960738520822367975528644329172668877696208741007648370045520535298040161675407779239300466681615493892692265542290255408673533853011662134953869432632554008235340864803377610352438146264524770710345273439724107080190182918285547426166561803716644089414078389475072103315432638197578186106576626728869020366214077455194554930725576023274922741115941214789600089166754476449453 p, q = getpq(n, e, d) print(p) print(q)
#coding=utf-8 from random import randint import gmpy2 def oddR(r): while r%2==0: r=r//2 return r
def bits(b): k=[] while b: if b%2!=0: k.append(1) else: k.append(0) b>>=1 k.reverse() return k
def quickmod(a,b,n): #a^b mod n 快速幂模n运算 f=1 k=bits(b) for i in range(len(k)): f=(f*f)%n if k[i]: f=(f*a)%n return f
def gcd(m,n): while(n!=0): m,n=n,m%n return m
def func(e_d,N): k=e_d-1 r=oddR(k) #求出k=2^t*r中的r
while True: b=randint(2,N-1) #获取区间(2,N-1)的一个随机数 a=quickmod(b,r,N) if a==1: continue y=gcd(a-1,N) if a>1 and y>1: q=N//y return q else: r=r*2
def deciphering(e_d,n): 、 p=func(e_d,n) q=n//p phi=n-(p+q)+1 if p*q==n: print p print q else: print"error"
n = 20714298338160449749545360743688018842877274054540852096459485283936802341271363766157976112525034004319938054034934880860956966585051684483662535780621673316774842614701726445870630109196016676725183412879870463432277629916669130494040403733295593655306104176367902352484367520262917943100467697540593925707162162616635533550262718808746254599456286578409187895171015796991910123804529825519519278388910483133813330902530160448972926096083990208243274548561238253002789474920730760001104048093295680593033327818821255300893423412192265814418546134015557579236219461780344469127987669565138930308525189944897421753947 e_d= 100772079222298134586116156850742817855408127716962891929259868746672572602333918958075582671752493618259518286336122772703330183037221105058298653490794337885098499073583821832532798309513538383175233429533467348390389323225198805294950484802068148590902907221150968539067980432831310376368202773212266320112670699737501054831646286585142281419237572222713975646843555024731855688573834108711874406149540078253774349708158063055754932812675786123700768288048445326199880983717504538825498103789304873682191053050366806825802602658674268440844577955499368404019114913934477160428428662847012289516655310680119638600315228284298935201 deciphering(e_d,n)
P16.N分解三个素数
对n进行分解,得到了3个素数 n=pqr
随机生成flag
1 2 3 4 5 6 7 8 9 10 11 12 13
import random import hashlib import string
#字符串列表 a=string.printable #随机生成flag for i in range(10): flag = "" for i in range(10): flag += a[random.randint(0, 99)] flag = hashlib.md5(flag.encode()).hexdigest() print("flag{" + flag + "}")
import gmpy2 import libnum import random import uuid flag="flag{"+str(uuid.uuid4())+"}" m=libnum.s2n(flag)
while 1: e = random.randint(100,1000) p=libnum.generate_prime(1024) q=libnum.generate_prime(1024) phi_n=(p-1)*(q-1) t=gmpy2.gcd(e,phi_n) if gmpy2.invert(e // t, phi_n) and t !=1: break n=p*q c=pow(m,e,n) print("p=",p) print("q=",q) print("e=",e) print("c=",c)
import gmpy2 from base64 import b64decode from Crypto.Util.number import long_to_bytes from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA
import gmpy2 from Crypto.Util.number import long_to_bytes
e = 54722 n = 17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121 c = 3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319 p = 106021448991021391444550749375115277080844281746248845802565680557785009341952320484175568763707424932172033597514861602114171459176440279045761846695231788376075050452154924141266290931413542110639081792550648106240966552406813059396358355737185354885474455248579946190266152416149137616855791805617206153497 q = 161136651053130509602530659420755324119806487925813087617466818245407407797561810253722204813002837916779909309520498985459703212021249251124954613236122142746302911323565396331355397916764254680629384957057354297855676493062493901977415968666512459829211010720514167083018352796496733697235524845188512914793
e = 65537 n = 156808343598578774957375696815188980682166740609302831099696492068246337198792510898818496239166339015207305102101431634283168544492984586566799996471150252382144148257236707247267506165670877506370253127695314163987084076462560095456635833650720606337852199362362120808707925913897956527780930423574343287847 c = 108542078809057774666748066235473292495343753790443966020636060807418393737258696352569345621488958094856305865603100885838672591764072157183336139243588435583104423268921439473113244493821692560960443688048994557463526099985303667243623711454841573922233051289561865599722004107134302070301237345400354257869 dp = 734763139918837027274765680404546851353356952885439663987181004382601658386317353877499122276686150509151221546249750373865024485652349719427182780275825
#先爆破K得到p、q temp=dp*e for i in range(1,e) : if (temp-1)%i==0: x=(temp-1)//i+1 y=n%x if y==0: p=x break q = n // p assert isPrime(p) assert isPrime(q) #print(f"p={p}\nq={q}")
phi = (q-1) * (p-1) d = gmpy2.invert(e,phi) #print(d) m = pow(c,d,n) m = long_to_bytes(m) print(m)
pq相似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import gmpy2 import sympy from Crypto.Util.number import long_to_bytes
n=177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683 e = 65537 c=1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049
import gmpy2 from Crypto.Util.number import long_to_bytes
e1 = 2767 e2 = 3659
n = 21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111
from Crypto.Util.number import * from gmpy2 import *
e = 0x10001 d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913 c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804
kphi = e*d - 1
for k in range(1, e): if kphi % k == 0: phi = kphi // k root = iroot(phi, 2)[0] for p in range(root - 2000, root + 2000): if phi % (p-1) == 0: break else: continue break
''' A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x p=next_prime(z*x*y) q=next_prime(z) ''' A = 2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724 n = 117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127 c = 41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128
import sympy from gmpy2 import * from Crypto.Util.number import long_to_bytes
p = 842868045681390934539739959201847552284980179958879667933078453950968566151662147267006293571765463137270594151138695778986165111380428806545593588078365331313084230014618714412959584843421586674162688321942889369912392031882620994944241987153078156389470370195514285850736541078623854327959382156753458569 q = 139916095583110895133596833227506693679306709873174024876891023355860781981175916446323044732913066880786918629089023499311703408489151181886568535621008644997971982182426706592551291084007983387911006261442519635405457077292515085160744169867410973960652081452455371451222265819051559818441257438021073941183 phi=(p-1)*(q-1)
e=2 str1="RoarCTF{" while(e<100000): e=next_prime(e) try: d=invert(e,phi) m=pow(c,d,n) except: print (e) else: d=invert(e,phi) m=pow(c,d,n) str2=str(long_to_bytes(m)) if str1 in str2: print(long_to_bytes(m)) break
from Crypto.Util.number import * from gmpy2 import * from sympy import * #from secret import flag ''' p = getPrime(25) e = # Hidden q = getPrime(25) n = p * q m = bytes_to_long(flag.strip(b"npuctf{").strip(b"}"))
c = pow(m, e, n) print(c) print(pow(2, e, n)) print(pow(4, e, n)) print(pow(8, e, n))
from gmpy2 import * from Crypto.Util.number import * from tqdm import tqdm def onemod(p,r): t = p-2 while pow(t, (p-1) // r, p) == 1: t -= 1 return pow(t, (p-1) // r, p) def solution(p,root): g = onemod(p, 0x1337) may = [] for i in range(0x1337): if i % 100 == 0: print(i) may.append(root * pow(g,i,p) % p) return may c = 10562302690541901187975815594605242014385201583329309191736952454310803387032252007244962585846519762051885640856082157060593829013572592812958261432327975138581784360302599265408134332094134880789013207382277849503344042487389850373487656200657856862096900860792273206447552132458430989534820256156021128891296387414689693952047302604774923411425863612316726417214819110981605912408620996068520823370069362751149060142640529571400977787330956486849449005402750224992048562898004309319577192693315658275912449198365737965570035264841782399978307388920681068646219895287752359564029778568376881425070363592696751183359 p = 199138677823743837339927520157607820029746574557746549094921488292877226509198315016018919385259781238148402833316033634968163276198999279327827901879426429664674358844084491830543271625147280950273934405879341438429171453002453838897458102128836690385604150324972907981960626767679153125735677417397078196059 q = 112213695905472142415221444515326532320352429478341683352811183503269676555434601229013679319423878238944956830244386653674413411658696751173844443394608246716053086226910581400528167848306119179879115809778793093611381764939789057524575349501163689452810148280625226541609383166347879832134495444706697124741 e = 0x1337 n = p * q c_p = pow(c, (1 + 3307 * (p - 1) // e) // e, p) C1 = solution(p, c_p) c_q = pow(c, (1 + (2649 * (q - 1) // e)) // e, q) C2 = solution(q, c_q) a = invert(p, q) b = invert(q, p) flag=0 for i in tqdm(C1): for j in tqdm(C2): flag += 1 if flag % 1000000 == 0: print(flag) x = (b * q * i + a * p * j) % n if b"NCTF{" in long_to_bytes(x): print(long_to_bytes(x)) exit()