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 (⭐⭐⭐⭐)
MapleCTF 2022 brsaby 166/618 (⭐)
MapleCTF 2022 jwt 79/618 (⭐⭐)
MapleCTF 2022 Spiral-baby 57/618 (⭐⭐)
MapleCTF 2022 qotp-real 27/618 (⭐⭐)
MapleCTF 2022 e000p 18/618 (⭐⭐)
MapleCTF 2022 Spiral πŸ”₯ 9/618 (⭐⭐⭐)
MapleCTF 2022 clipper chip 2/618 (❓)
BalsnCTF 2022 Yet another RSA with hint 38/584 (⭐⭐)
BalsnCTF 2022 vss πŸ”₯ 9/584 (⭐⭐⭐)
BalsnCTF 2022 lfsr πŸ”₯ 6/584 (⭐⭐⭐)
DownUnderCTF 2022 baby arx 279/1407 (⭐)
DownUnderCTF 2022 oracle for block cipher 102/1407 (⭐⭐)
DownUnderCTF 2022 cheap ring theory 101/1407 (⭐)
DownUnderCTF 2022 rsa interval oracle i 79/1407 (⭐⭐)
DownUnderCTF 2022 rsa interval oracle ii πŸ”₯ 36/1407 (⭐⭐)
DownUnderCTF 2022 rsa interval oracle iii 23/1407 (⭐⭐)
DownUnderCTF 2022 rsa interval oracle iv πŸ”₯ 5/1407 (⭐⭐⭐)
DownUnderCTF 2022 time locked 18/1407 (⭐⭐)
DownUnderCTF 2022 faulty arx πŸ”₯ 11/1407 (⭐⭐⭐)
DownUnderCTF 2022 1337crypt v3 πŸ”₯ 2/1407 (⭐⭐⭐)
DownUnderCTF 2022 kyber± 1/1407 (⭐⭐⭐⭐)

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

  • Solves: 70/382
  • Difficulty: ⭐⭐
  • Tags: aes, 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.

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 πŸ”₯

  • Solves: 5/382
  • Difficulty: ⭐⭐⭐
  • Tags: rsa, faulty signature
  • Source: Official Repository
πŸ› οΈ 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

  • Solves: 21/421
  • Difficulty: ⭐⭐
  • Tags: elgamal, fault attack
  • Author: @refactoreal, @y3noor
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

  • Solves: 29/421
  • Difficulty: ⭐⭐
  • Tags: rsa, fault attack
  • Author: @refactoreal, @y3noor
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
  • Source: Official Repository

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
  • Source: Official Repository

When connected to the server, a secret $s \in [1, 500000]$ is generated. Let $\text{f}$ be a polynomial such that

$$\text{f}(x) := a_9 x^9 + a_8 x^8 + … + a_1 x + s,$$

where $a_1, a_2, …, a_9 \in [1, 100000]$ are randomly generated. We are given nine of these ten values: $(1, \text{f}(1))$, $(2, \text{f}(2))$, …, $(10, \text{f}(10))$. The objective is to find $s$.

Elliptic Clock Crypto

  • Solves: 27/395
  • Difficulty: ⭐⭐
  • Tags: dlog
  • Author: Husnain
  • Source: Official Repository

Define $\oplus$ operation over $\mathbb{Z}_p$ by:

$$(x_1, y_1) \oplus (x_2, y_2) := (x_1y_2 + y_1x_2, y_1y_2 - x_1x_2).$$

Let $0 \leq a, b < 2^{256}$ be respectively Alice’s and Bob’s secret key. Let also $A = a \cdot G$, $B = b \cdot G$ ($k \cdot G = G + G + … + G$, a sum of $k$ $G$’s). We are given $p, A, B$ and $G$. The objective is to find $S := ab \cdot G$.

p = 62471552838526783778491264313097878073079117790686615043492079411583156507853
G = (34510208759284660042264570994647050969649037508662054358547659196695638877343, 4603880836195915415499609181813839155074976164846557299963454168096659979337)
A = (929134947869102207395031929764558470992898835457519444223855594752208888786,6062966687214232450679564356947266828438789510002221469043877962705671155351)
B = (49232075403052702050387790782794967611571247026847692455242150234019745608330,46585435492967888378295263037933777203199027198295712697342810710712585850566)

