CTF Challenge Name Solves (Difficulty)
Google CTF 2022 Cycling 🔥 50/382 (⭐⭐)
Google CTF 2022 Electric Mayhem CLS 70/382 (⭐⭐)
Google CTF 2022 Maybe Someday 35/382 (⭐⭐⭐)
Google CTF 2022 Enigma 9/382 (⭐⭐⭐)
Google CTF 2022 Custom Protocol 🔥 5/382 (⭐⭐⭐)
Google CTF 2022 Electric Mayhem PQC 🔥 3/382 (⭐⭐⭐⭐)
Crypto CTF 2022 Aniely 76/421 (⭐)
Crypto CTF 2022 Watery soup 🔥 15/421 (⭐⭐⭐)
Crypto CTF 2022 Oak land 35/421 (⭐⭐)
Crypto CTF 2022 polyRSA 145/421 (⭐)
Crypto CTF 2022 313 Loyal 17/421 (⭐⭐)
Crypto CTF 2022 Cantilever 60/421 (⭐⭐)
Crypto CTF 2022 Side step 28/421 (⭐⭐)
Crypto CTF 2022 Faonsa 21/421 (⭐⭐)
Crypto CTF 2022 Resign 35/421 (-)
Crypto CTF 2022 DBB 43/421 (⭐⭐)
Crypto CTF 2022 Soda 🔥 17/421 (⭐⭐⭐)
Crypto CTF 2022 Sparse 38/421 (⭐⭐)
Crypto CTF 2022 Fiercest 29/421 (⭐⭐)
Crypto CTF 2022 Persian cat 13/421 (⭐)
Crypto CTF 2022 Keydream 42/421 (⭐⭐)
Crypto CTF 2022 NLCS 🔥 5/421 (⭐⭐⭐)
Crypto CTF 2022 Shaim 15/421 (⭐⭐)
Crypto CTF 2022 Lagima 24/421 (⭐)
Crypto CTF 2022 Starter ECC 43/421 (⭐)
Crypto CTF 2022 Versace 15/421 (⭐⭐)
Crypto CTF 2022 GSDP 24/421 (⭐⭐)
UIUCTF 2022 asr 56/395 (⭐⭐)
UIUCTF 2022 Wringing Rings 44/395 (⭐⭐)
UIUCTF 2022 Elliptic Clock Crypto 27/395 (⭐⭐)
UIUCTF 2022 mom can we have AES 22/395 (⭐⭐)
UIUCTF 2022 That-crete Log 21/395 (⭐⭐)
UIUCTF 2022 Bro-key-n 14/395 (⭐⭐)
corCTF 2022 tadpole 262/978 (⭐)
corCTF 2022 luckyguess 150/978 (⭐⭐)
corCTF 2022 exchanged 94/978 (⭐⭐)
corCTF 2022 hidE 88/978 (⭐⭐)
corCTF 2022 generous 49/978 (⭐⭐)
corCTF 2022 leapfrog 36/978 (⭐⭐)
corCTF 2022 corrupted-curves 20/978 (⭐⭐⭐)
corCTF 2022 threetreasures 19/978 (⭐⭐⭐)
corCTF 2022 corrupted-curves+ 🔥 15/978 (⭐⭐⭐)
corCTF 2022 rlfsr 14/978 (⭐⭐⭐)
corCTF 2022 D3S 🔥 1/978 (⭐⭐⭐⭐)

Google CTF 2022

Cycling 🔥

We are given a RSA public key $(n, e)$ and $c_0$, the ciphertext of $m_0$ (the flag). If we denote $(m, c)$ be a message-ciphertext pair, then $c = \text{Enc}(m) := m^e\ \text{mod}\ n$. Given also

$$\text{Enc}^{2^{1025} - 3}(c) := \underbrace{\text{Enc}(\text{Enc}(…\text{Enc}}_{\text{Enc applied}\ 2^{1025}-3\ \text{times}}(c))) = m.$$

The objective is to recover $m_0$.

Electric Mayhem CLS

🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Maybe Someday

We are given a public key of Paillier cryptosystem $(n, g)$, and is asked to complete 16 rounds of challenge $\mathcal{C}$. In each round of $\mathcal{C}$:

  1. The server generates a random $s$, which of two bytes long.
  2. The server $m_0 := \text{SHA512}(s)$.
  3. The server encrypts a PKCSv1.5-padded $m_0$ with the public key $(n, g)$ and sends its ciphertext $c_0$ to the player.
  4. The player sends $c_1, c_2, …, c_{20}$ to the server.
  5. The server checks and tells the player if each of the corresponding $m_i$’s is PKCSv1.5-compliant.
  6. The player sends $\hat{m_0}$ to the server. If $\hat{m_0} = m_0$, the player wins this round.

The objective for the player is to win 16 rounds of $\mathcal{C}$ for the flag.

Enigma

🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Custom Protocol 🔥

🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Electric Mayhem PQC 🔥

  • Solves: 3/382
  • Difficulty: ⭐⭐⭐⭐
  • Tags: kyber512, power analysis
  • Source: Official Repository
🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Crypto CTF 2022

Aniely

Define the aniely_encrypt function as below:

