idek 2021 Writeup

I participated in idek’s 2021 CTF, playing as part of Social Engineering Experts over the weekend (Sat, 11 Dec. 2021, 08:00 SGT — Mon, 13 Dec. 2021, 08:00 SGT). In the end, we ranked 13th out of 235 scoring teams. Swept all crypto :

idek 2021 Writeup

Below are the writeups :


Challenge Category Points Solves
Idek ExponEntial Extravaganza Rev 498 5
EccRoll Crypto 484 14
Destroyted RSA Crypto 480 16
Polyphenol Crypto 465 21
Seed of Life Crypto 423 31
Hasbrown Crypto 338 45
Nameless Crypto 172 64
Rotting Fruits Crypto 100 178
Sanity Check Misc 100 193

Note : Some people solved the challenges and submitted the flag after the CTF ended. The points and solves shown above are the real numbers for solves during the duration of the CTF.



Idek ExponEntial Extravaganza

idek 2021 Writeup

Source Code :


#include <stdio.h>
#include <string.h>
#include <math.h>

int main(int argc, char** argv) {
  if(argc != 2){
    printf("Usage: ./reverseme password\n");
    return 1;
  }
  if(strlen(argv[1])!=14){
    printf("Incorrect Length\n");
    return 1;
  }
  if(*argv[1] != 112){//Not enough precision
    printf("Password Incorrect\n");
    return 1;
  }
  double magic_numbers[7] ={-68822144.50341525673866271972656250000000000000000000000000, 56777293.39031631499528884887695312500000000000000000000000, -3274524.75536667229607701301574707031250000000000000000000, -85761.51255339206545613706111907958984375000000000000000, 8443.33244327564352715853601694107055664062500000000000, -166.67369627952575683593750000000000000000000000000000, 1.00000000000000000000000000000000000000000000000000, };
  for(int i = 0; i < 6;i++){
    double foo=1.0,bar=0.0;
    for(int j=0;j<7;j++){
      bar += magic_numbers[j] * foo;
      foo *= (float)log(*(float*)((unsigned long)argv[1]+2*i));
    }
    if((int)(100000*bar) != 0){
      printf("Password Incorrect\n");
      return 1;
    }
  }
  printf("Password Correct\n");
  return 0;
}

Solve scripts :


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void) {
    printf("[");
    double magic_numbers[7] ={-68822144.50341525673866271972656250000000000000000000000000, 56777293.39031631499528884887695312500000000000000000000000, -3274524.75536667229607701301574707031250000000000000000000, -85761.51255339206545613706111907958984375000000000000000, 8443.33244327564352715853601694107055664062500000000000, -166.67369627952575683593750000000000000000000000000000, 1.00000000000000000000000000000000000000000000000000, };
    for (char c1 = 32; c1 < 127; c1++) {
        for (char c2 = 32; c2 < 127; c2++) {
            for (char c3 = 32; c3 < 127; c3++) {
                for (char c4 = 32; c4 < 127; c4++) {
                    char s[] = {c1, c2, c3, c4, 0};
                    
                    for(int i = 0; i < 6;i++){
                        double foo=1.0,bar=0.0;
                        for(int j=0;j<7;j++){
                            bar += magic_numbers[j] * foo;
                            foo *= (float)log(*(float*)((unsigned long)s+2*i));
                        }
                        if((int)(100000*bar) != 0){
                            continue;
                        }
                        else {
                            printf("b'%s', ", s);
                        }
                    }

                }
            }
        }
    }
    printf("]");
}

Output of above solver stored in this file.


