|
| 1 | +#!/usr/bin/python |
| 2 | + |
| 3 | +from binascii import hexlify |
| 4 | +from gmpy2 import * |
| 5 | +import math |
| 6 | +import os |
| 7 | +import sys |
| 8 | + |
| 9 | +if sys.version_info < (3, 9): |
| 10 | + math.gcd = gcd |
| 11 | + math.lcm = lcm |
| 12 | + |
| 13 | +_DEBUG = True |
| 14 | + |
| 15 | +FLAG = open('flag.txt').read().strip() |
| 16 | +FLAG = mpz(hexlify(FLAG.encode()), 16) |
| 17 | +SEED = mpz(hexlify(os.urandom(32)).decode(), 16) |
| 18 | +STATE = random_state(SEED) |
| 19 | + |
| 20 | +def get_prime(state, bits): |
| 21 | + return next_prime(mpz_urandomb(state, bits) | (1 << (bits - 1))) |
| 22 | + |
| 23 | +def get_smooth_prime(state, bits, smoothness=16): |
| 24 | + p = mpz(2) |
| 25 | + p_factors = [p] |
| 26 | + while p.bit_length() < bits - 2 * smoothness: |
| 27 | + factor = get_prime(state, smoothness) |
| 28 | + p_factors.append(factor) |
| 29 | + p *= factor |
| 30 | + |
| 31 | + bitcnt = (bits - p.bit_length()) // 2 |
| 32 | + |
| 33 | + while True: |
| 34 | + prime1 = get_prime(state, bitcnt) |
| 35 | + prime2 = get_prime(state, bitcnt) |
| 36 | + tmpp = p * prime1 * prime2 |
| 37 | + if tmpp.bit_length() < bits: |
| 38 | + bitcnt += 1 |
| 39 | + continue |
| 40 | + if tmpp.bit_length() > bits: |
| 41 | + bitcnt -= 1 |
| 42 | + continue |
| 43 | + if is_prime(tmpp + 1): |
| 44 | + p_factors.append(prime1) |
| 45 | + p_factors.append(prime2) |
| 46 | + p = tmpp + 1 |
| 47 | + break |
| 48 | + |
| 49 | + p_factors.sort() |
| 50 | + |
| 51 | + return (p, p_factors) |
| 52 | + |
| 53 | +e = 0x10001 |
| 54 | + |
| 55 | +while True: |
| 56 | + p, p_factors = get_smooth_prime(STATE, 1024, 16) |
| 57 | + if len(p_factors) != len(set(p_factors)): |
| 58 | + continue |
| 59 | + # Smoothness should be different or some might encounter issues. |
| 60 | + q, q_factors = get_smooth_prime(STATE, 1024, 17) |
| 61 | + if len(q_factors) != len(set(q_factors)): |
| 62 | + continue |
| 63 | + factors = p_factors + q_factors |
| 64 | + if e not in factors: |
| 65 | + break |
| 66 | + |
| 67 | +if _DEBUG: |
| 68 | + import sys |
| 69 | + sys.stderr.write(f'p = {p.digits(16)}\n\n') |
| 70 | + sys.stderr.write(f'p_factors = [\n') |
| 71 | + for factor in p_factors: |
| 72 | + sys.stderr.write(f' {factor.digits(16)},\n') |
| 73 | + sys.stderr.write(f']\n\n') |
| 74 | + |
| 75 | + sys.stderr.write(f'q = {q.digits(16)}\n\n') |
| 76 | + sys.stderr.write(f'q_factors = [\n') |
| 77 | + for factor in q_factors: |
| 78 | + sys.stderr.write(f' {factor.digits(16)},\n') |
| 79 | + sys.stderr.write(f']\n\n') |
| 80 | + |
| 81 | +n = p * q |
| 82 | + |
| 83 | +m = math.lcm(p - 1, q - 1) |
| 84 | +d = pow(e, -1, m) |
| 85 | + |
| 86 | +c = pow(FLAG, e, n) |
| 87 | + |
| 88 | +print(f'n = {n.digits(16)}') |
| 89 | +print(f'c = {c.digits(16)}') |
0 commit comments