from Crypto.Util.number import * flag = b'NSSCTF{******}' p = getPrime(512) q = getPrime(512) e = 65537*2 n = p*q m = bytes_to_long(flag) c = pow(m, e, n) print(f'p = {p}') print(f'q = {q}') print(f'e = {e}') print(f'c = {c}') ''' p = 9927950299160071928293508814174740578824022211226572614475267385787727188317224760986347883270504573953862618573051241506246884352854313099453586586022059 q = 9606476151905841036013578452822151891782938033700390347379468858357928877640534612459734825681004415976431665670102068256547092636766287603818164456689343 e = 131074 c = 68145285629092005589126591120307889109483909395989426479108244531402455690717006058397784318664114589567149811644664654952286387794458474073250495807456996723468838094551501146672038892183058042546944692051403972876692350946611736455784779361761930869993818138259781995078436790236277196516800834433299672560 '''
import libnum import gmpy2 c = p = q = e = 61932465 c = c % p phi = p-1 d = gmpy2.invert(e,phi) m = pow(c,d,p) print(libnum.n2s(int(m))) # b'flag{1858c133-a706-4110-af96-9639b25a3d5f}'
import random defchoose_one(p): whileTrue: rho = random.randint(1,p) ifpow(rho,(p-1)//2,p) != 1: return rho defAMM(delta,p): """ :param delta: 同余结果a :param p: 模数p :return: """ if delta % p == 0: return0 ifpow(delta,(p-1)//2,p) != 1: returnNone whileTrue: # 在[1,p)中选择一个模p的二次非剩余 rho = choose_one(p) if rho // p !=1: break
t = 0# 计算t、s phi = p-1 while phi % 2 == 0: t += 1 phi = phi//2 s = (p-1)//(2**t) assert(s % 2 != 0)
# 接下来就是最关键的一步,也就是我们花最多时间推导的部分 a = pow(rho,s,p) b = pow(delta,s,p) h = 1 for i inrange(1,t): d = pow(b,pow(2,t-1-i),p) if d == 1: k = 0 else: k = 1 b = b * pow(a,2*k,p) % p h = h * pow(a,k,p) % p a = pow(a,2,p)
import random import math defchoose_one(r,p): whileTrue: rho = random.randint(1,p) ifpow(rho,(p-1)//r,p) != 1: return rho
defexAMM(delta,r,p): if (p-1) % r != 0: # 检测整除 returnNone ifpow(delta,(p-1)//r,p) != 1: # 检测N次剩余 returnNone
# 第一步、第二步: 先生成一个r次非剩余 rho = choose_one(r,p) # 第三步(1): 求t,s t = 0 phi = p-1 while phi % r == 0: t += 1 phi = phi//r s = (p-1)//(r**t)
# 第三步(2): 计算最小的alpha,使得满足 s|r*alpha - 1 if math.gcd(s,r) != 1: returnNone k = 1 while (s*k+1) % r != 0: k+=1 alpha = (s*k+1)//r
# 第三步(3): 初始化一些值,为循环做准备 a = pow(rho,pow(r,t-1)*s,p) b = pow(delta,r*alpha-1,p) c = pow(rho,s,p) h = 1 for i inrange(1,t): d = pow(b,pow(r,t-1-i),p) if d == 1: j = 0 else: j = -math.log(d,a) % r # 这里可能还有点问题,但好像不影响可以跑出结果 b = b*pow(c,r*j,p) % p h = h*pow(c,j) % p c = pow(c,r,p) returnpow(delta,alpha,p) * h % p
# 这种find_g的方式时间复杂度太高了 deffind_g(p): for g inrange(2,p): flag = True for d inrange(1,p-1): if (p-1) % d == 0andpow(g,d,p)==1: if d != p-1: flag = False if flag: return g
deffind_all_root(x0,r,p,g): roots = [] for k inrange(0,r): roots.append(x0 * pow(g,k*((p-1)//r),p) % p) return roots
# 得到所有的ri,即(ri*mp)^e%p = 1 defALL_ROOT2(r, q): # use function set() and .add() ensure that the generated elements are not repeated li = set() while(len(li) < r): p = powmod(random.randint(1, q-1), (q-1)//r, q) li.add(p) return li
deffind_all_root(x0,p,li): roots = [] for i in li: root = (x0*i) % p roots.append(root) return roots
''' n = 38041020633815871156456469733983765765506895617311762629687651104582466286930269704125415948922860928755218376007606985275046819516740493733602776653724917044661666016759231716059415706703608364873041098478331738686843910748962386378250780017056206432910543374411668835255040201640020726710967482627384460424737495938659004753604600674521079949545966815918391090355556787926276553281009472950401599151788863393804355849499551329 c = 2252456587771662978440183865248648532442503596913181525329434089345680311102588580009450289493044848004270703980243056178363045412903946651952904162045861994915982599488021388197891419171012611795147125799759947942753772847866647801312816514803861011346523945623870123406891646751226481676463538137263366023714001998348605629756519894600802504515051642140147685496526829541501501664072723281466792594858474882239889529245732945 p = 5220649501756432310453173296020153841505609640978826669340282938895377093244978215488158231209243571089268416199675077647719021740691293187913372884975853901554910056350739745148711689601574920977808625399309470283 q = 7286645200183879820325990521698389973072307061827784645416472106180161656047009812712987400850001340478084529480635891468153462119149259083604029658605921695587836792877281924620444742434168448594010024363257554563 '''
import random import math import gmpy2 from Crypto.Util.number import * from tqdm import tqdm defchoose_one(r,p): whileTrue: rho = random.randint(1,p) ifpow(rho,(p-1)//r,p) != 1: return rho
defexAMM(delta,r,p): if (p-1) % r != 0: # 检测整除 returnNone ifpow(delta,(p-1)//r,p) != 1: # 检测N次剩余 returnNone
# 第一步、第二步: 先生成一个r次非剩余 rho = choose_one(r,p) # 第三步(1): 求t,s t = 0 phi = p-1 while phi % r == 0: t += 1 phi = (phi-1)//r s = (p-1)//(r**t)
# 第三步(2): 计算最小的alpha,使得满足 s|r*alpha - 1 if math.gcd(s,r) != 1: returnNone k = 1 while (s*k+1) % r != 0: k+=1 alpha = (s*k+1)//r
# 第三步(3): 初始化一些值,为循环做准备 a = pow(rho,pow(r,t-1)*s,p) b = pow(delta,r*alpha-1,p) c = pow(rho,s,p) h = 1 for i inrange(1,t): d = pow(b,pow(r,t-1-i),p) if d == 1: j = 0 else: j = -math.log(d,a) % r b = b*pow(c,r*j,p) % p h = h*pow(c,j) % p c = pow(c,r,p) returnpow(delta,alpha,p) * h % p
defALL_ROOT2(r, q): # use function set() and .add() ensure that the generated elements are not repeated li = set() while(len(li) < r): p = pow(random.randint(1, q-1), (q-1)//r, q) li.add(p) return li
deffind_all_root(x0,p,li): roots = [] for i in li: root = (x0*i) % p roots.append(root) return roots c = 2252456587771662978440183865248648532442503596913181525329434089345680311102588580009450289493044848004270703980243056178363045412903946651952904162045861994915982599488021388197891419171012611795147125799759947942753772847866647801312816514803861011346523945623870123406891646751226481676463538137263366023714001998348605629756519894600802504515051642140147685496526829541501501664072723281466792594858474882239889529245732945 p = 5220649501756432310453173296020153841505609640978826669340282938895377093244978215488158231209243571089268416199675077647719021740691293187913372884975853901554910056350739745148711689601574920977808625399309470283 q = 7286645200183879820325990521698389973072307061827784645416472106180161656047009812712987400850001340478084529480635891468153462119149259083604029658605921695587836792877281924620444742434168448594010024363257554563 r = 1009 delta1 = c % p x0 = exAMM(delta1,r,p) li1 = ALL_ROOT2(r,p) roots1 = find_all_root(x0,p,li1) delta2 = c % q x1 = exAMM(delta2,r,q) li2 = ALL_ROOT2(r,q) roots2 = find_all_root(x1,q,li2) print(roots1) print(roots2) for i in tqdm(range(len(roots1)),leave=True): for j inrange(len(roots2)): # 除数p、q M = p*q m1 = q m2 = p m1_ = gmpy2.invert(m1,p) m2_ = gmpy2.invert(m2,q) m = (m1*m1_*roots1[i] + m2*m2_*roots2[j]) % M flag = long_to_bytes(m) ifb'NSSCTF'in flag: print(flag) break ifb'NSSCTF'in flag: break # b"NSSCTF{ee5cb1a5-9d62-257a-9ef5-48b06ff0651a}\xbc\xbaw\xfe\xb8\x04A\x8es\xdct#\x1a\x91\x82\xbd\x0f\xfc<\xc4\xb0$\x01\xd0\xc8/\xd9d#\x9baf=\xf1\xfd\xde'\x0e=\xcfX\xd1\xdbM\x9f\xba\xaf\x8a\xb9\xf0\xd7\xaa{\xbf`:DY\xf5|\x11_R\x92\xa1\x9d\xc81\x12\xe9`\x17\xe3\n@K\\\xa5\x1f\xa7?\xdb\xf7p\x8aH\xba(\x02\xad\xf8n\xbe\xea\xcdTu\xac\xc4\xa1"
from Crypto.Util.number import * from tqdm import tqdm c = 2252456587771662978440183865248648532442503596913181525329434089345680311102588580009450289493044848004270703980243056178363045412903946651952904162045861994915982599488021388197891419171012611795147125799759947942753772847866647801312816514803861011346523945623870123406891646751226481676463538137263366023714001998348605629756519894600802504515051642140147685496526829541501501664072723281466792594858474882239889529245732945 p = 5220649501756432310453173296020153841505609640978826669340282938895377093244978215488158231209243571089268416199675077647719021740691293187913372884975853901554910056350739745148711689601574920977808625399309470283 q = 7286645200183879820325990521698389973072307061827784645416472106180161656047009812712987400850001340478084529480635891468153462119149259083604029658605921695587836792877281924620444742434168448594010024363257554563 r = 1009 c1 = c % p c2 = c % q Zmn = Zmod(p) # 创建一个模p的整数环 Zmn2 = Zmod(q) # 在模p的整数环下求 x^r = c 的根,也就是x^p = c mod(p)满足该式子的未知数x # all = True表示要求出所有解,而all = false则表示不需要求出所有解 x_list = Zmn(c1).nth_root(r,all=True) y_list = Zmn2(c2).nth_root(r,all=True) #print(y_list)
for i in tqdm(range(len(x_list)),leave = 'True'): for j inrange(len(y_list)): m_ = [x_list[i],y_list[j]] p_ = [p,q] result = CRT(m_,p_) flag = long_to_bytes(result) ifb'NSSCTF'in flag: print(flag) break ifb'NSSCTF'in flag: break
from Crypto.Util.number import bytes_to_long from secret import flag e = 0x14 p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441 q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721 n = p*q m = bytes_to_long(flag) c = pow(m,e,n) print(c) #406314720119562590605554101860453913891646775958515375190169046313074168423687276987576196367702523895650602252851191274766072774312855212771035294337840170341052016067631007495713764510925931612800335613551752201920460877432379214684677593342046715833439574705829048358675771542989832566579493199671622475225225451781214904100440695928239014046619329247750637911015313431804069312072581674845078940868349474663382442540424342613429896445329365750444298236684237769335405534090013035238333534521759502103604033307768304224154383880727399879024077733935062478113298538634071453067782212909271392163928445051705642
import os import gmpy2 from Crypto.Util.number import * import random from secrets import flag defpad(s,l): return s + os.urandom(l - len(s)) defgen(): g = getPrime(8) whileTrue: p = g * random.getrandbits(138) + 1 if isPrime(p): break whileTrue: q = g * random.getrandbits(138) + 1 if isPrime(q): break N = p ** 5 * q phi = p ** 4 * (p - 1) * (q - 1) d = random.getrandbits(256) e = inverse(d, phi) E = e * g hint = gmpy2.gcd(E, phi) return N, E, hint
flag = pad(flag,64) m = bytes_to_long(flag) n,e,hint = gen() c = pow(m,e,n) print(f'hint = {hint}') print(f'n = {n}') print(f'e = {e}') print(f'c = {c}') # hint = 251 # n = 108960799213330048807537253155955524262938083957673388027650083719597357215238547761557943499634403020900601643719960988288543702833581456488410418793239589934165142850195998163833962875355916819854378922306890883033496525502067124670576471251882548376530637034077 # e = 3359917755894163258174451768521610910491402727660720673898848239095553816126131162471035843306464197912997253011899806560624938869918893182751614520610693643690087988363775343761651198776860913310798127832036941524620284804884136983215497742441302140070096928109039 # c = 72201537621260682675988549650349973570539366370497258107694937619698999052787116039080427209958662949131892284799148484018421298241124372816425123784602508705232247879799611203283114123802597553853842227351228626180079209388772101105198454904371772564490263034162
import random import math defchoose_one(r,p): whileTrue: rho = random.randint(1,p) ifpow(rho,(p-1)//r,p) != 1: return rho
defexAMM(delta,r,p): if (p-1) % r != 0: # 检测整除 returnNone ifpow(delta,(p-1)//r,p) != 1: # 检测N次剩余 returnNone
# 第一步、第二步: 先生成一个r次非剩余 rho = choose_one(r,p) # 第三步(1): 求t,s t = 0 phi = p-1 while phi % r == 0: t += 1 phi = (phi-1)//r s = (p-1)//(r**t)
# 第三步(2): 计算最小的alpha,使得满足 s|r*alpha - 1 if math.gcd(s,r) != 1: returnNone k = 1 while (s*k+1) % r != 0: k+=1 alpha = (s*k+1)//r
# 第三步(3): 初始化一些值,为循环做准备 a = pow(rho,pow(r,t-1)*s,p) b = pow(delta,r*alpha-1,p) c = pow(rho,s,p) h = 1 for i inrange(1,t): d = pow(b,pow(r,t-1-i),p) if d == 1: j = 0 else: j = -math.log(d,a) % r b = b*pow(c,r*j,p) % p h = h*pow(c,j) % p c = pow(c,r,p) returnpow(delta,alpha,p) * h % p
defALL_ROOT2(r, q): # use function set() and .add() ensure that the generated elements are not repeated li = set() while(len(li) < r): p = pow(random.randint(1, q-1), (q-1)//r, q) li.add(p) return li deffind_all_root(x0,p,li): roots = [] for i in li: root = (x0*i) % p roots.append(root) return roots
c1 = [x1,x2] c2 = [y1,y2] for i in c1: for j in c2: M = p*q m1 = q m2 = p m1_ = gmpy2.invert(m1,p) m2_ = gmpy2.invert(m2,q) x = (m1*m1_*i + m2*m2_*j) % M print(long_to_bytes(x)) """ b'this_is_message' b"?\xbb\xfc<\x89/*`x\xc7V'y\xa7?\xf3#.T\x06R\xf2\x8b\x90\x16\xe5L\xc3\x82\x8a\xdfSS\x1e\x89-F\x8b\x1b\\\x12\t\xa3\xc79\xe9\x04\xe4\xe3\xa78E\x80A\xc8\xdf\xc7\xfc\xb84;P\xb8\x9b\xb6\xde^v\xd4&\xe3i\x91\xf6\x86\xdch\xf3\xd5\xb1\x93\xd7\xe8>0\x17\xf8Z\xfb\xc0\xe7\xb5-%\xaf\xa0t\xa6\xa9\x80\xfe\xa0*u\x96\xa0\xe2\x89\xf0&=\xb9\x88\xb6\x06\x07\x85,\x07\xb8\xa6\xba\xb3\xd7$M\xb0\xd6" b'V\x85\x1cR\xd1\xc5\xb8r\xcenk\xba\x91\x17\xcdQ\xbd\xdc\x96\xc5MJ\x16\xa23|\xe0<=PZ\xec\xd8\x9d\x14*51f\x97\x19\x87/\x91&\xae\xee}\x1b\x1c\x9e\xa8\xb6VC,S\xfb\xfd\x8eh\xc5\x88\xea\xcb\xac\xcf \x85!\xdc\x04\xec\xdfz\x82\x0b\xa4\xe8\x97\xa9\x84\x9d\xea\xbb\xadF*\x89f8\xcc\xb9\xd2\xeb\xae"\x0b\x01\xb1\xbe\xd0K\xf2yC\x15+\xd4Z;\xe3\xa1y\x1e<\x019{\x13\xcc\x8c2\xe4\x9awfk' b"\x96A\x18\x8fZ\xf4\xe2\xd3G5\xc1\xe2\n\xbf\rD\xe1\n\xea\xcb\xa0<\xa22Jb,\xff\xbf\xdb:@+\xbb\x9dW{\xbc\x81\xf3+\x90\xd3X`\x97\xf3a\xfe\xc3\xd6\xee6\x98\x0c\x0c\x1b\xf8\xb5\xc2\xa4\x16A\x86\x82\x8b-\x97YH\xbfn~\xd6\x01^t\x98\xbeI=\\\x86(\xeb\xc5>\x85\x85' \x81\xe6\xf8\x9bN\x96\xb1\xab2\xbdpvh\x0f\xe3\xf7\xb5\xc4\x80y\x9d)\xba\xbb\xda\x13\x06\x19Y\x13\xd9\x81HKc\xaf\xdc" """
from Crypto.Util.number import * from secret import flag flag=bytes_to_long(flag) l=flag.bit_length()//3 + 1 n=[] N=1 whilelen(n) < 3: p = 4*getPrime(l)-1 if isPrime(p): n.append(p) N *= p
print(f'c={flag*flag%N}') # flag**2 % N from sympy import symbols, expand x = symbols('x') polynomial = expand((x - n[0]) * (x - n[1]) * (x - n[2]))