table = [b'$Yn@', b'%Yn@', b'/fTw', b'0fTw', b'1fTw', b'21aL', b'2fTw', b'31aL', b'3fTw', b'41aL', b'4fTw', b'51aL', b'5fTw', b'61aL', b'6fTw', b'71aL', b'7fTw', b'81aL', b'8fTw', b'91aL', b'9fTw', b':1aL', b':fTw', b';1aL', b';fTw', b'<1aL', b'<fTw', b'=1aL', b'=fTw', b'>1aL', b'>fTw', b'?1aL', b'?fTw', b'@1aL', b'@fTw', b'A1aL', b'AfTw', b'B1aL', b'BfTw', b'C1aL', b'CfTw', b'D1aL', b'DfTw', b'E1aL', b'EfTw', b'F1aL', b'FfTw', b'G1aL', b'GfTw', b'H1aL', b'HfTw', b'I1aL', b'IfTw', b'J1aL', b'JfTw', b'K1aL', b'KfTw', b'L1aL', b'LfTw', b'M1aL', b'MfTw', b'NfTw', b'OfTw', b'PfTw', b'QfTw', b'RfTw', b'SLzf', b'SfTw', b'TLzf', b'TfTw', b'ULzf', b'UfTw', b'VLzf', b'VfTw', b'WLzf', b'WfTw', b'XLzf', b'XfTw', b'YLzf', b'YfTw', b'ZLzf', b'ZfTw', b'[Lzf', b'[fTw', b'\Lzf', b'\fTw', b']Lzf', b']fTw', b'^Lzf', b'^fTw', b'_Lzf', b'_fTw', b'`Lzf', b'`fTw', b'a0%Y', b'aLzf', b'afTw', b'b0%Y', b'bLzf', b'bfTw', b'c0%Y', b'cLzf', b'cfTw', b'd0%Y', b'dLzf', b'dfTw', b'e0%Y', b'eLzf', b'efTw', b'f0%Y', b'fLzf', b'ffTw', b'g0%Y', b'gLzf', b'gfTw', b'h0%Y', b'hLzf', b'hfTw', b'i0%Y', b'iLzf', b'ifTw', b'j0%Y', b'jLzf', b'jfTw', b'k0%Y', b'kLzf', b'kfTw', b'l0%Y', b'lLzf', b'lfTw', b'm0%Y', b'm@M1', b'mLzf', b'mfTw', b'n0%Y', b'n@M1', b'nLzf', b'nfTw', b'o0%Y', b'o@M1', b'oLzf', b'ofTw', b'p0%Y', b'p@M1', b'pLzf', b'pfTw', b'q0%Y', b'q@M1', b'qLzf', b'qfTw', b'r0%Y', b'r@M1', b'rLzf', b'rfTw', b's0%Y', b's@M1', b'sLzf', b'sfTw', b't0%Y', b't@M1', b'tLzf', b'tfTw', b'u0%Y', b'u@M1', b'uLzf', b'ufTw', b'v0%Y', b'v@M1', b'vLzf', b'vfTw', b'w0%Y', b'w@M1', b'wLzf', b'wfTw', b'x0%Y', b'x@M1', b'xLzf', b'xfTw', b'y0%Y', b'y@M1', b'yLzf', b'yfTw', b'z0%Y', b'z@M1', b'zLzf', b'zfTw', b'{0%Y', b'{@M1', b'{Lzf', b'{fTw', b'|0%Y', b'|@M1', b'|Lzf', b'|fTw', b'}0%Y', b'}@M1', b'}Lzf', b'}fTw', b'~0%Y', b'~@M1', b'~Lzf', b'~fTw', ]

print(len(table))

print([x for x in table if x[0] == 112])

print([x for x in table if x[:2] == b"%Y"])

print([x for x in table if x[:2] == b"n@"])

print([x for x in table if x[:2] == b"M1"])

print([x for x in table if x[:2] == b"aL"])

print([x for x in table if x[:2] == b"zf"])

print(b"idek{" + b'p0%Y' + b"n@" + b"M1" + b"aL" + b"zfTw" + b"}")

Flag : idek{p0%Yn@M1aLzfTw}


EccRoll

idek 2021 Writeup

Source code :


from Crypto.Util.number import bytes_to_long
import random
from secret import flag

def gen(nbits):

	p = random_prime(2^(nbits)+1, 2^(nbits))
	E = EllipticCurve(GF(p), [9487, 0])
	G = E.gens()[0]
	ord_G = G.order()

	### Remove small prime powers to avoid Pohlig-Hellman
	for i in range(2, 33):
		if ord_G % i == 0:
			G = i * G
			ord_G //= i

	### Make a relationship between generators, so it will
	### be much harder to guess the bits, right?
	g = (p - G.xy()[0])

	return p, G, g

def encrypt(bflag):

	p, G, g = gen(128)

	enc = []

	for b in bflag:
		### Haha, the outputs should be random enough 
		r = random.randint(2, p-1)
		if b == "0":
			enc += [(r * G).xy()[0]]
		else:
			enc += [pow(g, r, p)]

	return p, G, g, enc

