Very Smooth
This commit is contained in:
89
very_smooth/gen.py
Executable file
89
very_smooth/gen.py
Executable file
@@ -0,0 +1,89 @@
|
||||
#!python3
|
||||
|
||||
from binascii import hexlify
|
||||
from gmpy2 import *
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 9):
|
||||
math.gcd = gcd
|
||||
math.lcm = lcm
|
||||
|
||||
_DEBUG = False
|
||||
|
||||
FLAG = open('flag.txt').read().strip()
|
||||
FLAG = mpz(hexlify(FLAG.encode()), 16)
|
||||
SEED = mpz(hexlify(os.urandom(32)).decode(), 16)
|
||||
STATE = random_state(SEED)
|
||||
|
||||
def get_prime(state, bits):
|
||||
return next_prime(mpz_urandomb(state, bits) | (1 << (bits - 1)))
|
||||
|
||||
def get_smooth_prime(state, bits, smoothness=16):
|
||||
p = mpz(2)
|
||||
p_factors = [p]
|
||||
while p.bit_length() < bits - 2 * smoothness:
|
||||
factor = get_prime(state, smoothness)
|
||||
p_factors.append(factor)
|
||||
p *= factor
|
||||
|
||||
bitcnt = (bits - p.bit_length()) // 2
|
||||
|
||||
while True:
|
||||
prime1 = get_prime(state, bitcnt)
|
||||
prime2 = get_prime(state, bitcnt)
|
||||
tmpp = p * prime1 * prime2
|
||||
if tmpp.bit_length() < bits:
|
||||
bitcnt += 1
|
||||
continue
|
||||
if tmpp.bit_length() > bits:
|
||||
bitcnt -= 1
|
||||
continue
|
||||
if is_prime(tmpp + 1):
|
||||
p_factors.append(prime1)
|
||||
p_factors.append(prime2)
|
||||
p = tmpp + 1
|
||||
break
|
||||
|
||||
p_factors.sort()
|
||||
|
||||
return (p, p_factors)
|
||||
|
||||
e = 0x10001
|
||||
|
||||
while True:
|
||||
p, p_factors = get_smooth_prime(STATE, 1024, 16)
|
||||
if len(p_factors) != len(set(p_factors)):
|
||||
continue
|
||||
# Smoothness should be different or some might encounter issues.
|
||||
q, q_factors = get_smooth_prime(STATE, 1024, 17)
|
||||
if len(q_factors) != len(set(q_factors)):
|
||||
continue
|
||||
factors = p_factors + q_factors
|
||||
if e not in factors:
|
||||
break
|
||||
|
||||
if _DEBUG:
|
||||
import sys
|
||||
sys.stderr.write(f'p = {p.digits(16)}\n\n')
|
||||
sys.stderr.write(f'p_factors = [\n')
|
||||
for factor in p_factors:
|
||||
sys.stderr.write(f' {factor.digits(16)},\n')
|
||||
sys.stderr.write(f']\n\n')
|
||||
|
||||
sys.stderr.write(f'q = {q.digits(16)}\n\n')
|
||||
sys.stderr.write(f'q_factors = [\n')
|
||||
for factor in q_factors:
|
||||
sys.stderr.write(f' {factor.digits(16)},\n')
|
||||
sys.stderr.write(f']\n\n')
|
||||
|
||||
n = p * q
|
||||
|
||||
m = math.lcm(p - 1, q - 1)
|
||||
d = pow(e, -1, m)
|
||||
|
||||
c = pow(FLAG, e, n)
|
||||
|
||||
print(f'n = {n.digits(16)}')
|
||||
print(f'c = {c.digits(16)}')
|
||||
2
very_smooth/output.txt
Executable file
2
very_smooth/output.txt
Executable file
@@ -0,0 +1,2 @@
|
||||
n = b03ea698ce2b51fb00e11e6fbaf1e5373dc5b0c70eb2b14a36d21e8667be8774eee51f6050a10237f6b24f21204fc8013681e7ed72ed051188f3274aae8f1de0d39389b514c196fa82c98a270bfabefd044da8c687b0e114ebbde82536c0709ac5ad81bfe0077e9d9b798ad5abecee52767e68f8060c45936521fd93893102eb1676f2ff41324a7a6b3dff2e830538e06d25934e9f14bf6b40ab5674fe648e314bf06f84282f5ef52bc1401de3a42eb66e64bcdadd2674348e5bdb7016feda44d719af387a948ad81cbaed10213dd930fc7bc7677d8c4cdab0645d0ff15e6ad6ca37135942c3be08f23e7be0992c8b3370dcdc31045e086d823107fb2e443dc9
|
||||
c = a913a96e215b5aa79c702d27fa375c73d06787639c4131fb32877cafefaa8faf70e15f6a17ef2a9a6f5310b157cb287b740e77cb5385081d1853a9104bc16357b259fa2d146bd87398d4ef6f1c078289812952c67792cf9cd745049aeb9d4ab4dff2825a9c0b3381f19b2a67164f9d4de33c25f98bc2f224feb5507b531e1a1c7be5ed2d8ddd01f3fae37245e8cf99c75a21848993d445e1d6d69d555a3e6cc8055704fdde88df9084bda3ea65a9384fa64bf8df4d88946449526320c15d4d2d871638070489adf3f8c95caffeab40b0d137a9319be20cdf6ebbaf037f62093d9bd33edd4ffd7e1929b9ab06252956fd85250a0515ef2b4e035017be5702cdd3
|
||||
65
very_smooth/sol.py
Executable file
65
very_smooth/sol.py
Executable file
@@ -0,0 +1,65 @@
|
||||
#!python3
|
||||
from sage.all import *
|
||||
from pwn import *
|
||||
|
||||
with open("output.txt", 'r') as f:
|
||||
lines = f.readlines()
|
||||
N = Integer(lines[0][4:].strip(), 16)
|
||||
c = Integer(lines[1][4:].strip(), 16)
|
||||
log.info(f"N: {N}")
|
||||
log.info(f"c: {c}")
|
||||
|
||||
e = Integer(0x10001)
|
||||
log.info(f"e: {e}")
|
||||
|
||||
smooth_bound = 16
|
||||
loopmsg = log.progress("calculating p, q")
|
||||
interval = (0, smooth_bound)
|
||||
center = 0
|
||||
while True:
|
||||
base = Integer(2)
|
||||
M = 1
|
||||
for p in Primes():
|
||||
if p >= smooth_bound:
|
||||
break
|
||||
|
||||
np = p
|
||||
while np+p < smooth_bound:
|
||||
np += p
|
||||
|
||||
M *= np
|
||||
|
||||
g = gcd(pow(base, M, N)-1, N)
|
||||
|
||||
if g == 1 and center == 0:
|
||||
interval = (smooth_bound, smooth_bound*2)
|
||||
smooth_bound *= 2
|
||||
elif g == 1 and center != 0:
|
||||
interval = (center, interval[1])
|
||||
center = interval[0] + (interval[1] - interval[0])/2
|
||||
smooth_bound = center
|
||||
elif g == N and center == 0:
|
||||
center = interval[0] + (interval[1] - interval[0])/2
|
||||
smooth_bound = center
|
||||
elif g == N and center != 0:
|
||||
interval = (interval[0], center)
|
||||
center = interval[0] + (interval[1] - interval[0])/2
|
||||
smooth_bound = center
|
||||
else:
|
||||
loopmsg.success("factoring found")
|
||||
p = int(g)
|
||||
q = N // p
|
||||
break
|
||||
|
||||
assert p*q == N
|
||||
log.info(f"p: {p}")
|
||||
log.info(f"q: {q}")
|
||||
|
||||
d = pow(e, -1, (p-1)*(q-1))
|
||||
log.info(f"d: {d}")
|
||||
|
||||
m = pow(c, d, N)
|
||||
log.info(f"m: {m}")
|
||||
m_literal = pack(int(m), 'all', 'big', False)
|
||||
log.success(f"solution: {m_literal}")
|
||||
|
||||
Reference in New Issue
Block a user