flag = s2n(flag) p = getPrime(1024) q = getPrime(1024) if p < q: p, q = q, p assert q < p < 2 * q phi = (p - 1) * (q - 1) N = p * q d = randint(0, int(iroot(N, 4)[0]) // 3) print(f'N = {N}') print(f'd = {d}') e = invmod(d, phi) print(f'e = {e}') c = pow(flag, e, N) print(f'c = {c}')
''' N = 21327609432635697635661734492967514868032345219646509293473450728946796929125596264796686608077350282146808431543688814099354946988813695125850734043400446455515569653767982263228375866016212125033017742119349015072822178318196190745694850995570515630230752678292777440574778729120793338895028632923682027496271327472935942662500117169921554840041050071839641224638348524022215169727418319630285293394980617769914591506983043636592739835090149763802884920200300368993239366686843677366099965654860267609759882686378049533310393901183559714507043035045332273502601434654726043496991435324318063462466253726816633686491 e = 18977835107309220930390004484766560831346929608900345454868912576417879395319152391809677007908654095951324946088077940809180932163517507338773363819836058226479707254933679974004335002153790380237807333376658330135322627930737835299410373663744954613372507542594748704398503555416693543828015836373800739443278657909905379530092958500438988035068330839162959013568315176411267327500693507377318806169025417092598473813234048525222602269176512302545380940501266666455315603787471273429334914051803354595877792553046681362881913923273953799258321308753602286651515092850863999625965095880385885087205694014033060741113 c = 2951989543787250024227309988919939594167825226148750874062428524625014545445228307222640088545937734380203828988989321941362142365155595290586130523703955533644047842799047518117049515659231726842039527270329713890518786418601487875975864228006745361862477308867519292913016550436143764016127132235503694918940332463597026396960672403183254520332051492462851679089378927071373658225211987354898477962818171916800202243021649078952845125153161320695143579666246174891848723194556125740925439954503389599981696506010841328091656707182777225501527571416356759631836676820899342968642257694841513191347688952532566252238 '''
# numerator(n):分子, denominator(d):分母 deft_cf(n, d): # 将分数 x/y 转为连分数的形式 res = [] while d: res.append(n // d) n, d = d, n % d return res
defcf(sub_res): # 得到渐进分数的分母和分子 n, d = 1, 0 for i in sub_res[::-1]: # 从后面往前循环 d, n = n, i * n + d return d, n
deflist_fraction(x, y): # 列出每个渐进分数 res = t_cf(x, y) res = list(map(cf, (res[0:i] for i inrange(1, len(res))))) # 将连分数的结果逐一截取以求渐进分数 return res
defget_pq(a, b, c): # 由p+q和pq的值通过维达定理来求解p和q(解二元一次方程) par = gmpy2.isqrt(b * b - 4 * a * c) # 由上述可得,开根号一定是整数,因为有解 x1, x2 = (-b + par) // (2 * a), (-b - par) // (2 * a) return x1, x2
defwienerAttack(e, n): for (d, k) in list_fraction(e, n): # 用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数 if k == 0: # 可能会出现连分数的第一个为0的情况,排除 continue if (e * d - 1) % k != 0: # ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n) continue
phi = (e * d - 1) // k # 这个结果就是 φ(n) px, qy = get_pq(1, n - phi + 1, n)