mom can we have AES

  • Solves: 22/395
  • Difficulty: ⭐⭐
  • Tags: man-in-the-middle
  • Author: Random Object No.79
  • Source: Official Repository
πŸ› οΈ 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: dlog
  • Author: zhengdw, Spamakin
  • Source: Official Repository

Note. In this challenge, the prime check runs the Miller-Rabin test with bases $b = 2, 3, 5, 7, 11, 13, 17, 19, 31337$.
When connected to the server, a message $m := \text{flag} \oplus \text{token}$ is defined and $\text{token}$ is given. Repeat the below procedures five times:

  1. We send $q_1, q_2, …$ to the server. $q_i$’s needs to be primes with $\text{max}(q_i) \geq 2^{512}$. The product, $p = q_1 \cdot q_2 \cdot …$ needs to be a prime and $2^{512} \leq p \leq 2^{1024}$. Note that the prime $p$ computed should not be used in a previous round.
  2. The server generates a random $0 \leq x < p$ and sends it to us.
  3. The server computes $y = x^m\ \text{mod}\ p$ and sends it to us.

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

Bro-key-n

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

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

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

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

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
  • Source: Official Repository

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
  • Source: Official Repository

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

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
  • Source: Official Repository

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
  • Source: Official Repository
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
  • Source: Official Repository
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

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
  • Source: Official Repository

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.

MapleCTF 2022

brsaby

  • Solves: 166/618
  • Difficulty: ⭐
  • Tags: rsa
  • Author: zhengdw

Let $n = pq$ be the public modulus of RSA. Given $n$, $e = 65537$, $c$ (the encrypted flag) and $h := p^4 - q^3$, the goal is to recover the flag.

n = 134049493752540418773065530143076126635445393203564220282068096099004424462500237164471467694656029850418188898633676218589793310992660499303428013844428562884017060683631593831476483842609871002334562252352992475614866865974358629573630911411844296034168928705543095499675521713617474013653359243644060206273
e = 65537
c = 110102068225857249266317472106969433365215711224747391469423595211113736904624336819727052620230568210114877696850912188601083627767033947343144894754967713943008865252845680364312307500261885582194931443807130970738278351511194280306132200450370953028936210150584164591049215506801271155664701637982648648103
h = 20172108941900018394284473561352944005622395962339433571299361593905788672168045532232800087202397752219344139121724243795336720758440190310585711170413893436453612554118877290447992615675653923905848685604450760355869000618609981902108252359560311702189784994512308860998406787788757988995958832480986292341328962694760728098818022660328680140765730787944534645101122046301434298592063643437213380371824613660631584008711686240103416385845390125711005079231226631612790119628517438076962856020578250598417110996970171029663545716229258911304933901864735285384197017662727621049720992964441567484821110407612560423282

jwt

  • Solves: 79/618
  • Difficulty: ⭐⭐
  • Tags: ecdsa
  • Author: vEvergarden

This challenge implements ECDSA with a fixed private key $x$. However, for every signature generated, the nonce $k$ is always set to be $x$. The goal is to recover $x$.

Spiral-baby

  • Solves: 57/618
  • Difficulty: ⭐⭐
  • Tags: block cipher
  • Author: vEvergarden

The challenge defines a new block cipher called Spiral:


#
# Util functions
#

# rotate a 4x4 matrix clockwise
def spiralRight(matrix):
    right = []
    for j in range(4):
        for i in range(3, -1, -1):
            right.append(matrix[i][j])
    return bytes2matrix(right)


# rotate a 4x4 matrix counterclockwise
def spiralLeft(matrix):
    left = []
    for j in range(3, -1, -1):
        for i in range(4):
            left.append(matrix[i][j])
    return bytes2matrix(left)


# convert bytes to 4x4 matrix
def bytes2matrix(bytes):
    return [list(bytes[i : i + 4]) for i in range(0, len(bytes), 4)]


# convert 4x4 matrix to bytes
def matrix2bytes(matrix):
    return bytes(sum(matrix, []))