def aniely_stream(passphrase):
	def mixer(u, v):
		return ((u << v) & 0xffffffff) | u >> (32 - v)

	def forge(w, a, b, c, d):
		for i in range(2):
			w[a] = (w[a] + w[b]) & 0xffffffff
			w[d] = mixer(w[a] ^ w[d], 16 // (i + 1))
			w[c] = (w[c] + w[d]) & 0xffffffff
			w[b] = mixer(w[b] ^ w[c], (12 + 2*i) // (i + 1))

	bring = [0] * 16
	bring[:4] = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]
	bring[4:12] = unpack('<8L', passphrase)
	bring[12] = bring[13] = 0x0
	bring[14:] = [0] * 2

	while True:
		w = list(bring)
		for _ in range(10):
			forge(w, 0x0, 0x4, 0x8, 0xc)
			forge(w, 0x1, 0x5, 0x9, 0xd)
			forge(w, 0x2, 0x6, 0xa, 0xe)
			forge(w, 0x3, 0x7, 0xb, 0xf)
			forge(w, 0x0, 0x5, 0xa, 0xf)
			forge(w, 0x1, 0x6, 0xb, 0xc)
			forge(w, 0x2, 0x7, 0x8, 0xd)
			forge(w, 0x3, 0x4, 0x9, 0xe)
		for c in pack('<16L', *((w[_] + bring[_]) & 0xffffffff for _ in range(16))):
			yield c
		bring[12] = (bring[12] + 1) & 0xffffffff
		if bring[12] == 0:
			bring[13] = (bring[13] + 1) & 0xffffffff

def aniely_encrypt(msg, passphrase):
	if len(passphrase) < 32:
		passphrase = (passphrase * (32 // len(passphrase) + 1))[:32]
	rand = urandom(2) * 16
	return bytes(a ^ b ^ c for a, b, c in zip(msg, aniely_stream(passphrase), rand))

We are given $\text{key} = \text{passphrase} \oplus \text{flag}$ and $c = \text{AnielyEncrypt}(\text{passphrase}, \text{key})$. The goal is to recover $\text{flag}$.

Watery soup 🔥

The server has a secret $f \in [2^{256}, 2^{511})$. We can send many pairs of $(p, g)$ ($p \in [2^{127}, 2^{224})$ being a prime and $g \in [2^{64}, 2^{127})$) and obtain $r$, with

$$r = [(g^3f)^{f-g} \cdot f + f^2 + g]\ \text{mod}\ p.$$

The goal is to recover $f$ (the flag).

Oak land

We are given $p$, $e$, $f$, $g$ and $c$ as below:

p = 7389313481223384214994762619823300589978423075857540712007981373887018860174846208000957230283669342186460652521580595183523706412588695116906905718440770776239313669678685198683933547601793742596023475603667
e = 31337
f = 7236042467316654159796543399639966340258093274047941788600980451877044636122969830708918356119442228154447395855689559447196348683125675305629837437591088260218138895919514078948650757100432223219969122629790
g = 1878626136321051642174045874618248475160620873585704351202865003185878331837410979441756843820270907300810543618813757245154196050399357659526631164136221434463496532263979506870318259276669412698827040743576
c = 871346503375040565701864845493751233877009611275883500035764036792906970084258238763963152627486758242101207127598485219754255161617890137664012548226251138485059295263306930653899766537171223837761341914356

We are also given the relation

$$c \equiv 110 e^x + 313 f^x + 114 g^x\ (\text{mod}\ p).$$

The goal is to find $x$.

polyRSA

We are given the RSA public key $(n, e = 31337)$ and the encrypted flag $c$:

n = 44538727182858207226040251762322467288176239968967952269350336889655421753182750730773886813281253762528207970314694060562016861614492626112150259048393048617529867598499261392152098087985858905944606287003243
c = 37578889436345667053409195986387874079577521081198523844555524501835825138236698001996990844798291201187483119265306641889824719989940722147655181198458261772053545832559971159703922610578530282146835945192532

Given that the primes for the modulus, $p, q$, are given by

$$\left\{ \begin{aligned} p &= k^6 + 7k^4 - 40k^3 + 12k^2 - 114k + 31377 \\ q &= k^5 - 8k^4 + 19k^3 - 313k^2 - 14k + 14011 \end{aligned} \right. $$

313 Loyal

When connected to the server, $x_1, x_2, …, x_k$ are generated such that

  1. $x_1 < x_2 < … < x_k$, and
  2. $x_i = 2^{10} r_i + f_i$ for $i = 1, 2, …, k$ where $r_i \in [2, 2^{64})$ is random and $f_i$ is the $i$-th character of the flag.

We can send multiple pairs of $(n, g, p)$ with $n \geq 2^{256}$, $g \in \mathbb{Z}$ and $p(x) = \sum p_i x^i$ being a polynomial, and the server will return a shuffled list of $(c_1, c_2, …, c_k)$, where

$$c_i := \left(\prod {p_i}^{x^i}\right)^{s_i} g^m \cdot r^n\ \text{mod}\ n^2$$

with $s_i \in [2, n)$ being random. The objective is to recover the flag $(f_1, f_2, …, f_k)$.

Cantilever

We are given a RSA public key $(n, e = 65537)$ and $c_1, c_2$ defined below.

n = 7069789930583271525053215046247773438899869283661158227309691853515987055334306019600324056376312479212090202373516405860759222837585952590589336295698718699890424169542280710721069784487366121478569760563045886361884895363592898476736269784284754788133722060718026577238640218755539268465317292713320841554802703379684173485217045274942603346947299152498798736808975912326592689302969859834957202716983626393365387411319175917999258829839695189774082810459527737342402920881184864625678296442001837072332161966439361793009893108796934406114288057583563496587655548536011677451960307597573257032154009427010069578913
c1 = 488692928085934899944055554857568564903346089951134051486941368561567330884363274156339625953702601270565654444836193796061118053575538224794730472032345171432952984560662218697488844007827176184413713651118743456250147472678673801728916283759932987216388378211555067885210167894310696549664382751443669387953644382833924884208966436685137553434532738845959014828804809425096115758364136546390809453200055265653531950423111482644330073443545410319576097902472017235065047191133112557289289189187696092145850680765843608118584107829268136014912479701945735063525799796920293418182776436767911172221104640501952880057
c2 = 109770827223661560471527567179288748906402603483328748683689436879660543465776899146036833470531024202351087008847594392666852763100570391337823820240726499421306887565697452868723849092658743267256316770223643723095601213088336064635680075206929620159782416078143076506249031972043819429093074684182845530529249907297736582589125917235222921623698038868900282049587768700860009877737045693722732170123306528145661683416808514556360429554775212088169626620488741903267154641722293484797745665402402381445609873333905772582972140944493849645600529147490903067975300304532955461710562911203871840101407995813072692212

Additionally, the prime factors of $n$, namely $p$ and $q$, are given by

$$p = 2 r_1 r_2 … r_u + 1\ \text{and}\ q = 2 s_1 s_2 … s_v + 1,$$

where $r_1, …, r_u, s_1, …, s_v$ are all primes (less than $2^{20}$). Also, $c_1$ and $c_2$ are given by

$$\left\{\begin{aligned} c_1 &= {m_1}^e\ \text{mod}\ n \\ c_2 &= e^{m_2}\ \text{mod}\ n \end{aligned}\right.,$$

where $m_1$ and $m_2$ are two parts of the flag. The goal is to recover $m_1$ and $m_2$.

Side step

Let $p = 2^{1024} - 2^{234} - 2^{267} - 2^{291} - 2^{403} - 1$.

When connected to the server, a secret $s \in [2, (p-1)/2]$ is randomly generated and is kept secret. We can send quadratic residues $g$ to the server and it returns the value of pow_d(g, s, p) defined below:

def pow_d(g, e, n):
	t, r = 0, 1
	for _ in bin(e)[2:]:
		if r == 4: t += 1
		r = pow(r, 2, n)
		if _ == '1': r = r * g % n
	return t, r

The objective is to send $g$ to the server such that $g^s\ \text{mod}\ p = 4$.

Faonsa

Note. This challenge is known having an unintended solution. That said, the number of solves may not reflect the actual difficulty.

When connected to the server, a 256-bit safe prime $p$ (i.e., $p = 2q+1$ where $q$ is also a prime), a primitive root $g \in \mathbb{Z}_p$ and a random $x \in [2, p/2)$ are generated. Define also $y = g^x\ \text{mod}\ p$.

We are given $(p, g, y)$ (ElGamal public key). Denote $P = p$ and $Y = y$. We can perform the three operations:

  1. [Apply Fault] Flip up to 30 bits of $p$ and make it the new $P$. Set $Y = g^x\ \text{mod}\ P$.
  2. [Sign] Sign an arbitrary message $m\ (\neq m_0)$ with the ElGamal key $x, (P, g, Y)$.
  3. [Verify] Verify the signature $(m, s)$ using the public key $(P, g, Y)$. Additionally, if the signature is valid and $m = m_0$, the server will also send the flag.

The goal is to obtain the flag using the verify operation.

Resign

We are given a message $m$ and a signature $s$. The objective is to generate a RSA key such that the $s$ is a signature of the message $m$.

DBB

Let $P$ and $Q$ be points over elliptic curve $\mathcal{C}$, with $Q = m \cdot P$ ($m < n$) and

$$\mathcal{C}: y^2 \equiv x^3 + ax + b\ (\text{mod}\ n).$$

We are given $n$, $P_x$, $Q_x$ and $Q_y$. The goal is to find $m$.

n = 34251514713797768233812437040287772542697202020425182292607025836827373815449
Px = 7331
Qx = 10680461779722115247262931380341483368049926186118123639977587326958923276962
Qy = 4003189979292111789806553325182843073711756529590890801151565205419771496727

Soda 🔥

Note. This challenge is known having an unintended solution. That said, the number of solves may not reflect the actual difficulty.

A pair secret $p, q$ is determined and used for all remote connections. We are given $n = pq$, $g = 31337$ and $m_0 \approx 2^{159}$. We can also send $s\ (\neq m_0)$ to the server and it computes soda(g, p, q, s), defined below:

def soda(g, p, q, m):
	n, phi = p * q, (p - 1) * (q - 1)
	if isPrime(m) and m.bit_length() <= 128:
		e = m
	else:
		e = 2 * (pow(g, m**2, n) % 2**152) ^ 1
	if GCD(e, phi) == 1:
		d = inverse(e, phi)
		return pow(g, d, n)

The objective is to find $s$ such that $s^e\ \text{mod}\ n = g$, where e = 2 * (pow(g, m0**2, n) % 2**152) ^ 1.

Sparse

Let $p$ and $q$ be the two 417-bit prime factors of the RSA public modulus $n$ such that

$$q = p + \sum_{i=1}^5 r_i \cdot 2^{b_i},$$

where $r_i \in \{-1, 0, 1\}$ and $b_i \in \{3, …, 413\}$ for $i = 1, 2, 3, 4, 5$. We are given the RSA public key $(n, e = 65537)$ and the ciphertext $c$ (encrypted by the RSA key). The objective is to decrypt $c$ for the flag.

Fiercest

Note. This challenge is known having an unintended solution. That said, the number of solves may not reflect the actual difficulty.

When connected to the server, a 1024-bit RSA modulus $n$ is generated. We are given $n, e = 65537$ as the RSA public key. Denote $N = n$. We can perform the two operations:

  1. [Apply Fault] Flip up to 2 bits of $n$ and set it as the new $N$.
  2. [Verify] Verify the signature $(m, s)$ using the public key $(N, e)$. Additionally, if the signature is valid and $m = m_0$, the server will also send the flag.

The goal is to obtain the flag using the verify operation.

Persian cat

  • Solves: 13/421
  • Difficulty: ⭐
  • Tags: block cipher, custom cipher
  • Author: @refactoreal, @y3noor
Note. This challenge is known having an unintended solution. That said, the number of solves may not reflect the actual difficulty.

The challenge implements a custom cipher (code below). The server keeps a secret key (namely skey) and we are allowed to send m (needs to be ASCII-printable). We will obtain encrypt(m + flag, skey).

The objective is to recover flag.


Omega = [
		0x4e, 0x96, 0xfd, 0x7d, 0x8d, 0xf6, 0xdb, 0x33, 0x1e, 0x16, 0x9b, 0x6a, 0xe2, 0xc9, 0xa9, 0xe0, 
		0x34, 0xe6, 0x86, 0xd6, 0x52, 0x02, 0x25, 0x1f, 0x23, 0xdf, 0xd5, 0x12, 0x45, 0x6b, 0x6f, 0x4d, 
		0x31, 0x77, 0x09, 0xbf, 0x93, 0xca, 0x4b, 0xef, 0xee, 0x7c, 0x53, 0x1a, 0xc8, 0xea, 0x9d, 0xda, 
		0x32, 0xa4, 0x11, 0x7b, 0xd8, 0x3f, 0x13, 0x57, 0x75, 0xcb, 0x37, 0x9a, 0x83, 0xa5, 0x3e, 0xd3, 
		0x4a, 0x1d, 0x29, 0xb9, 0x18, 0x27, 0x2d, 0x0f, 0x15, 0x0d, 0x66, 0xae, 0xf5, 0xfa, 0x08, 0x9f, 
		0xc6, 0x55, 0xa0, 0xb7, 0x28, 0x0e, 0xf4, 0x01, 0x04, 0x46, 0xf9, 0x39, 0xe3, 0x7f, 0x5e, 0x61, 
		0x40, 0x26, 0xec, 0xb6, 0x14, 0xf0, 0x59, 0x50, 0xcf, 0x3a, 0x8b, 0x43, 0xaf, 0x10, 0xe5, 0xe8, 
		0x03, 0xbd, 0x51, 0xa7, 0x1c, 0x8e, 0x7a, 0x98, 0x3c, 0xeb, 0xac, 0x54, 0x84, 0xf7, 0x62, 0x88, 
		0x64, 0xa8, 0xbb, 0xab, 0xe1, 0x95, 0x94, 0x41, 0x2a, 0x60, 0x30, 0xcc, 0x48, 0xd2, 0x89, 0xb2, 
		0x65, 0x76, 0x0a, 0xb8, 0x56, 0x4f, 0xc3, 0x87, 0xdd, 0x4c, 0xc2, 0xd4, 0x82, 0x35, 0x90, 0xa2, 
		0x5f, 0xad, 0x19, 0x74, 0x73, 0xd0, 0x24, 0x69, 0x20, 0x07, 0xdc, 0x1b, 0x44, 0x58, 0xff, 0x5a, 
		0x6c, 0xf2, 0xfb, 0x8c, 0x79, 0x97, 0xa6, 0x22, 0xb4, 0x7e, 0x5b, 0x17, 0x2f, 0x91, 0x71, 0xfe, 
		0x38, 0xa3, 0x05, 0xb1, 0xba, 0x99, 0xd9, 0xf1, 0x21, 0x5c, 0x67, 0x6d, 0xde, 0xaa, 0xc7, 0x8f, 
		0x81, 0x0b, 0xb0, 0xbc, 0x0c, 0xcd, 0x63, 0xc1, 0xfc, 0xc0, 0x42, 0x78, 0xc5, 0x8a, 0x06, 0x3d, 
		0x2e, 0x9e, 0xa1, 0x80, 0xb3, 0xf8, 0xe9, 0x68, 0xd1, 0x36, 0x70, 0x49, 0xc4, 0xd7, 0x2c, 0x6e, 
		0xe7, 0xb5, 0xbe, 0x92, 0xce, 0xed, 0xf3, 0x9c, 0xe4, 0x3b, 0x47, 0x2b, 0x85, 0x5d, 0x72, 0x01
		]

def padding(msg):
	if len(msg) % 32 != 0:
		extra = '*' * (32 - len(msg) % 32)
		return msg + extra
	else:
		return msg

def keygen(u, v):
	return [a ^ b for a, b in zip(u, v)][:20]

def roadrunner(table, roadrunner_wile, lili, lilibeth, omega):
	for z in range(16):
		roadrunner_wile[z] = (((omega[table[lili[z][0]]] | omega[table[lili[z][1]]]) +
			(omega[table[lili[z][2]]] | omega[table[lili[z][3]]])) ^ ((omega[table[lili[z][4]]] +
			omega[table[lili[z][5]]]) + (omega[table[lili[z][6]]] ^ omega[table[lili[z][7]]]))) % 256
		roadrunner_wile[z] = (roadrunner_wile[z] + (((~omega[table[lili[z][8]]] ^ omega[table[lili[z][9]]]) +
			(omega[table[lili[z][10]]] & ~omega[table[lili[z][11]]])) ^ ((omega[table[lili[z][12]]] ^ 
			~omega[table[lili[z][13]]]) + (omega[table[lili[z][14]]] ^ omega[table[lili[z][15]]])))) % 256
		roadrunner_wile[z] = (roadrunner_wile[z] + lilibeth[roadrunner_wile[z]] + lilibeth[z]) % 256
	return roadrunner_wile

def roadrunner_init(table, roadrunner_wile, lili, lilibeth, omega):
	SBOX = [
		[10, 11, 4, 5, 15, 0, 2, 3, 1, 9, 14, 6, 7, 12, 8, 13], 
		[1, 11, 13, 2, 0, 7, 3, 8, 14, 4, 6, 15, 5, 10, 12, 9], 
		[1, 9, 0, 4, 11, 5, 2, 8, 15, 7, 3, 6, 10, 14, 13, 12], 
		[5, 0, 9, 8, 3, 10, 12, 4, 1, 6, 7, 11, 15, 14, 2, 13], 
		[10, 6, 13, 3, 2, 11, 12, 14, 5, 9, 4, 1, 0, 8, 15, 7], 
		[15, 6, 1, 10, 7, 13, 14, 8, 3, 12, 0, 5, 2, 9, 4, 11], 
		[13, 7, 9, 5, 14, 12, 8, 15, 6, 0, 10, 4, 3, 11, 2, 1], 
		[13, 15, 8, 10, 6, 11, 9, 7, 12, 2, 3, 4, 14, 0, 5, 1], 
		[11, 3, 14, 7, 4, 8, 12, 2, 13, 0, 6, 1, 9, 10, 5, 15], 
		[2, 3, 14, 9, 11, 5, 15, 0, 4, 7, 1, 6, 12, 13, 8, 10], 
		[13, 3, 14, 1, 10, 0, 6, 5, 7, 2, 4, 9, 12, 8, 11, 15], 
		[15, 7, 4, 12, 14, 2, 9, 6, 3, 1, 13, 5, 0, 8, 11, 10], 
		[10, 7, 5, 14, 6, 2, 15, 1, 8, 11, 12, 9, 0, 3, 4, 13], 
		[1, 5, 0, 4, 6, 9, 11, 12, 3, 14, 7, 2, 15, 8, 13, 10], 
		[14, 9, 11, 2, 10, 4, 3, 0, 5, 8, 6, 15, 1, 12, 13, 7], 
		[11, 13, 6, 2, 0, 9, 3, 12, 1, 8, 7, 15, 4, 5, 10, 14]
		]
	for z in range(16):
		roadrunner_wile[z] = (((omega[table[SBOX[z][0]]] | omega[table[SBOX[z][1]]]) +
			(omega[table[SBOX[z][2]]] | omega[table[SBOX[z][3]]])) ^ ((omega[table[SBOX[z][4]]] +
			omega[table[SBOX[z][5]]]) + ( omega[table[SBOX[z][6]]] ^ omega[table[SBOX[z][7]]]))) % 256
		roadrunner_wile[z] = (roadrunner_wile[z] + (((~omega[table[SBOX[z][8]]] ^ omega[table[SBOX[z][9]]]) + 
			(omega[table[SBOX[z][10]]] & ~omega[table[SBOX[z][11]]])) ^ ((omega[table[SBOX[z][12]]] ^ 
			~omega[table[SBOX[z][13]]]) + (omega[table[SBOX[z][14]]] ^ omega[table[SBOX[z][15]]])))) % 256
	return roadrunner_wile

def circle_it_out(msg, ruler, roadrunner_wile, lili, lilibeth, enc, l, r, omega):
	for i in range(16):
		l[0][i] = msg[i]
		r[0][i] = msg[i+16]
	for i in range(1, ruler):
		roadrunner_wile = roadrunner(r[i-1], roadrunner_wile, lili, lilibeth, omega)
		for y in range(16):
			l[i][y] = r[i-1][y]
			r[i][y] = (l[i-1][y] ^ roadrunner_wile[y])%256
	for i in range(16):
		enc[i+16] = l[ruler-1][i]%256
		enc[i] = r[ruler-1][i]%256
	return roadrunner_wile, enc, l, r

def circle_it_out_init(msg, ruler, roadrunner_wile, lili, lilibeth, enc, l, r, omega):
	for i in range(16):
		l[0][i] = msg[i]
		r[0][i] = msg[i+16]
	for i in range(1,ruler):
		roadrunner_wile = roadrunner_init(r[i-1], roadrunner_wile, lili, lilibeth, omega)
		for y in range(16):
			l[i][y] = r[i-1][y]
			r[i][y] = (l[i-1][y] ^ roadrunner_wile[y])%256
	for i in range(16):
		enc[i] = l[ruler-1][i]%256
		enc[i+16] = r[ruler-1][i]%256
	return roadrunner_wile, enc, l, r

def persian_init(key, roadrunner_wile, lili, lilibeth, enc, l, r, omega, Omega):
	stkey = [88, 20, 64, 181, 251, 167, 69, 243, 205, 166, 110, 65, 90, 176, 229, 46, 206, 104, 15, 19, 49, 101, 3, 223, 221, 231, 232, 43, 62, 193, 80, 228]
	for compt in range(256):
		omega[compt] = (Omega[compt]^key[compt%20]) % 256
	for w in range(4):
		roadrunner_wile, enc, l, r = circle_it_out_init(stkey, 32, roadrunner_wile, lili, lilibeth, enc, l, r, omega);
		for compt in range(256):
			omega[compt] = (omega[compt]^enc[compt%32])%256
		for compt in range(32):
			stkey[compt] = enc[compt]
	for compt in range(16):
		err = 0
		ix = 0
		while ix < 16:
			roadrunner_wile, enc, l, r = circle_it_out_init(enc, 4, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
			x = 0
			while x < ix:
				if lili[compt][x] == (enc[7]%16):
					x = ix
					err = 1
					roadrunner_wile, enc, l, r = circle_it_out_init(enc, 4, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
				else: x += 1
			if err == 0: lili[compt][ix] = enc[7]%16
			else:
				err = 0;
				ix = ix-1;
			ix += 1
	err = 0 
	ix = 0
	while ix < 256:
		roadrunner_wile, enc, l, r = circle_it_out_init(enc, 4, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
		x = 0
		while x < ix:
			if lilibeth[x] == ( enc[7]%256):
				x  = ix 
				err = 1
				roadrunner_wile, enc, l, r = circle_it_out_init(enc, 4, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
			else:	
				x += 1
		if err == 0: lilibeth[ix]=enc[7]%256
		else:
			err = 0;
			ix = ix-1;
		ix += 1
	for compt in range(256):
		omega[compt] = (omega[compt] ^ key[compt%20])%256	
	for w in range(4):
		roadrunner_wile, enc, l, r = circle_it_out_init(stkey, 32, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
		for compt in range(256):
			omega[compt] = (omega[compt] ^ enc[compt%32])%256
		for compt in range(32):
			stkey[compt] = enc[compt]
	return roadrunner_wile, lili, lilibeth, enc, l, r, omega

def encrypt_iginition(msg, key):
	roadrunner_wile = [0 for x in range(16)]
	lili = [[0 for x in range(16)] for y in range(256)] 
	lilibeth, omega = [[0 for x in range(256)] for _ in '01']
	enc = [0 for x in range(32)]
	l, r = [[[0 for x in range(16)] for y in range(32)] for _ in '01'] 
	roadrunner_wile, lili, lilibeth, enc, l, r, omega = persian_init(key, roadrunner_wile, lili, lilibeth, enc, l, r, omega, Omega)
	roadrunner_wile, enc, l, r = circle_it_out(msg, 6, roadrunner_wile, lili, lilibeth, enc, l, r, omega)
	return enc

def encrypt(msg, key):
	msg = padding(msg)
	blocks = [msg[i*32:i*32+32] for i in range(len(msg) // 32)]
	ciphers = []
	enc = encrypt_iginition([ord(item) for item in blocks[0]], key)
	ciphers.append(enc)
	for i in range(len(blocks)-1):
		enc = encrypt_iginition([ord(item) for item in blocks[i+1]], keygen([ord(item) for item in blocks[i]], ciphers[i]))
		ciphers.append(enc)
	return "".join("".join(str(format(i, "02x")) for i in item) for item in ciphers)

Keydream

Let $p$ and $q$ be two primes such that

rstr = 'CCTF{it_is_fake_flag_' + randstr(27) + '_90OD_luCk___!!}'
p = bytes_to_long(rstr.encode('utf-8'))
q = bytes_to_long(rstr[::-1].encode('utf-8'))

Let $(n = p \cdot q, e = 65537)$ be the public key and $c$ being the encrypted flag. The goal is to recover $m$ (the flag).

n = 23087202318856030774680571525957068827041569782431397956837104908189620961469336659300387982516148407611623358654041246574100274275974799587138270853364165853708786079644741407579091918180874935364024818882648063256767259283714592098555858095373381673229188828791636142379379969143042636324982275996627729079
c = 3621516728616736303019716820373078604485184090642291670706733720518953475684497936351864366709813094154736213978864841551795776449242009307288704109630747654430068522939150168228783644831299534766861590666590062361030323441362406214182358585821009335369275098938212859113101297279381840308568293108965668609

NLCS 🔥

Let $s_0, s_1, …, s_{65535}$ be the first $65536$ output bits of the LFSR system using an irreducible polynomial $f(x) = x^{64} + x^{33} + x^{30} + … \in \mathbb{F}_2[x]$ and the initial state $s_0, s_1, …, s_{63}$, derived from the flag. We are given the values of

$$\begin{aligned} t_i := (s_i &+ s_{i + 12} + s_{i + 62} + s_{i + 18} + s_{i + 36}) \\ &+ (s_{i + 2}s_{i + 8} + s_{i + 34}s_{i + 20} + s_{i + 27}s_{i + 60} + s_{i + 31}s_{i + 34} \\ &+ s_{i + 63}s_{i + 48} + s_{i + 50}s_{i + 15} + s_{i + 25}s_{i + 49} + s_{i + 49}s_{i + 7}) \\ &+ (s_{i + 13}s_{i + 61}s_{i + 10} + s_{i + 32}s_{i + 37}s_{i + 29} + s_{i + 9}s_{i + 6}s_{i + 42} \\ &+ s_{i + 59}s_{i + 26}s_{i + 55} + s_{i + 42}s_{i + 41}s_{i + 29} + s_{i + 58}s_{i + 21}s_{i + 24}) \end{aligned}$$

for every $i\in [0, 65536 - 64]$, the goal is to recover $s_0, s_1, \ldots, s_{63}$.

Credits: @grhkm21 for the challenge summary.

Shaim

Define the shaim algorithm be the below. We are given a printable message $m_0$ (which has length between 40 and 71). The objective is to find a message $m$ such that shaim(m) == shaim(m0).

def shaim(msg):
	SBOX = [
		0xbe, 0xc5, 0x0f, 0x83, 0xb2, 0x77, 0xa8, 0x40, 0x4c, 0x53, 0x65, 0xd6, 0x27, 0xa7, 0x7c, 0x48, 
		0x1a, 0x60, 0x30, 0x17, 0xf3, 0x80, 0x04, 0x74, 0xd2, 0x5a, 0x2c, 0x8e, 0xa0, 0x32, 0x38, 0xcb, 
		0xe5, 0x4d, 0x19, 0x8f, 0xd9, 0x6d, 0x86, 0x58, 0xfc, 0xfa, 0xba, 0xdd, 0xc7, 0x57, 0xc1, 0x1c, 
		0x6a, 0x0c, 0x7b, 0x4b, 0xc8, 0x52, 0x54, 0x82, 0x47, 0x5d, 0xc9, 0xe8, 0x6b, 0xdb, 0x5e, 0x08,
		0xfb, 0x8d, 0x0e, 0x43, 0x37, 0x39, 0x50, 0x91, 0x7e, 0xf4, 0xe7, 0x35, 0xb8, 0x88, 0x20, 0x8b, 
		0x90, 0xe9, 0xee, 0xd5, 0xd3, 0xc3, 0xff, 0xa9, 0xae, 0x64, 0xf5, 0xac, 0x11, 0x4a, 0x76, 0x06, 
		0x18, 0x8a, 0xa3, 0xec, 0x56, 0x94, 0xdf, 0x42, 0x00, 0x22, 0xda, 0x6c, 0xb1, 0x12, 0xf2, 0xfe, 
		0xbf, 0x21, 0x1b, 0x4e, 0x9f, 0x97, 0xa6, 0x2b, 0x0b, 0xd4, 0x93, 0xc6, 0x03, 0x71, 0x14, 0x7a, 
		0x02, 0x0a, 0xc4, 0xdc, 0x36, 0x96, 0xd0, 0x09, 0x33, 0x26, 0xbc, 0x1d, 0xb6, 0xde, 0xe6, 0xe3, 
		0xeb, 0x28, 0x8c, 0x24, 0x99, 0x3f, 0xc0, 0x6f, 0xa2, 0xc2, 0xfd, 0x3c, 0x2d, 0x15, 0xf6, 0xad, 
		0x2f, 0xbd, 0x67, 0x05, 0x68, 0xa1, 0x69, 0x13, 0xca, 0x9d, 0x3a, 0x01, 0x63, 0xd7, 0x75, 0x07, 
		0x59, 0xb9, 0x46, 0xf8, 0xcd, 0x5c, 0x70, 0x95, 0xf9, 0x16, 0x45, 0xd1, 0x98, 0x79, 0x9c, 0x81, 
		0x44, 0x62, 0x6e, 0xb4, 0x34, 0xce, 0x84, 0xab, 0x29, 0x1e, 0x2a, 0x9b, 0xe2, 0x25, 0xb5, 0x87, 
		0x23, 0x3d, 0x5f, 0xaa, 0xf7, 0x9e, 0xed, 0xb3, 0xe1, 0x72, 0x7d, 0x3b, 0xb7, 0x0d, 0x51, 0x9a, 
		0x4f, 0x55, 0xf1, 0xf0, 0xe0, 0x31, 0x7f, 0xbb, 0x89, 0x5b, 0xe4, 0x78, 0x73, 0xef, 0xea, 0x92, 
		0x61, 0x41, 0x1f, 0xcc, 0xb0, 0x49, 0x85, 0x3e, 0x66, 0xaf, 0xd8, 0x2e, 0xa5, 0x10, 0xa4, 0xcf
		]
	nbit, hmsg = 64, msg.hex()
	hmsg += 'f' + hex(len(msg.hex())*4)[2:]
	hmsg += (nbit - (4*len(hmsg) % nbit)) // 4 * 'f'
	H, SBOX_M  = [], ''
	for i in range (0, len(hmsg) - 1, 2):
		tmp = hex(SBOX[int(hmsg[i:i+2], 16)])[2:]
		tmp = '0' + tmp if len(tmp) % 2 else tmp
		SBOX_M += tmp
	hmsg = SBOX_M  
	l = nbit // 4     
	H.append((int(hmsg[0:l], 16)))
	for i in range(1, len(hmsg) // l):
		plain = long_to_bytes(int(hmsg[i*l:(i+1)*l], 16))
		key = long_to_bytes(H[i-1])
		_DES = DES.new(key = key, mode = DES.MODE_OFB, IV = key)
		H.append(bytes_to_long(_DES.encrypt(plain)) ^ bytes_to_long(key))
	dgst = sha256(long_to_bytes(H[-1])).hexdigest()
	return dgst

Lagima

Let $n = 313$ and $s$ be a secret integer. We are given $n$ permutations of $[1, n]$, say $p_1, \ldots, p_n \in S_n$, as well as $p_1^s, \ldots, p_n^s$ (i.e., $p_1, p_2, …, p_n$ applied $s$ times). The goal is to recover $s$.

Credits: @grhkm21 for the challenge summary.

Starter ECC

We are given $n, a, b, x$. The objective is to find $y$ such that $y^2 \equiv x^3 + ax + b\mod n$.

x = 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046477020617917601884853827611232355455223966039590143622792803800879186033924150173912925208583
a = 31337
b = 66826418568487077181425396984743905464189470072466833884636947306507380342362386488703702812673327367379386970252278963682939080502468506452884260534949120967338532068983307061363686987539408216644249718950365322078643067666802845720939111758309026343239779555536517718292754561631504560989926785152983649035
n = 117224988229627436482659673624324558461989737163733991529810987781450160688540001366778824245275287757373389887319739241684244545745583212512813949172078079042775825145312900017512660931667853567060810331541927568102860039898116182248597291899498790518105909390331098630690977858767670061026931938152924839936

Credits: @grhkm21 for the challenge summary.

Versace

Define a custom asymmetric cipher, where the below are the keygen and the encrypt functions:

def keygen(n):
	e = 65537
	x, y = [getRandomRange(2, n - 2) for _ in '01']
	fi = pow(5, x, n)
	th = pow(13, y, n)
	return (n, e, fi, th)

def encrypt(m, pubkey):
	n, e, fi, th = pubkey
	k, u, v = [getRandomRange(2, n - 2) for _ in '012']
	c_1 = pow(k, e, n)
	c_2 = pow(5, u, n)
	c_3 = pow(13, v, n)
	c_4 = pow(fi, u, n) * pow(th, v, n) * pow(k + 1, e, n) * m % n
	return c_1, c_2, c_3, c_4

Given $n$ and a set of output from pubkey = keygen(n) and enc = encrypt(msg, pubkey). The objective is to find msg.

n = 141886649864474336567180245736091175577519141092893110664440298696325928109107819365023509727482657156444454196974621121317731892910779276975799862237645015028934626195549529415068518701179353407407170273107294065819774663163018151369555922179926003735413019069305586784817562889650637936781439564028325920769
pubkey = (141886649864474336567180245736091175577519141092893110664440298696325928109107819365023509727482657156444454196974621121317731892910779276975799862237645015028934626195549529415068518701179353407407170273107294065819774663163018151369555922179926003735413019069305586784817562889650637936781439564028325920769, 65537, 125494383162828289973475117066203219587304356806057400173045477137700391356840397636206107925460433939119412469184723408274805651096828270461235114589209044543108910295997506041345432448035371092981112305692014036117962906342882215492784319467728201344342591126197621795974549431806828947671232171059809967991, 138257736445723754207239869344459794807808248188757696052272858978544083465381926995900887162870612185045399616892685750962667762789508194359878372465943702647287813020223160406789982302692329883577043521781397505345137392777694159916452699296748509096494301465498192136911589776144421856343483031920756519249)
enc = (88920444409754899592335110119456825172544580816901497880270628553955508488170483498726344301421934007876515783471747430111559265733377611608113080609941423596790625452564403457107243481310552344096683637970851198148957553062631972064855184560312748315536290880767375156429548232884895308088306625307674645678, 45539956581550314230977168288877082058214432324397034618326297663129864608739856352261029083496409133620455599376139981575342903237304167908534019438874239934645347320209162850653298515960349717851268830205737252263548268549179642907155075129172651815656517165432021020317138111104384072600486843574535899860, 69849817078368866947686316374564245958824276178721440086311727765763093314086243149277327430285562537315291446874425715021031882041090977200029684675392021083309757246079110723453995717856469919242618068208424495615283285085190255592463862108516827540775850882615540406750734639040903336048095547788528187976, 20285007564778647051596518902857046010716548094264173639037549746086538656814534621919993169453446815272789643882592631536755194356753848872566348635207131520597253599540337542405837637606323276917410384296602682043902830628022440639028040137219164743287397377174047728489836106561656239657061612908104843401)

Credits: @grhkm21 for the challenge summary.

GSDP

Let $R, S \in M_{5, 5}(\mathbb{Z}_n)$ be random matrices. We are given $n, R, S, Y, C_1$ and $C_2$:

n = 20474248118672564431085568112167867588651829
r = [ 2168977325369444782802512809005167009163457  9637731563002649997560875900298785659999735 11402741982195550777990817093767890991834736  6248261665690503242396669505673833765541530 18383713927317640760514600671318653784954042]
    [16744026390724915738262959513570982580233867 10819123318870588054961801715028528659245735  5382293825969147064471127752184942873958882  2344559383975384575566938072263260707083674  6107831242377773278696901510341268870768483]
    [13913478639322625565461944432421523802028490  1657756157808133991943366467693421012417454 20077078978711296540965234618986335826824167 15787724170325517021960596569296223410283963 11311327970428371404045885802092772454814312]
    [ 6961572103900078883590821780051797472394845  9455345930492634517894541442153982197931104  7188007809979291502164073459871201264229019  5450777010613496799286069470550372888274079 19294083677962489844799387987438241606854764]
    [ 2085952337131731679161648956407072286901978  6312527395255217479599228946227018949620025  3768572167307432043022080651953496439648407 12149358492352082063390352013944276402659624  1238053480843820309901822772557963596458725]
s = [14359986778171934757328112351570087412922923 11851267097835964101770194163721259897123880 12595767519284390452196370829927812771980581   206471849033914539608937494910010443534631 16748276256578102130941428769109053956841543]
    [17260552917456245674154511124533873366489719  6705751087806309384311406617121931614484164 17060390771834209118913353599009244296476485 14200001344699610276445944574627003822066232 11014902955514050741738009264685742116160993]
    [ 6574547665819712697427953197398960761636762 12380657135986764418898027400335749204149860 20268210493845979828493975027685347139394991 18542561637456865344299035395313783209218383  7517573123535289654812496192079398350464721]
    [11797258068553520501845550128339899816126913 18396577268206658268808323909560870783161039  5490905135614309369346662799065239256309022 14271245849005639472351475697722779937695903  4543895191969014210971676462965142633095929]
    [ 8211670484406041965410550067328494865731128  9385233048164928123059801337014436991987865  2095213218314387589455876832673480152942740 13404162072797239424739266925419641170015472  6893572325245832032339890201821364839102869]
y = [ 9455266042843307825749316910810796871873373 15333106063741475447799261101208428669252581 17507977101165165875868259123812011424101505 18840713703683969794184618879025658583771001  8194677825423260832777930195809869229371863]
    [12501728660245911874452737460699597975974127 19510243647017562462989706821025083261970404 16201393977361396153964696776216973010001356  9663056411865435751212414658633217623172749  3239680106699734686590526219042751814995824]
    [ 3712586611180063604215543952289707697324027 14733212399197986119485181728946640781107458  2840139099323763287710523315368925837277792 13720228569300291500610175158110171144774084  6108815350519225911945135207538331156078296]
    [ 7943973119701029382921917301472306070824581  2869347305630973901685036806460889911095637 10842022254827356928486285947954965977783240 20363982398752260203093070660357855892929807  3232527006736169029584220678644241677651188]
    [18741615057330867264302735709730246936126331  7207581826003452274777064725926668618294351 12235279908760679864964056098862023499484670 11395481161377031878998588680860748310228740 14691306415490831547905993706341909177907668]
c_1 = [14520715136678131886650886394655992310739740  5133803346119603685589690243318329447613811  8631069083165564771821540186676532972101042 11371460936058753234877719062830204068473293  4675643908977844081807119750891783452511801]
      [10758446634943798177756512241470807154028028   230322671654482905785761279475308992164431 19859272618066856343509476253828743509021381 10790059806866303289733349155468067057434048  7937553273189724162746367232714449171157875]
      [12713707768421115203045631708468778038780988  6562443329388128558909111073920129986165358  8629397281530840800788762372728359271085200  3497280351202001940823865223283895540070188 16324531747558707671873605114378727152000738]
      [17664302494165645750553234381674396726461155 11329821313213471881023356172069963076578223 17420708004114170496283987639981918922808988  4025301508682028642713745479550070150287792 13516995862604528976910352157951268294502659]
      [13197381126644223748863331681581035046689048 18134793368131211547774737770284104243998582  3304296884612368960093061281547555357926671 17654343876553302292700074689920978613390384 19965538184282119398237005639724114717256368]
c_2 = [ 7467508370111086497875591641000575993385737   436730215933598480688770862716304678927061 16388674389038775692052384536812272916184391  1544929917235051621830007372321346311674993 20266847919326089072814025756784393554435095]
      [ 8525400103718228392870804572553779730855209  6910832586632574200490719455813022347001485 17879158289938108082881632425571195671456277 10773037736439027909506921110474733019517450  6673285991052846421739430171898388311111793]
      [ 9870026505859633975247413380429542368374340  3599087047295232637660012477486366289652163  9771908525081529326761727267151928531319243 19335625816265272435673905591707160166566864 15219307175745538685718076680399058971932192]
      [ 7121095235650179073589022177762837236165521 10051305836914620675997951100253778882475518 14120877609199150307731361282669945615365363  3064435253345055470095756982744706296418025   126078528977194834765813221549264972548412]
      [18926039657432874696099563502261812215936524 14159758827498805644159739654028640645658626  4643672049840979864316682883185591331924981 20293416534996028081504808704845564317319704  5806383537343185356941724671128323142478351]

We are also given the relations

$$\left\{\begin{aligned} Y &= f(R)^u \cdot S \cdot f(R)^v \\ C_1 &= h(R)^u \cdot S \cdot h(R)^v \\ C_2 &= \text{HashBase}\left(h(R)^u \cdot Y \cdot h(R)^v\right) \oplus \text{HashBase}(\mathcal{F}) \end{aligned}\right.$$

where $f(x) = a_0 x^4 + a_1 x^3 + … + a_4$ with $a_i \in [0, 25]$ (not given), $h(x) = x^5 + x + 1$ and $\text{HashBase}$ is the function with given implementation. The objective is to recover $\mathcal{F}$, the flag.

def hash_base(m):
	m = M(m)
	_M = M(zero_matrix(d))
	for i in range(d):
		for j in range(d):
			_M[i, j] = pow(2, m[i, j], n)
	return M(_M)

Credits: @grhkm21 for the challenge summary.

UIUCTF 2022

asr

  • Solves: 56/395
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: zhengdw

We are given $e, d$ (the public and private exponents of RSA) and the encrypted flag. It is known the largest prime factor for $p-1$ and $q-1$ is less than $2^{64}$ ($p$ and $q$ are the prime factors of the public modulus $n$). The goal is to recover the flag.

e = 65537
d = 195285722677343056731308789302965842898515630705905989253864700147610471486140197351850817673117692460241696816114531352324651403853171392804745693538688912545296861525940847905313261324431856121426611991563634798757309882637947424059539232910352573618475579466190912888605860293465441434324139634261315613929473
ct = 212118183964533878687650903337696329626088379125296944148034924018434446792800531043981892206180946802424273758169180391641372690881250694674772100520951338387690486150086059888545223362117314871848416041394861399201900469160864641377209190150270559789319354306267000948644929585048244599181272990506465820030285

Wringing Rings

  • Solves: 44/395
  • Difficulty: ⭐⭐
  • Tags: secret-sharing
  • Author: Spamakin
🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Elliptic Clock Crypto

  • Solves: 27/395
  • Difficulty: ⭐⭐
  • Tags: tbc
  • Author: Husnain
🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

mom can we have AES

  • Solves: 22/395
  • Difficulty: ⭐⭐
  • Tags: tbc
  • Author: Random Object No.79
🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

That-crete Log

  • Solves: 21/395
  • Difficulty: ⭐⭐
  • Tags: tbc
  • Author: zhengdw, Spamakin
🛠️ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

Bro-key-n

  • Solves: 14/395
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: Husnain

We are given a partially redacted private key file (in .pem). The objective is to recover the private key.

-----BEGIN RSA PRIVATE KEY-----
MIIJJAIBAAKCAgASUWUVXgOvRLJkI77YJ6BlG5t6en55ysW40HpawMJb9bTyWMIn
NIkWpL7+swa+eddajk+sL32Fkdf38eUAbq/y0y6T/LGlDLW9RJqEhAxx+fC62Zmu
7tUA3DK3CS0LAhrd4oWdU8YE9LFhOID7StpmxaGdoFi8emZGuTXE0ooyG60KObs4
dGV3Xbwq1xhM4iG9Drw94PwOlXS5UqDNfCcY0GlrorKsUSJwjNlkPIoos5FtR7KP
Rsau1+kd8aeCeAObkZciPRqLDojy3cVXZqKO6qpXHk2qfyEy1AKAFaNyt4sEt3WY
ex9qQg9a2W0w12zD01QZnJaKhTkMhdThLHrrBQsbBPQwsjcl7FwT0DQBOPZsas+k
WUYbTr++WvKy1pB7j6eC4WUlFFKf3zQ2Z+aHXX0UmPPYDLdlJFgLbyrwEULxW7EO
kTZt2IL3c4+ywkK0F6Ty4M+lzW/Wtj0ZcpAd9pudXEgXeCSUMJ6AlU0ckOl1WSpH
zORHYZ9aPVt2Ertme7sU4XdJZLFOqXzqN1+Z96GdpUOptOmpeL2/sv/4816OlZdH
OIjLErLv73CNhxSJ592zymSZesb0rSnH4T01ResFai6HLOMvE99ezt0lt73XwyRk
MGRm0uW35Ir5rOioHkKVgas3dGjH8DED73WOrvt5p0BImSb9jyYzT9odZQIDAQAB
AoIB/0WfF5MewOJnN59kPPdRpU6kn0vkRtCg4N6PgntsJ0tdlV+F+mkIRALMJyHn
TrqmXNzSB/9ogKwqpa68tKXwDM______________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________YM4i/wJBudIGNGxwJRfOR9HUI2G/wchfC1772bxdFev5+0YM
PiuBRnypiaHcf2/AAOmDMZJFyrTqrfy8jmxfdwKCAQAMVay1pGR15Pyz/AEqJvO4
lrw09/BHA1xhDTc5uYzlChRuxJEn5ehmc1Lgbawr+jciSkfCnNkEueQYv0+EhPYF
lJBsztrCJX3hzcVEU7qJLR4aAP6Px+G0Fd/kxQVbyrCvCKM1ptmpNPqYZE2IR5Ri
Fzj4eD7rl1qEaBNIEdNs2VRMmsRwhrqIZcgRVbzcOf5cE3agelmTT/JeGFVFF+Ri
knxvhVcSScPKgsfdhpFwcYbeLqbLac7ZQcb1+Qz7XU______________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
________________________________________________________________
______________________________________________________
-----END RSA PRIVATE KEY-----

corCTF 2022

tadpole

  • Solves: 262/978
  • Difficulty: ⭐
  • Tags: lcg
  • Author: @willwam845

Let $p$ be a secret prime. We are given the LCG $x_{i+1} = a \cdot x_i + b\ \text{mod}\ p$ with $x_0 = 13337$. We are given $a, b, x_1$ and $x_2$. The objective is to recover $p$.

a = 7904681699700731398014734140051852539595806699214201704996640156917030632322659247608208994194840235514587046537148300460058962186080655943804500265088604049870276334033409850015651340974377752209566343260236095126079946537115705967909011471361527517536608234561184232228641232031445095605905800675590040729
b = 16276123569406561065481657801212560821090379741833362117064628294630146690975007397274564762071994252430611109538448562330994891595998956302505598671868738461167036849263008183930906881997588494441620076078667417828837239330797541019054284027314592321358909551790371565447129285494856611848340083448507929914
x1 = 52926479498929750044944450970022719277159248911867759992013481774911823190312079157541825423250020665153531167070545276398175787563829542933394906173782217836783565154742242903537987641141610732290449825336292689379131350316072955262065808081711030055841841406454441280215520187695501682433223390854051207100
x2 = 65547980822717919074991147621216627925232640728803041128894527143789172030203362875900831296779973655308791371486165705460914922484808659375299900737148358509883361622225046840011907835671004704947767016613458301891561318029714351016012481309583866288472491239769813776978841785764693181622804797533665463949

luckyguess

  • Solves: 150/978
  • Difficulty: ⭐⭐
  • Tags: lcg
  • Author: @willwam845

Let $p = 2^{521} - 1$ and $0 \leq a, b \leq 2^{521} - 1$ be two given numbers. Define the LCG by

$$x_{i+1} = a \cdot x_i + b\ \text{mod}\ p.$$

We are asked to give $x, y$. After that, $0 \leq r < 2^{20}$ is randomly generated. We will be given the flag if $x_0 = x$ and $x_r = y$.

exchanged

  • Solves: 94/978
  • Difficulty: ⭐⭐
  • Tags: math, lcg
  • Author: @willwam845

We are given LCG parameters $p, a, b$ and the seed $x_0$. We are also given $M = x_m, N = x_n$ where $0 \leq m, n < p$. The goal is to find $x_{m+n}$.

p = 142031099029600410074857132245225995042133907174773113428619183542435280521982827908693709967174895346639746117298434598064909317599742674575275028013832939859778024440938714958561951083471842387497181706195805000375824824688304388119038321175358608957437054475286727321806430701729130544065757189542110211847
a = 118090659823726532118457015460393501353551257181901234830868805299366725758012165845638977878322282762929021570278435511082796994178870962500440332899721398426189888618654464380851733007647761349698218193871563040337609238025971961729401986114391957513108804134147523112841191971447906617102015540889276702905
b = 57950149871006152434673020146375196555892205626959676251724410016184935825712508121123309360222777559827093965468965268147720027647842492655071706063669328135127202250040935414836416360350924218462798003878266563205893267635176851677889275076622582116735064397099811275094311855310291134721254402338711815917
x0 = 35701581351111604654913348867007078339402691770410368133625030427202791057766853103510974089592411344065769957370802617378495161837442670157827768677411871042401500071366317439681461271483880858007469502453361706001973441902698612564888892738986839322028935932565866492285930239231621460094395437739108335763
M = 27055699502555282613679205402426727304359886337822675232856463708560598772666004663660052528328692282077165590259495090388216629240053397041429587052611133163886938471164829537589711598253115270161090086180001501227164925199272064309777701514693535680247097233110602308486009083412543129797852747444605837628
N = 132178320037112737009726468367471898242195923568158234871773607005424001152694338993978703689030147215843125095282272730052868843423659165019475476788785426513627877574198334376818205173785102362137159225281640301442638067549414775820844039938433118586793458501467811405967773962568614238426424346683176754273

hidE

  • Solves: 88/978
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: quintec

When connected to the server, a RSA modulus $n$ is generated. The seed for Python’s random package is set to be int(time.time()). We are given $n$ and two methods (we can use these methods as much as we would), which encrypts either the flag, or a user-supplied message using the first $e$ generated by random.randint(1, n) which is coprime with $\varphi(n)$, and sends to the player.

The objective is to recover the flag.

generous

  • Solves: 49/978
  • Difficulty: ⭐⭐
  • Tags: okamoto-uchiyama
  • Author: qoprime

The below defines the Okamoto-Uchiyama cryptosystem.

Let $p$ and $q$ be two primes and $n = p^2q$. Define $2 \leq g < n$ and $h = g^n\ \text{mod}\ n$. The public and private keys are given by $(n, g, h)$ and $(g, p, q)$ respectively.

The encryption function $c := \text{Enc}(m)$ is given by:

  1. Generates $1 \leq r < n$ randomly.
  2. Computes $c = g^m \cdot h^r\ \text{mod}\ n$.

The decryption function $m := \text{Dec}(c)$ is given by:

  1. Computes $a = [(c^{p-1}\ \text{mod}\ p^2) - 1] / p$ and $b = [(g^{p-1}\ \text{mod}\ p^2) - 1] / p$.
  2. Computes $m = a \cdot b^{-1}\ \text{mod}\ p$.

When connected to the server, two 512-bit primes $p, q$ are generated and $g$ such that $g^{p-1} \not\equiv 1\ (\text{mod}\ p^2)$. We are given $(n, g, h)$ and the encrypted flag $\text{Enc}(\text{flag})$. After that, we are given the oracle which computes $\text{Dec}(c)\ \text{mod}\ 2$ for user-supplied $c$, for an arbitrary number of times.

The objective is to recover $\text{flag}$.

leapfrog

  • Solves: 36/978
  • Difficulty: ⭐⭐
  • Tags: lcg
  • Author: @willwam845

We are given the $i$-th output from an unknown LCG (neither $a, b$ nor $p$ are given), with $i = 0, 5, 8, 31, 44, 68, 74, 84, 93, 100, 104, 123$. The goal is to recover $a, b$ and $p$.

x_0   = 26242498579536691811055981149948736081413123636643477706015419836101346754443
x_5   = 30320412755241177141099565765265147075632060183801443609889236855980299685595
x_8   = 65684356693401962957802832810273549345608027337432965824937963429120291339333
x_31  = 15025547765549333168957368149177848577882555487889680742466312084547650972663
x_44  = 46764069432060214735440855620792051531943268335710103593983788232446614161424
x_68  = 71575544531523096893697176151110271985899529970263634996534766185719951232899
x_74  = 8149547548198503668415702507621754973088994278880874813606458793607866713778
x_84  = 12081871161483608517505346339140143493132928051760353815508503241747142024697
x_93  = 65627056932006241674763356339068429188278123434638526706264676467885955099667
x_100 = 23413741607307309476964696379608864503970503243566103692132654387385869400762
x_104 = 56014408298982744092873649879675961526790332954773022900206888891912862484806
x_123 = 77000766146189604405769394813422399327596415228762086351262010618717119973525
x_139 = 14589246063765426640159853561271509992635998018136452450026806673980229327448

corrupted-curves

  • Solves: 20/978
  • Difficulty: ⭐⭐⭐
  • Tags: ecc
  • Author: qoprime

Denote $x_0$ be a secret (the flag).

When connected to the server, a 512-bit prime $p$ and $0 \leq a, b < 2^{384}$ are generated such that there exists $y_0$ such that ${y_0}^2 \equiv {x_0}^3 + a \cdot x_0 + b\ (\text{mod}\ p)$.

We can call the below oracle $\mathcal{O}(x_1)$, where $0 \leq x_1 < p$, as long as $\text{count} < 64$. Initialize $S = \phi$:

  1. Generate a 64-bit $e$.
  2. If $x \in S$ or $x < 2^{384}$ or $x > p - 2^{384}$, abort.
  3. Define the curve $C: y^2 \equiv x^3 + (a \oplus e) \cdot x + (b \oplus e)\ (\text{mod}\ p)$.
  4. If there exists a point $P$ such that its $x$-coordinate equals $x_1$, returns its $y$-coordinate and set $\text{count} \leftarrow \text{count} + 1$ and set $S \leftarrow S \cup \{x_1\}$.

The goal is to recover $x_0$.

threetreasures

  • Solves: 19/978
  • Difficulty: ⭐⭐⭐
  • Tags: ecc
  • Author: qoprime
Note: the flag has the format with corctf{...}.

Given that the flag is 375 bits long and it is broken evenly into three parts: $a, b, c$ ($a, b$ and $c$ consist of the first 125 bits, subsequent 125 bits and the remaining bits respectively). Let $p$ be a 512-bit prime and denote the elliptic curve $\mathcal{C}$ by

$$\mathcal{C}: y^2 = x^3 + ax + b\ (\text{mod}\ p).$$

Moreover, let $G \in \mathcal{C}$ such that $3G = O$. Let also $q$ be another 512-bit prime, $n = pq$ and $\text{Enc}(c) := \text{Pad}(c)^{65537}\ \text{mod}\ n$. We are given $n$, $\text{Enc}(c)$ and $G$. The goal is to recover $a, b$ and $c$.

n      = 97915144495462666300795364589570761584322186881492143950078938328867290046424857019504657598883431857075772605985768551863478086544857915637724181292135280539943713583281151707224031808445390796342632369109562433275679473233398168787639940620683354458292117457239552762694657810883738834935391913698852811737
Enc(c) = 20363336204536918055183609604474634074539942561101208682977506918349108499764147141944713060658857301108876346227077713201766486360148051069618774935469969057808945271860025712869868421279488925632657486125211168314387620225601572070169746014988350688548088791906161773656057212229972967244998930356157725393
G      = (3115938227771961657567351113281194074601897467086373590156577019504528350118731801249444974253028485083440228959842232653488953448859690520619223338133881, 2665631524518629436093690344927156713668794128141943350227439039472817541262750706395352700109556004195261826476428128993836186741129487842876154876730189)

corrupted-curves+ 🔥

  • Solves: 15/978
  • Difficulty: ⭐⭐⭐
  • Tags: ecc
  • Author: qoprime
Note. This challenge is similar to corrupted-curves, except that the upper limit of $\text{count}$ is changed, and it no longer accepts user-supplied $x_1$.

Denote $x_0$ be a secret (the flag).

When connected to the server, a 512-bit prime $p$ and $0 \leq a, b < 2^{384}$ are generated such that there exists $y_0$ such that ${y_0}^2 \equiv {x_0}^3 + a \cdot x_0 + b\ (\text{mod}\ p)$.

We can call the below oracle $\mathcal{O}$ as long as $\text{count} < 2022$. Initialize $S = \phi$:

  1. Generate a 64-bit $e$ and $2 \leq x_1 < p$.
  2. If $x \in S$ or $x < 2^{384}$ or $x > p - 2^{384}$, abort.
  3. Define the curve $C: y^2 \equiv x^3 + (a \oplus e) \cdot x + (b \oplus e)\ (\text{mod}\ p)$.
  4. If there exists a point $P$ such that its $x$-coordinate equals $x_1$, returns its $y$-coordinate and set $\text{count} \leftarrow \text{count} + 1$ and set $S \leftarrow S \cup \{x_1\}$.

The goal is to recover $x_0$.

rlfsr

  • Solves: 14/978
  • Difficulty: ⭐⭐⭐
  • Tags: lfsr
  • Author: @willwam845

Let $R$ be a known 128-bit LFSR. We are given $15104 = 128 \times 118$ output bits, in a way that the first 128 bits are shuffled, the subsequent 128 bits are shuffled, etc. The goal is to recover the initial values of the LFSR.

D3S 🔥

  • Solves: 1/978
  • Difficulty: ⭐⭐⭐⭐
  • Tags: des
  • Author: pot

We are given a Feistel cipher implementation, where the message space, ciphertext space, key space are all 54 trits (i.e., $\mathcal{M} = \mathcal{C} = \mathcal{K} = \mathbb{Z}_3^{54}$). We are given $3^9$ message-ciphertext pairs and the objective is to recover the key.

TODO