bflag = bin(bytes_to_long(flag))[2:]

### I'm so kind, thus I'll give you 20 encryptions
for i in range(20):
	p, G, g, enc = encrypt(bflag)
	print("p = {}".format(p))
	print("G = {}".format(G))
	print("g = {}".format(g))
	print("enc = {}".format(enc))	
  

Output file can be found here.

Solve script :


from tqdm import tqdm
from Crypto.Util.number import long_to_bytes

p_list = []
G_list = []
g_list = []
enc_list = []

with open('output.txt', 'r') as f:
    lines = f.readlines()
    for i, line in enumerate(lines):
        #p
        if i % 4 == 0:
            p_list.append(Integer(line.strip().split(" = ")[1]))
        #G
        if i % 4 == 1:
            F = EllipticCurve(GF(p_list[-1]), [9487, 0])
            comps = line.strip().split(" = ")[1].split(" : ")
            comps = [x.replace("(", "").replace(")", "") for x in comps]
            G_list.append(F(Integer(comps[0]), Integer(comps[1])))
        #g
        if i % 4 == 2:
            g_list.append(Integer(line.strip().split(" = ")[1]))
        #enc
        if i % 4 == 3:
            str_list = line.strip().split(" = ")[1][1:-1].split(", ")
            enc_list.append([Integer(x) for x in str_list])

def guessBit(p, x):
    return str(int(kronecker(x, p) == -1))

guesses = []

for guess in guesses:
    print(''.join(guess))

for p, G, g, enc in list(zip(p_list, G_list, g_list, enc_list)):
    E = EllipticCurve(GF(p), [9487, 0])
    guesses.append([])
    for bit in enc:
        guess = guessBit(p, bit)
        guesses[-1].append(guess)

to_remove = []
for i, guess in enumerate(guesses):
    if '1' not in guess:
        to_remove.append(i)

for i, ind in enumerate(to_remove):
    del guesses[ind - i]

compounded = []
for i in range(len(guesses[0])):
    for guess in guesses:
        if guess[i] == '1':
            compounded.append('1')
            break
    else:
        compounded.append('0')

print(long_to_bytes(int(''.join(compounded), 2)))

#b'idek{Wh3n_b=0_X_C00rd1n4t3s_of_p01nts_w1th_0dd_0rd3rs_4r3_qu4dr4t1c_r3s1du3s!!!}'

Flag : idek{Wh3n_b=0_X_C00rd1n4t3s_of_p01nts_w1th_0dd_0rd3rs_4r3_qu4dr4t1c_r3s1du3s!!!}


Destroyed RSA

idek 2021 Writeup

Source code :


import random
from Crypto.Util.number import bytes_to_long, getPrime, isPrime
from flag import flag

f = flag