SBOX = [184, 79, 76, 49, 237, 28, 54, 183, 106, 24, 192, 7, 43, 111, 175, 44, 46, 199, 182, 115, 83, 227, 61, 230, 6, 57, 165, 137, 58, 14, 94, 217, 66, 120, 53, 142, 29, 150, 103, 75, 186, 39, 31, 196, 18, 207, 244, 16, 213, 243, 114, 251, 96, 4, 138, 197, 10, 176, 157, 91, 238, 155, 254, 71, 86, 37, 130, 12, 52, 162, 220, 56, 88, 188, 27, 208, 25, 51, 172, 141, 168, 253, 85, 193, 90, 35, 95, 105, 200, 127, 247, 21, 93, 67, 13, 235, 84, 190, 225, 119, 189, 81, 250, 117, 231, 50, 179, 22, 223, 26, 228, 132, 139, 166, 210, 23, 64, 108, 212, 201, 99, 218, 160, 240, 129, 224, 233, 242, 159, 47, 126, 125, 146, 229, 0, 252, 161, 98, 30, 63, 239, 164, 36, 80, 151, 245, 38, 107, 3, 65, 73, 204, 8, 205, 82, 78, 173, 112, 219, 136, 123, 149, 118, 32, 215, 163, 74, 134, 248, 68, 110, 45, 59, 145, 178, 156, 100, 177, 221, 2, 92, 20, 40, 144, 101, 140, 169, 116, 143, 202, 1, 113, 209, 104, 133, 128, 70, 89, 216, 147, 122, 131, 9, 249, 121, 109, 191, 77, 124, 246, 55, 198, 187, 185, 17, 60, 180, 203, 19, 158, 97, 206, 148, 5, 87, 170, 236, 222, 194, 15, 214, 241, 211, 234, 42, 41, 153, 62, 102, 152, 69, 181, 34, 48, 226, 11, 195, 154, 174, 167, 135, 232, 72, 171, 33]

SPIRAL = [
    [1, 19, 22, 23],
    [166, 169, 173, 31],
    [149, 212, 176, 38],
    [134, 94, 59, 47],
]

#
# The Spiral block cipher
#

class Spiral:
    def __init__(self, key, rounds=4):
        self.rounds = rounds
        self.keys = [bytes2matrix(key)]
        self.BLOCK_SIZE = 16

        for i in range(rounds):
            self.keys.append(spiralLeft(self.keys[-1]))

    def encrypt(self, plaintext):
        if len(plaintext) % self.BLOCK_SIZE != 0:
            padding = self.BLOCK_SIZE - len(plaintext) % self.BLOCK_SIZE
            plaintext += bytes([padding] * padding)

        ciphertext = b""
        for i in range(0, len(plaintext), 16):
            ciphertext += self.encrypt_block(plaintext[i : i + 16])
        return ciphertext

    def encrypt_block(self, plaintext):
        self.state = bytes2matrix(plaintext)
        self.add_key(0)

        for i in range(1, self.rounds):
            self.substitute()
            self.rotate()
            self.mix()
            self.add_key(i)

        self.substitute()
        self.rotate()
        self.add_key(self.rounds)

        return matrix2bytes(self.state)

    def add_key(self, idx):
        for i in range(4):
            for j in range(4):
                self.state[i][j] = (self.state[i][j] + self.keys[idx][i][j]) % 255

    def substitute(self):
        for i in range(4):
            for j in range(4):
                self.state[i][j] = SBOX[self.state[i][j]]

    def rotate(self):
        self.state = spiralRight(self.state)

    def mix(self):
        out = [[0 for _ in range(4)] for _ in range(4)]
        for i in range(4):
            for j in range(4):
                for k in range(4):
                    out[i][j] += SPIRAL[i][k] * self.state[k][j]
                out[i][j] %= 255

        self.state = out

When connected to the server, a 16-byte key is randomly generated and we are allowed to encrypt

  • the flag, and
  • or arbitrary message,

using Spiral with one round, as much as we could. The goal is to recover the flag.

qotp-real

  • Solves: 27/618
  • Difficulty: ⭐⭐
  • Tags: rng
  • Author: zhengdw
πŸ› οΈ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

e000p

  • Solves: 18/618
  • Difficulty: ⭐⭐
  • Tags: ec
  • Author: zhengdw

Let $\mathcal{C}$ be the Edwards curve Curve41417, $G \in \mathcal{C}$ be the generator and $n$ be its order. Define $x := \text{FLAG}^{-1}\ \text{mod}\ n$. Let also $h = x \land \text{MASK}$ ($\land$ is the bitwise AND operator) and $P = x \cdot G$.

We are given $\text{MASK}$, $P$ and $h$, the goal is to recover $\text{FLAG}$.

