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