def interesting_prime():
    #recognize me?
    D = 987
    while True:
        s = random.randint(2**1020,2**1021-1)
        check = D * s ** 2 + 1
        if check % 4 == 0 and isPrime((check // 4)):
            return check // 4


m = bytes_to_long(f)
p = interesting_prime()
q = getPrime(2048)
N = p*q
e = 6551
c = pow(m, e, N)

with open('out.txt', 'w') as w:
    w.write(f"n = {N}")
    w.write(f"e = {e}")
    w.write(f"c = {c}")
    

Output file can be found here.

Solve script :


from sage.all import *
from math import gcd
import sys
from Crypto.Util.number import *
from tqdm import tqdm

sys.setrecursionlimit(100000)

def polynomial_xgcd(a, b):
    """
    Computes the extended GCD of two polynomials using Euclid's algorithm.
    :param a: the first polynomial
    :param b: the second polynomial
    :return: a tuple containing r, s, and t
    """
    assert a.base_ring() == b.base_ring()

    r_prev, r = a, b
    s_prev, s = 1, 0
    t_prev, t = 0, 1

    while r:
        try:
            q = r_prev // r
            r_prev, r = r, r_prev - q * r
            s_prev, s = s, s_prev - q * s
            t_prev, t = t, t_prev - q * t
        except RuntimeError:
            raise ArithmeticError("r is not invertible", r)

    return r_prev, s_prev, t_prev

def polynomial_inverse(p, m):
    """
    Computes the inverse of a polynomial modulo a polynomial using the extended GCD.
    :param p: the polynomial
    :param m: the polynomial modulus
    :return: the inverse of p modulo m
    """
    g, s, t = polynomial_xgcd(p, m)
    return s * g.lc() ** -1

def factorize(N, D):
    """
    Recovers the prime factors from a modulus using Cheng's elliptic curve complex multiplication method.
    More information: Sedlacek V. et al., "I want to break square-free: The 4p - 1 factorization method and its RSA backdoor viability"
    :param N: the modulus
    :param D: the discriminant to use to generate the Hilbert polynomial
    :return: a tuple containing the prime factors
    """
    assert D % 8 == 3, "D should be square-free"

    zmodn = Zmod(N)
    pr = zmodn["x"]

    H = pr(hilbert_class_polynomial(-D))
    Q = pr.quotient(H)
    j = Q.gen()

    try:
        k = j * polynomial_inverse((1728 - j).lift(), H)
    except ArithmeticError as err:
        # If some polynomial was not invertible during XGCD calculation, we can factor n.
        p = gcd(int(err.args[1].lc()), N)
        return int(p), int(N // p)

    E = EllipticCurve(Q, [3 * k, 2 * k])
    while True:
        x = zmodn.random_element()

        #print(f"Calculating division polynomial of Q{x}...")
        z = E.division_polynomial(N, x=Q(x))

        try:
            d, _, _ = polynomial_xgcd(z.lift(), H)
        except ArithmeticError as err:
            # If some polynomial was not invertible during XGCD calculation, we can factor n.
            p = gcd(int(err.args[1].lc()), N)
            return int(p), int(N // p)

        p = gcd(int(d), N)
        if 1 < p < N:
            return int(p), int(N // p)

n = 1107089530865291005792928480548189885479977703442107533313356742591951667125087535826010797157037462511849114045516095117408586807231706532861043400760247491545435256670371588020835746662537074526723641129179212527096161455117334264697975671817050553066298766943783138197527420889207777538892682506714149210612017224796083819420558023833783052917520724666512823601961316820680461331809092698744718706733677296285030329390980535993866209005527261307419128592439300515586162373258781346476786339580690681056167085317745381659204404735103663112312693895151699459534695810700103198736323229849182269856798173444808702578924983265251814786149856862410628895786620259450924651662102926294106305830166586486290823127164862167085238586221495862582249250498351063486438791642573599997108715545357001141390463446119948917429169048381714872075664706511363903028841832059662969788526342879432038294204060254076089346916015904423832151508649589004393115281760187305175538986217342069866841444503926477979016789070563231454129660241269241703644048193901022392096029852555194381071481792694321652042639278577632914177886450520371875549477493674646527815335341293227066407822982856815277497965140254717599437693337147736442753971955722420621907486011
e = 6551
c = 1058973149865164549817155137780815812623456388672543624635614085499244505987561039674767711743995552767627702752408380616883846211075499731545623651849875151404363710832001498313789374024771997636035858261588415813326816005995068929381352608925142940988357078368871961040798086164564448858106053108740194519944625550651430368864502736439474454098320996590422347650921528404245531928248700516748854749201075928521539792773428322450795957658901093109369813686410937987553062385702498313602204488073904351501964183374202465473380985602391885101503608627656341003137115517005592591746184951205036757837506166599417314523057848473058411480339477693062957272869601856015496182168433136199994935250109784152100245527161736252507193119985157036229139371883973535111593404077185046749750799222687057579590699112612517984739574870394435873979331373499970168615775526148858445852147161884965435806142797327740412603655959161046424598064190354357612721920648035385092037901968197029138094288551013982417040611621259974923351358663093743109476722870043782424356300204605852351738436494837101112320000689343206094235482366575795725469918145189121430260345459865260920783660140849521053205162497433393126952425091234633490186637000777737106192645410
D = 987

p, q = factorize(n, D)

assert p*q == n

def roots_of_unity(e, phi, n, rounds=250):
    # Divide common factors of `phi` and `e` until they're coprime.
    phi_coprime = phi
    while gcd(phi_coprime, e) != 1:
        phi_coprime //= gcd(phi_coprime, e)

    # Don't know how many roots of unity there are, so just try and collect a bunch
    roots = set(pow(i, phi_coprime, n) for i in range(1, rounds))

    assert all(pow(root, e, n) == 1 for root in roots)
    return roots, phi_coprime

# n is prime
# Problem: e and phi are not coprime - d does not exist
phi = (p - 1) * (q-1)

# Find e'th roots of unity modulo n
roots, phi_coprime = roots_of_unity(e, phi, n)

# Use our `phi_coprime` to get one possible plaintext
d = inverse_mod(e, phi_coprime)
pt = pow(c, d, n)
assert pow(pt, e, n) == c

# Use the roots of unity to get all other possible plaintexts
pts = [(pt * root) % n for root in roots]
pts = [long_to_bytes(pt) for pt in pts]

for pt in pts:
    if b'idek' in pt: 
        print(pt)

#b'idek{A_mashup_of_2_interesting_papers?_4p-1_and_coprime_e-phi}'

Got first blood :D

idek 2021 Writeup

Flag : idek{A_mashup_of_2_interesting_papers?_4p-1_and_coprime_e-phi}


Polyphenol

idek 2021 Writeup

Source code :


import random
from secret import flag

assert flag[: 5] == b"idek{"
assert flag[-1:] == b"}"

L = len(flag[5: -1])
print(f"L = {L}")
coeff = list(flag[5: -1])
points = random.sample(range(L), L // 2)
evaluations = []

for p in points:
	evaluations += [sum(c * p ** i for i, c in enumerate(coeff))]

print(f"points = {points}")
print(f"evaluations = {evaluations}")

Output file can be found here.

Solve script :


from sage.modules.free_module_integer import IntegerLattice

# Directly taken from rbtree's LLL repository
# From https://oddcoder.com/LOL-34c3/, https://hackmd.io/@hakatashi/B1OM7HFVI
def Babai_CVP(mat, target):
	M = IntegerLattice(mat, lll_reduce=True).reduced_basis
	G = M.gram_schmidt()[0]
	diff = target
	for i in reversed(range(G.nrows())):
		diff -=  M[i] * ((diff * G[i]) / (G[i] * G[i])).round()
	return target - diff


def solve(mat, lb, ub, weight = None):
	num_var  = mat.nrows()
	num_ineq = mat.ncols()

	max_element = 0 
	for i in range(num_var):
		for j in range(num_ineq):
			max_element = max(max_element, abs(mat[i, j]))

	if weight == None:
		weight = num_ineq * max_element

    # sanity checker
	if len(lb) != num_ineq:
		print("Fail: len(lb) != num_ineq")
		return

	if len(ub) != num_ineq:
		print("Fail: len(ub) != num_ineq")
		return

	for i in range(num_ineq):
		if lb[i] > ub[i]:
			print("Fail: lb[i] > ub[i] at index", i)
			return

    	# heuristic for number of solutions
	DET = 0

	if num_var == num_ineq:
		DET = abs(mat.det())
		num_sol = 1
		for i in range(num_ineq):
			num_sol *= (ub[i] - lb[i])
		if DET == 0:
			print("Zero Determinant")
		else:
			num_sol //= DET
			# + 1 added in for the sake of not making it zero...
			print("Expected Number of Solutions : ", num_sol + 1)

	# scaling process begins
	max_diff = max([ub[i] - lb[i] for i in range(num_ineq)])
	applied_weights = []

	for i in range(num_ineq):
		ineq_weight = weight if lb[i] == ub[i] else max_diff // (ub[i] - lb[i])
		applied_weights.append(ineq_weight)
		for j in range(num_var):
			mat[j, i] *= ineq_weight
		lb[i] *= ineq_weight
		ub[i] *= ineq_weight

	# Solve CVP
	target = vector([(lb[i] + ub[i]) // 2 for i in range(num_ineq)])
	result = Babai_CVP(mat, target)

	for i in range(num_ineq):
		if (lb[i] <= result[i] <= ub[i]) == False:
			print("Fail : inequality does not hold after solving")
			break
    
    	# recover x
	fin = None

	if DET != 0:
		mat = mat.transpose()
		fin = mat.solve_right(result)
	
	## recover your result
	return result, applied_weights, fin

L = 34
points = [4, 26, 22, 30, 1, 0, 2, 28, 23, 6, 25, 15, 5, 17, 14, 3, 13]
evaluations = [6218619148819094267912, 3239660278168289094170378865781537878483145039862, 13167423991006904868698304825721530103488567362, 362300164581366743933077318596814390341728710066538, 2912, 68, 1115908868222, 37269531510352347514290324712333731253807861642016, 56973337294691266392513915302684316231304471586, 3613524058959314538010460402, 889396341293302641051808753025749133146757798168, 43685960244566626421146033917835089685178, 9183044381254551882537188, 2694648608589552169772471076958756166751152, 4505915953382938147124977926390455694362, 529597204775372366, 392892826701163426612412172019222254476]

M1 = identity_matrix(L)
M2 = Matrix([list(map(lambda x: x^i, points)) for i in range(L)])
M = M1.augment(M2)

lb = [32] * L + evaluations
ub = [126] * L + evaluations

res, weights, _ = solve(M, lb, ub)

print("idek{", ''.join([chr(x) for x in res[:L]]), "}", sep="")

#idek{D1d_y0u_s34rch_7h1s_p0ly_6y_LLL???}

Flag : idek{D1d_y0u_s34rch_7h1s_p0ly_6y_LLL???}


Seed of Life

idek 2021 Writeup

Source code :


import random

seed = REDACTED
assert seed in range(10000000)
random.seed(seed)
for i in range(19):
	random.seed(random.random())
seedtosave = random.random()
print("share1:")
for add in range(0, 1000):
	random.seed(seedtosave+add)
	for i in range(0, 100):
		print(random.random())
print("share2:")
for add in range(0, 1000):
	random.seed(seedtosave-add)
	for i in range(0, 1000):
		print(random.random())
print("share3:")
random.seed(seedtosave)
for i in range(0, 100):
	print(random.random()*100)
  

Output file can be found here.

Solve script :


import random
from tqdm import tqdm
from Crypto.Util.number import *

for seed in tqdm(range(10000000)):

    random.seed(seed)
    toBreak = False

    for i in range(19):
        random.seed(random.random())

    seedtosave = random.random()

    for add in range(0, 1000):
        random.seed(seedtosave+add)
        for i in range(0, 100):
            temp = random.random()
            if add == 0 and i == 0 and temp != 0.5327486342598738:
                toBreak = True
                break

        if toBreak:
            break

    if toBreak:
        continue

    for add in range(0, 1000):
        random.seed(seedtosave-add)
        for i in range(0, 1000):
            random.random()

    random.seed(seedtosave)
    for i in range(0, 100):
        t = random.random()*100

    if t == 83.74981977975804:
        print("idek{", seed, "}", sep="")
        exit()

#idek{103123}

Flag : idek{103123}


Hashbrown

idek 2021 Writeup

Source code :


import string
import hashlib
import random

password2hash = b"REDACTED"
hashresult = hashlib.md5(password2hash).digest()
sha1 = hashlib.sha1(hashresult)
sha224 = hashlib.sha224(sha1.digest())
for i in range(0, 10):
	sha1 = hashlib.sha1(sha224.digest())
	sha224 = hashlib.sha224(sha1.digest())
output = sha224.hexdigest()
print("output: " + output)

Output file can be found here.

Solve script :


import string
import hashlib
import random
from tqdm import tqdm

possibleChars = list(chr(i).encode() for i in range(32, 127))

for c1 in tqdm(possibleChars):
    for c2 in possibleChars:
        for c3 in possibleChars:
            for c4 in possibleChars:
                password2hash = c1 + c2 + c3 + c4
                hashresult = hashlib.md5(password2hash).digest()
                sha1 = hashlib.sha1(hashresult)
                sha224 = hashlib.sha224(sha1.digest())
                for i in range(0, 10):
                    sha1 = hashlib.sha1(sha224.digest())
                    sha224 = hashlib.sha224(sha1.digest())
                output = sha224.hexdigest()
                if output == "9ee2275f8699c3146b65fabc390d83df5657a96c39ab58933f82d39b":
                    print("idek{", password2hash.decode(), "}", sep="")
                    #idek{WDOb}
                    exit()

Flag : idek{WDOb}


Nameless

idek 2021 Writeup

Source code :


#!/usr/bin/env python3

from Crypto.Util.number import getPrime, bytes_to_long

flag = bytes_to_long(open("flag.txt", "rb").read())

p = getPrime(1024)
q = getPrime(1024)

n = p*q
e = 65537

c = pow(flag, e, n)

print(f"{n = }")
print(f"{p**2 + q**2 = }")
print(f"{c = }")

# n = 17039353907577304435335064263404014554877715060984532599266619880863167873378099082282744647069063737519071263364836126585022715467571812084451441982393173641398961475914685815327955647115633127041896154455593434072255425400800779717723399468604805292082232853055652824142503280033249169812067036520117578584094798348819948005306782099055133323817492597665553443090585282100292603079932759878536941929823231580881942192749039900111873581375554659251791337260557811529597205007196563571790350676229812320194120553090511341491088451472118285832059742983329898372623700182290118257197824687682775782009980169859003817731
# p**2 + q**2 = 34254734236141177160574679812056859631858427160408786991475995766265871545173190051194038767461225382849521482292062983459474860288453334280315736001800236347672807900333594896297515619502911996316514299218938831378736595562870019767614772735193898275208842936903810908125651716713945099823849942766283224215669363078687494444967371294251548767512167452469907361824731739495988324619487099803563636546009036759134670516039262088500254966964852889263176272377467365967151127628965809347292638988052064278479647751273833336918088826074446862207626964731876317800211831559603043730904022957158490478667914769698472788362
# c = 12870370380105677159569686874593314643716517767455659912764832987663831817849402722874771360315463499459803247514426078866675686952348433836656840934671927466173330528381359767745015167610939855705805470288376941237662107279159556248387485524451540986787953598577323572841487131458590546170321983597795128547549803960136942090569419458036728363613060710384550676895546741408072019046530957103700345379626982758919062223712005709765751343132802610106335253368313457365776378662756844353849622352138042802036310704545247436297860319183507369367717753569233726139626694256257605892684852784606001755037052492614845787835

Solve script :


from Crypto.Util.number import *

n = 17039353907577304435335064263404014554877715060984532599266619880863167873378099082282744647069063737519071263364836126585022715467571812084451441982393173641398961475914685815327955647115633127041896154455593434072255425400800779717723399468604805292082232853055652824142503280033249169812067036520117578584094798348819948005306782099055133323817492597665553443090585282100292603079932759878536941929823231580881942192749039900111873581375554659251791337260557811529597205007196563571790350676229812320194120553090511341491088451472118285832059742983329898372623700182290118257197824687682775782009980169859003817731
p2q2 = 34254734236141177160574679812056859631858427160408786991475995766265871545173190051194038767461225382849521482292062983459474860288453334280315736001800236347672807900333594896297515619502911996316514299218938831378736595562870019767614772735193898275208842936903810908125651716713945099823849942766283224215669363078687494444967371294251548767512167452469907361824731739495988324619487099803563636546009036759134670516039262088500254966964852889263176272377467365967151127628965809347292638988052064278479647751273833336918088826074446862207626964731876317800211831559603043730904022957158490478667914769698472788362
c = 12870370380105677159569686874593314643716517767455659912764832987663831817849402722874771360315463499459803247514426078866675686952348433836656840934671927466173330528381359767745015167610939855705805470288376941237662107279159556248387485524451540986787953598577323572841487131458590546170321983597795128547549803960136942090569419458036728363613060710384550676895546741408072019046530957103700345379626982758919062223712005709765751343132802610106335253368313457365776378662756844353849622352138042802036310704545247436297860319183507369367717753569233726139626694256257605892684852784606001755037052492614845787835

pPlusq = sqrt(p2q2 + 2*n)

P.<x> = PolynomialRing(ZZ, 'x')
quad = x^2 - pPlusq*x + n
roots = quad.roots()
p, q = int(roots[0][0]), int(roots[1][0])

assert p*q == n

e = 65537
phi = (p-1)*(q-1)
d = inverse(e, phi)
m = pow(c, d, n)
print(long_to_bytes(int(m)))

#b'idek{crypt0_1s_just_m4th_23b984a1}\n'

Flag : idek{crypt0_1s_just_m4th_23b984a1}


Rotting Fruits

idek 2021 Writeup

Flag : idek{rot13_is_kinda_kewl_ngl}


Sanity Check

idek 2021 Writeup

Flag : idek{let_the_games_begin!}