MASK = 0xfffffffffffffffffff800001ffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffff800001fff
P = (29389900956614406804195679733048238721927197300216785144586024378999988819550861039522005309555174206184334563744077143526515, 35393890305755889860162885313105764163711685229222879079392595581125504924571957049674311023316022028491019878405896203357959)
h = 323811241263249292936728039512527915123919581362694022248295847200852329370976362254362732891461683020125008591836401372097

Spiral πŸ”₯

  • Solves: 9/618
  • Difficulty: ⭐⭐⭐
  • Tags: block cipher
  • Author: vEvergarden
Note. The challenge uses the same cipher given in Spiral-baby. However, the cipher is now of four rounds instead of one.

When connected to the server, a 16-byte key is randomly generated and we are allowed to encrypt

  • the flag, and
  • or arbitrary message,

using Spiral with four rounds, as much as we could. The goal is to recover the flag.

clipper chip

  • Solves: 2/618
  • Difficulty: ❓
  • Tags: ❓
  • Author: xal
Needs more information. I am not totally clear about this challenge. Please let me know if you have a better picture on this one!

BalsnCTF 2022

Yet another RSA with hint

  • Solves: 38/584
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: utaha

Let $(n, e)$ be a RSA public key ($n$ being 1024 bits and $e = 65537$), and $c$ be the encrypted flag. We are also given $\text{hint} := (b_2, b_3, …, b_{199})$, where $b_k$ is the sum of digits of $p$ (a prime factor of $n$) in base $k$. The objective is to recover the flag.

n = 69769370315605399620499157110259161770226204413410714287546175640222894393734656823609842094208000324903785445480970937467772043771047139468214623293799193606693151204028152125827120312591965423568920046988483517193159267137262989786922993050699199470525597334312901558499603311835177928669168435353736304603
e = 65537
c = 44629586340631092032969036077439025547731549046317830052768219747251144452428756243443530079705365300095620187777995163429306743725384004785137984724398460770780400852341911649904759816676765406154144761671142475150796245779492784073799771022568183264838096756108860913879311490014711507384458820460700533977
hint = [250, 305, 371, 421, 519, 569, 583, 621, 746, 679, 787, 821, 880, 919, 899, 1021, 1038, 1151, 1133, 1229, 1157, 1205, 1237, 1301, 1399, 1335, 1574, 1549, 1495, 1469, 1564, 1709, 1634, 1633, 1759, 1673, 1794, 1817, 1790, 1989, 1971, 2081, 2058, 2041, 2114, 2065, 2239, 2381, 2193, 2199, 2432, 2297, 2500, 2519, 2459, 2501, 2558, 2597, 2647, 2609, 2750, 2711, 2627, 2765, 2609, 3053, 2931, 3333, 2939, 2809, 2843, 2789, 3002, 3089, 2924, 3185, 3306, 3389, 3169, 2989, 3302, 3201, 3153, 3089, 2874, 3305, 3554, 3493, 3822, 3419, 3467, 3261, 3548, 3461, 3679, 3533, 3420, 4251, 4274, 4249, 3967, 4013, 4172, 4117, 3824, 4461, 3707, 4193, 3585, 4109, 4532, 4237, 4009, 4439, 4089, 4917, 3896, 4181, 4370, 3989, 4032, 4641, 4841, 4509, 4324, 4643, 4379, 4685, 4595, 5079, 4437, 5165, 5161, 4271, 5624, 4557, 4570, 4871, 5191, 5189, 4871, 4689, 4923, 5597, 4859, 4973, 5084, 5457, 5196, 5099, 4855, 5541, 5237, 5077, 5284, 5729, 5468, 5539, 5468, 5709, 5308, 5813, 6201, 6317, 5264, 4979, 6540, 5693, 5885, 5679, 5921, 5713, 6086, 6425, 5574, 6221, 5774, 6581, 6422, 6209, 6324, 5651, 6227, 6021, 6789, 6617, 6155, 6657, 6218, 6719, 5820, 6221, 6026, 6815, 6509, 6113, 6731, 7343]

vss πŸ”₯

  • Solves: 9/584
  • Difficulty: ⭐⭐⭐
  • Tags: math
  • Author: utaha

When connected to the server, two 512-bit numbers $x, y$ will be generated. We are allowed to get up to around 180 sets of $(a, b, c, p, g, v, q)$ such that:

  1. $u = (a + bx + cy)\ \text{mod}\ p$, and
  2. $v = g^u\ \text{mod}\ q$.

