From d7b7c52cfa5e4386974a9246901eee0720ff1917 Mon Sep 17 00:00:00 2001 From: Maxime Vorwerk Date: Wed, 31 Jul 2024 16:06:24 +0200 Subject: [PATCH] Sum-O-Primes --- sum_o_primes/gen.py | 37 ++++++++++++++++++++++++++++++++++++ sum_o_primes/output.txt | 3 +++ sum_o_primes/sol.py | 42 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100755 sum_o_primes/gen.py create mode 100755 sum_o_primes/output.txt create mode 100755 sum_o_primes/sol.py diff --git a/sum_o_primes/gen.py b/sum_o_primes/gen.py new file mode 100755 index 0000000..676cf9c --- /dev/null +++ b/sum_o_primes/gen.py @@ -0,0 +1,37 @@ +#!python3 + +from binascii import hexlify +from gmpy2 import mpz_urandomb, next_prime, random_state +import math +import os +import sys + +if sys.version_info < (3, 9): + import gmpy2 + math.gcd = gmpy2.gcd + math.lcm = gmpy2.lcm + +FLAG = open('flag.txt').read().strip() +FLAG = int(hexlify(FLAG.encode()), 16) +SEED = int(hexlify(os.urandom(32)).decode(), 16) +STATE = random_state(SEED) + +def get_prime(bits): + return next_prime(mpz_urandomb(STATE, bits) | (1 << (bits - 1))) + +p = get_prime(1024) +q = get_prime(1024) + +x = p + q +n = p * q + +e = 65537 + +m = math.lcm(p - 1, q - 1) +d = pow(e, -1, m) + +c = pow(FLAG, e, n) + +print(f'x = {x:x}') +print(f'n = {n:x}') +print(f'c = {c:x}') diff --git a/sum_o_primes/output.txt b/sum_o_primes/output.txt new file mode 100755 index 0000000..1c86325 --- /dev/null +++ b/sum_o_primes/output.txt @@ -0,0 +1,3 @@ +x = 1429cf99b5dd5dde9f016095be650d5b0a9a73e648aa72324cb8eb05bd14c1b913539a97f5417474f6014de830ad6dee028dd8908e593b1e99c4cc88f400127214036e71112292e58a2ccffc48f57524aee90f9858d935c7a86297a90c7fe48b80f6c4e8df9eaae501ef40da7984502457255fbc8a9e1574ec6ba210be134f192 +n = 64fc90f5ca6db24f7bfc6419de407596d29a9ecda526101b8d0eff2181e9b8ed1538a1cbabe4dfc5bcd899976e7739f8b448815b50db36a994c5b1df97981d562c663113fc5ee84f3206aecd18248fb4e9bddf205c8119e8437f7d6522e63d05bc357ae4969a4b3000b8226f8d142c23c4e38cdb0c385bf9564e8a115e4c52b7a2e3a9073a5d99d7bec3bca6452cf0c1b8d8b6b123cc6a6980cf14088d6a2bbb5ed36b85cb0003e535bd16d79ad54ff5b26e62f57de074654493d3a26a149786d5fbf61b42c9305092eb018aa3db3cb18b24f188ae520bd18acf9ffced09a2ba302a520f6e2bfd8eea9adc01eb8ee941181694a3ab493e1aa53fbbbf2851a591 +c = 56ed81bbc149701110f0a15e2e6078ab926d74ee2c11b804ae4fad4333a25c247f38bb74867922438d10ce529b75f5ee5e29ce71d6f704cc0644f7e78d60a2af8921fbc49326280e3f0c00f2769e837363cbb05dc3f30bda8fdc94111fb025008eae562ae57029d5cfde6bdd09893a738187578d22f82a5f8769f093681662329f05b262c2054f91696a24f631ba8132f3d92ae7758c91fa9b5657e4944c5d5f93afb4af68908d004ae5f97071bcaceb7d0034297eeb897f972b44b0d7def52f46ee45d386a5e24ed613bf7e5177c6e10f69a3d3de0f0c30de0b15d360ee81da3d277a4acf47b6df389c24615884b692e604eba711fc28c34bc56227b8455705 diff --git a/sum_o_primes/sol.py b/sum_o_primes/sol.py new file mode 100755 index 0000000..626ad4e --- /dev/null +++ b/sum_o_primes/sol.py @@ -0,0 +1,42 @@ +#!python3 +from sage.all import * +import pwn + +with open("output.txt", 'r') as f: + lines = f.readlines() + x = Integer(lines[0][4:], 16) + N = Integer(lines[1][4:], 16) + c = Integer(lines[2][4:], 16) + +pwn.log.info("x: {}".format(x)) +pwn.log.info("N: {}".format(N)) +pwn.log.info("c: {}".format(c)) + +# n = p*q +# x = p+q +# -> n = p*(x-p) +# -> n = px - p² +# -> p² - px + n = 0 +# -> (p - x/2)² + n - x²/4 = 0 +# -> (p - x/2)² = x²/4 - n +# -> p - x/2 = +- sqrt(x²/4 - n) +# -> p = x/2 +- sqrt(x²/4 - n) + +disc = sqrt(pow(x, 2)//4 - N) +p = x//2 + disc +q = x//2 - disc +# since (p, q) can be replaced by (q, p) +assert p+q == x +assert p*q == N +pwn.log.success("calculated p and q") +pwn.log.info("p: {}".format(p)) +pwn.log.info("q: {}".format(q)) + +e = Integer(65537) +d = pow(e, -1, (p-1)*(q-1)) +pwn.log.info("calculated d: {}".format(d)) + +m = pow(c, d, N) +m_literal = pwn.pack(int(m), 'all', 'big', False) +pwn.log.success(m_literal.decode()) +