from Crypto.Util.number import * from Crypto.PublicKey import RSA
e = 65537 flag = b'ACTF{...}'
whileTrue: p = getPrime(1024) q = inverse(e, p) ifnot isPrime(q): continue n = p * q; public = RSA.construct((n, e)) withopen("public.pem", "wb") as file: file.write(public.exportKey('PEM')) withopen("flag", "wb") as file: file.write(long_to_bytes(pow(bytes_to_long(flag), e, n))) break
from sage.allimport * from secret import flag from Crypto.Util.number import bytes_to_long
defleak(a, b): p = random_prime(pow(2, 64)) q = random_prime(pow(2, 64)) n = p*q e = 65537 print(n) print((pow(a, e) + pow(b, e) + 0xdeadbeef) % n)
defgen_key(): a = randrange(0, pow(2,256)) b = randrange(0, pow(2,256)) p = pow(a, 4) q = pow(b, 4) rp = randrange(0, pow(2,24)) rq = randrange(0, pow(2,24)) pp = next_prime(p+rp) qq = next_prime(q+rq) if pp % pow(2, 4) == (pp-p) % pow(2, 4) and qq % pow(2, 4) == (qq-q) % pow(2, 4): n = pp*qq rp = pp-p rq = qq-q return n, rp, rq
n, rp, rq = gen_key() e = 65537 c = pow(bytes_to_long(flag), e, n) print("n =", n) print("e =", e) print("c =", c) print("=======leak=======") leak(rp, rq)
''' n = 3183573836769699313763043722513486503160533089470716348487649113450828830224151824106050562868640291712433283679799855890306945562430572137128269318944453041825476154913676849658599642113896525291798525533722805116041675462675732995881671359593602584751304602244415149859346875340361740775463623467503186824385780851920136368593725535779854726168687179051303851797111239451264183276544616736820298054063232641359775128753071340474714720534858295660426278356630743758247422916519687362426114443660989774519751234591819547129288719863041972824405872212208118093577184659446552017086531002340663509215501866212294702743 e = 65537 c = 48433948078708266558408900822131846839473472350405274958254566291017137879542806238459456400958349315245447486509633749276746053786868315163583443030289607980449076267295483248068122553237802668045588106193692102901936355277693449867608379899254200590252441986645643511838233803828204450622023993363140246583650322952060860867801081687288233255776380790653361695125971596448862744165007007840033270102756536056501059098523990991260352123691349393725158028931174218091973919457078350257978338294099849690514328273829474324145569140386584429042884336459789499705672633475010234403132893629856284982320249119974872840 =======leak======= 122146249659110799196678177080657779971 90846368443479079691227824315092288065 '''
from Crypto.Util.number import * from gmpy2 import iroot,invert from tqdm import tqdm from math import ceil,floor
n = 3183573836769699313763043722513486503160533089470716348487649113450828830224151824106050562868640291712433283679799855890306945562430572137128269318944453041825476154913676849658599642113896525291798525533722805116041675462675732995881671359593602584751304602244415149859346875340361740775463623467503186824385780851920136368593725535779854726168687179051303851797111239451264183276544616736820298054063232641359775128753071340474714720534858295660426278356630743758247422916519687362426114443660989774519751234591819547129288719863041972824405872212208118093577184659446552017086531002340663509215501866212294702743 e = 65537 c = 48433948078708266558408900822131846839473472350405274958254566291017137879542806238459456400958349315245447486509633749276746053786868315163583443030289607980449076267295483248068122553237802668045588106193692102901936355277693449867608379899254200590252441986645643511838233803828204450622023993363140246583650322952060860867801081687288233255776380790653361695125971596448862744165007007840033270102756536056501059098523990991260352123691349393725158028931174218091973919457078350257978338294099849690514328273829474324145569140386584429042884336459789499705672633475010234403132893629856284982320249119974872840
leak_n = 122146249659110799196678177080657779971 leak_p = 8949458376079230661 leak_q = 13648451618657980711 leak_phi = (leak_p - 1)*(leak_q - 1) leak_d = invert(e,leak_phi) leak_out = 90846368443479079691227824315092288065 leak_out -= 0xdeadbeef m = 4 ''' for rp in tqdm(range(1,16777216)): rpe = pow(rp,e,leak_n) rq = pow(leak_out-rpe,leak_d,leak_n) #if rq.bit_length() in range(23,25): if rq.bit_length() <= 24 and n%16 == (rp*rq)%16: print(rp,rq) break ''' #rp, rq = 405771, 11974933 rq, rp = 405771, 11974933 start = ceil(iroot(rp*rq,2)[0]) edge = floor(rq/2+2**(m/2-1)*rp+1) print(f'start = {start}') print(f'edge = {edge}')
for i in tqdm(range(start,edge)): sigma = (int(iroot(n,2)[0]) - i)**2#整数化 z = (n - rp*rq)%sigma delta = z**2 - 4*sigma*rp*rq if delta < 0: continue if iroot(delta,2)[1]: x1, x2 = (z+int(iroot(delta,2)[0]))//2, (z-int(iroot(delta,2)[0]))//2#整数化 print(f'x1 = {x1}') assert x1**2 - z*x1 + sigma*rp*rq == 0 maybe_p = int(n//(x1//rp+rq)) if n%maybe_p == 0: p = maybe_p q = n//p print(f'p = {p}\nq = {q}') break print(f'x2 = {x2}') assert x2**2 - z*x2 + sigma*rp*rq == 0 maybe_q = int(n//(x2//rq+rp)) if n%maybe_q == 0: q = maybe_q p = n//q print(f'p = {p}\nq = {q}') break
phi = (p-1)*(q-1) d = invert(e,phi) flag = long_to_bytes(pow(c,d,n)) print(flag)
from Crypto.Util.number import * from gmpy2 import iroot,invert from tqdm import tqdm from z3 import *
n = 3183573836769699313763043722513486503160533089470716348487649113450828830224151824106050562868640291712433283679799855890306945562430572137128269318944453041825476154913676849658599642113896525291798525533722805116041675462675732995881671359593602584751304602244415149859346875340361740775463623467503186824385780851920136368593725535779854726168687179051303851797111239451264183276544616736820298054063232641359775128753071340474714720534858295660426278356630743758247422916519687362426114443660989774519751234591819547129288719863041972824405872212208118093577184659446552017086531002340663509215501866212294702743 e = 65537 c = 48433948078708266558408900822131846839473472350405274958254566291017137879542806238459456400958349315245447486509633749276746053786868315163583443030289607980449076267295483248068122553237802668045588106193692102901936355277693449867608379899254200590252441986645643511838233803828204450622023993363140246583650322952060860867801081687288233255776380790653361695125971596448862744165007007840033270102756536056501059098523990991260352123691349393725158028931174218091973919457078350257978338294099849690514328273829474324145569140386584429042884336459789499705672633475010234403132893629856284982320249119974872840 ''' for i in tqdm(range(1,16777216)): rpe = pow(rp,e,leak_n) rq = pow(leak_out-rpe,leak_d,leak_n) if rq.bit_length() <= 24 and n%16 == (rp*rq)%16: print(rp,rq) break ''' rp, rq = 405771, 11974933
a,b = Ints('a b') solver = Solver() #solver.add(n == (a**4+rp)*(b**4+rq)) #solver.add(int(iroot(n,4)[0]) == a*b)#int化 solver.add( n == (a**4+rp)*(b**4+rq), int(iroot(n,4)[0]) == a*b ) if solver.check() == sat: result = solver.model()