The goal is to recover $x$ and $y$.

LFSR πŸ”₯

  • Solves: 6/584
  • Difficulty: ⭐⭐⭐
  • Tags: lfsr
  • Author: utaha
Note. In the challenge, the operations are done in $\text{GF}(2)$. That said, $+$ is actually the $\oplus$ (XOR) operation and $\times$ is the AND operation.

Let $\mathcal{L}$ be a LFSR with key $(s_0, s_1, …, s_{127})$, and for $i \geq 0$,

$$s_{i+128} = s_{i} + s_{i+1} + s_{i+2} + s_{i+7}.$$

Let the output bits $y_0, y_1, …$ defined by

$$\begin{aligned} y_i &= s_i + s_{i+16} + s_{i+32} + s_{i+120} + s_i s_{i+8} + s_i s_{i+32} + s_{i+8} s_{i+64} + s_{i+16} s_{i+32} \\ &\qquad + s_i s_{i+8} s_{i+64} + s_{i+16} s_{i+32} s_{i+64} + s_i s_{i+8} s_{i+16} s_{i+64} s_{i+120} + s_{i+8} s_{i+16} s_{i+32} s_{i+64} s_{i+120}. \end{aligned}$$

We are given the first 8192 bits of the output (i.e., $y_0, y_1, …, y_{8191}$). The goal is to recover the key (i.e., $s_0, s_1, …, s_{127}$).

DownUnderCTF 2022

baby arx

  • Solves: 279/1407
  • Difficulty: ⭐
  • Tags: ?
  • Author: @josep68_
πŸ› οΈ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

oracle for block cipher

  • Solves: 102/1407
  • Difficulty: ⭐⭐
  • Tags: ?
  • Author: @josep68_

Let m be the message with a given 16-byte prefix. When connected to the server, a 16-byte key k is generated. We are allowed to pick two IVs iv1, iv2. After each pick, we will be given the ciphertext of m, encrypted with AES-OFB with key k and iv. The goal is to recover m.

cheap ring theory

  • Solves: 101/1407
  • Difficulty: ⭐
  • Tags: ?
  • Author: @josep68_
πŸ› οΈ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

rsa interval oracle i

  • Solves: 79/1407
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: @josep68_

When connected to the server, two 192-bit primes $p, q$ are generated and $n = p \cdot q$. Let $e = 65537$ and $d$ be the corresponding decryption exponent. We are given $(n, e)$ (a RSA public key). A 336-bit message $m$ is generated and encrypted using the RSA public key. The ciphertext, $c$, is given as well.

We are allowed to set $k$ intervals $[\alpha_1, \beta_1)$, …, $[\alpha_k, \beta_k)$. We are also allowed to send $c_1, c_2, …, c_q$ (in multiple batches) and obtain $\mathcal{O}(c_1), \mathcal{O}(c_2), …, \mathcal{O}(c_q)$. The server will sleeps for $s$ seconds after returning each batch of $\mathcal{O}(c_i)$’s.

The goal is to recover $m$ within $t$ seconds.

Finally, $\mathcal{O}(c)$ is given by the smallest $i$ such that $m := c^d\ \text{mod}\ n$ and $m \in [\alpha_i, \beta_i)$ (or -1 if it falls into neither of the intervals).

In this challenge, $k = 384$, $q = 384$, $t = 1800$ and $s = 0$.

rsa interval oracle ii πŸ”₯

  • Solves: 36/1407
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: @josep68_

The challenge is similar to rsa interval oracle i, except that we are only allowed to set one interval (i.e., $k = 1$).

rsa interval oracle iii

  • Solves: 23/1407
  • Difficulty: ⭐⭐
  • Tags: rsa
  • Author: @josep68_

The challenge is similar to rsa interval oracle i, with $k = 4$, $q = 4700$, $t = 180$ and $s = 44$.

rsa interval oracle iv πŸ”₯

  • Solves: 5/1407
  • Difficulty: ⭐⭐⭐⭐
  • Tags: rsa
  • Author: @josep68_

The challenge is similar to rsa interval oracle i, with $q = 4700$ and $t = 180$.

In this challenge, we are no longer able to add intervals by ourselves, but to use these intervals: $[1, 2^{373}), [1, 2^{374}), [1, 2^{375}), [1, 2^{376})$. Also, we can only send all the $c_i$’s in one batch, i.e., we cannot send $c_i$’s adaptively.

time locked

  • Solves: 18/1407
  • Difficulty: ⭐⭐
  • Tags: math
  • Author: @josep68_

Let $f$ be the function given below. The goal is to recover $f(2^{2^{1337}})$.

p = 275344354044844896633734474527970577743
a = [2367876727, 2244612523, 2917227559, 2575298459, 3408491237, 3106829771, 3453352037]
Ξ± = [843080574448125383364376261369231843, 1039408776321575817285200998271834893, 712968634774716283037350592580404447, 1166166982652236924913773279075312777, 718531329791776442172712265596025287, 766989326986683912901762053647270531, 985639176179141999067719753673114239]

def f(n):
    if n < len(Ξ±):
        return Ξ±[n]

    n -= len(Ξ±) - 1
    t = Ξ±[::-1]
    while n > 0:
        x = sum([a_ * f_ for a_, f_ in zip(a, t)]) % p
        t = [x] + t[:-1]
        n -= 1

    return t[0]

faulty arx πŸ”₯

  • Solves: 11/1407
  • Difficulty: ⭐⭐⭐
  • Tags: ?
  • Author: @josep68_
πŸ› οΈ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.

1337crypt v3 πŸ”₯

  • Solves: 2/1407
  • Difficulty: ⭐⭐⭐
  • Tags: math
  • Author: @josep68_

Let $3 \leq x < 2^{780}$. We are given $\alpha_1, \alpha_2, \alpha_3, \beta_1, \beta_2, \beta_3$ such that:

$$\left\{\begin{aligned} \beta_1 &= \sin \alpha_1 x \\ \beta_2 &= \cos \alpha_2 x \\ \beta_3 &= \tan \alpha_3 x \end{aligned}\right..$$

Hereby $\alpha_1, \alpha_2, \alpha_3, \beta_1, \beta_2, \beta_3$ are real numbers with 1337 bits of precision. The goal is to recover $x$.

alpha1 = 382688.000003718840762957370928334219657048504840071252989018263226986883648629049352735765207269589923429068690707732585598417261371285342932900956113960156340065674727873827170594382319143476595475658327786062528588588365234789011569313613560380958047757353077898557461668048835816899156195030884972536360965559815694251787832696791756073796676100126068701864254874470530046373944314078415476327719123
alpha2 = 15637.0000000000000000000000000000000000000000073407249596755993494633815978948470725770595202532938111233270822656540006827548854086357909099305933838931019150313577619230563069886151776251889782046359224864632667394933146539407828208245853609735993739377148185083846731149980246713157043706328084023440946327661078130241672626606833808343709723838524304060402271919834105020805612169606358017694056416
alpha3 = 29275.0000000000640306760478159122361364268852615107016525704106080086895615545710184648549454761942179678623356595579867852707677349455538454994245696487465653543975651069930536590338519688676538350247199102639964709439110478379805687129967589534757115196430034251100020849966477333439686322641356763869580696872661554589116735439860643787761928921454825557808884297326088601658418898922938739996904201
beta1 = 0.965482350590597357930331336732328693322339578742073734517347983738107022900479878437240803728616183527740872166110419707555902612362293470627167159630511997241207746072653515847677991057240464634863174163959352186613630940970393483122090644984824146327516779925585782449367431713140436462716606231926544190865635435305068802789385561809037048381522369403391403353483514563964854636147009339110513969645
beta2 = 0.919312641039301449759543236755656153255910638284013829633241595979805444268967097520473755994266515165860135737385130077610933382052195648654916587723024832651148703456409500869252608520524821467862378804471336340455738379241087436118861027054778860623168210037730515076872812158198969896476202559290795561594850736319300877512941843333101776445598926887112185986310036903702305697813449195991705718975
beta3 = 1.14855387625795367637526700157484262696944920546403536701593427303031683808809632650237298251670835767655247021139590568460713791448489530488025769625130549491228701922532851244586550786881004979465956996142194848926889854866759317451072626109337018933249842757205735321771354730486331102478476183417508143532011641972415188172049143718997615501480006657475224101754862855024419523910721536847865397788

kyberΒ±

  • Solves: 1/1407
  • Difficulty: ⭐⭐⭐⭐
  • Tags: ?
  • Author: @josep68_
πŸ› οΈ To-be written. This is a placeholder because I am lazy. Please read the tags, or the official source meanwhile.