Three Encodings, One Flag, One Rune
Welcome, Cakesmith. Your first trial locks behind three masks: hex, Ascii85, base64. Strip them all to find the flag and claim your first rune.
Below lies your first trial: a string wrapped in three encoding layers. Your task: decode hex โ Ascii85 โ base64 to reveal the flag. Submit it as jack{...}.
403b534a4b40354522483d5d664b5640723e25523d5d5d69683d3e4e696e3e236d583e3d5d664b503e223a532f4057216b5f
three layers of encoding, not encryption. identify each by its alphabet.
The Cipher Woven in Threads
Deeper in the guild archive, a second ward hums โ not a simple lock this time, but a plaintext braided against itself, byte over byte, in a repeating rhythm only a patient hand can unpick.
Below is a base64-encoded ciphertext. It was produced by XORing an English plaintext against a short repeating key (the key repeats cyclically across the whole message). Your job: recover the key, decrypt the ciphertext, and find the flag hidden inside the resulting English text. Submit the flag exactly as it appears, in the form jack{...}.
FgEXVAcWBRwZRRYESQYcDUQCGAAACg8ABhwbRAocGxFZFgEXHRpEDhUPAAoWSQERCxYEDRhFFw0dUh0GRBINBAscQgsHAEgND1kZAAkHCAYdBgNBCh8XHAMEAVQHAkEbEhEcEUkXDAsIFAoCExxCBgARDEQAHgoMFxEdUhVIFwgXDAkcQhoaGxoQQQ4EFx1CGhMdDEQVFksHHEIcHBYaAQASCgcVB0kQDUgFDwAECxxCBRMXAw0PHksVGBYAFxoLAUENAwBZBAUTE0gQCRwSRQ4KAAEEDRYEHUsMCkIDExcDHxMcGwAYFgAcEzcPBAAYOgsHGRcVHA0PHjQIEBEdEx8NFxxZCgsdQggcDUgXDBAfDVkVAR1UBQEACh4XHBFJBhwNRAUQGBEYDAoXVAoBFQ4OABdCCx4bCw8SWRwMFQ5JFB0GAEENAwBZDgwcExwMQRYNRQ0KDFIfDR1BGAUBWQQbHRlIEAkcGQBZFgEXVBoBEg1LEBcQCAQRBBdBFgUAWQEGHgEFCkEYH0UYQh0bGQ0=
The Thrice-Whispered Secret
Three cakesmiths across three towers intercepted the same whispered recipe, each locked under their own modulus with the guild's lazy default of e=3. A whisper broadcast three times is a whisper no more.
Below are three (n, c) pairs. Each is the same plaintext message m, RSA-encrypted with the same small exponent e=3 under a different modulus n. Recover m and read the flag. Combine the three ciphertexts via CRT to get m^3 mod (n1ยทn2ยทn3), take the exact integer cube root to recover m, then convert that integer to bytes (big-endian) to get the flag text. Submit it as jack{...}.
e = 3 n1 = 7385418709882126574399023182332111031304569685072089333329423653083103791564432374178156911007086332294496740559478612614089338943878132993944558495609227 c1 = 2280668048541185402160273355026016641348435053329335840328804389246122712317590211545456184246388876166003327469504501482386442690089809109268147652821428 n2 = 3661708606119927773984003415905942918577052310117227341276662013086794216599099816101038561656976596428085585746958067859531447956966893555355447978830631 c2 = 620742040066871249464540095485283879140711814328349977121373587762840123775768450488302663966741172576307838923096518196910679209242098022942839417338449 n3 = 8449134968201648326902312430250137153554410775955430096577856508929048131727000760931868426657218303780219429161626781355056344075576891936359138231484603 c3 = 7437216749369165648561804295887094790057426162336042655174564902614954041800245960584641977662114840417846403704779050771374174406967796379399111582267499
The Oversized Key
A junior Cakesmith forged this RSA lock in a hurry and picked a private exponent for speed, not safety. Speed leaves fingerprints โ and you've been trained to read them.
Below you'll find an RSA public key (n, e) and a ciphertext c. The exponent e was chosen carelessly, leaving the private exponent d small enough to recover directly from the public data alone โ no factoring n by brute force required. Find d, use it to decrypt c, and convert the resulting integer to ASCII bytes to read the flag. Submit the flag in the exact form jack{...}.
n = 4906982395031620860431371193718785113147442620523813064649441311471915222807864543717553652438157325092213608592485558217536020728685785757963683857270899 e = 1312007485265418056241096153758337669843368718297184280430537283177430004354650511251863242105058856702857733262180754612752322672460338375817450239972747 c = 2756094359608315291729712714981763609224486102504229733236578973878935654786271351834492443908774305799888883021227364192912413412129615078533120832914220
the flag is the decrypted message, read as ASCII bytes.
The Twin Forges of Fermat
Deep in the vault archives, a lazy apprentice smith forged a lock from two primes hammered from the same block of ore โ never realizing how close they'd land to one another. That carelessness is your crowbar, Jack.
The RSA modulus n shown below was built from two primes p and q that are suspiciously close in value โ close enough that brute-force square-root search finds them fast. Factor n, use the public exponent e shown below along with your recovered p and q to compute the private exponent d, then decrypt the ciphertext c shown below. Convert the decrypted integer to ASCII bytes to recover the flag. Submit it in the form jack{...}.
n = 11843051887512532650898545698899183267521151874444440874397381608391045233000526049682300103446785809554457556622352932178608467738156667820748078657182073 e = 65537 c = 2021638642296438451533556532646819280940783853763753828999112033756804856168943738058316399182340649203189245506853925329389715977018627080601024658017714
the flag is the decrypted message, read as ASCII bytes.
The Oracle's Predictable Pulse
Deep in the guild's server room hums an old oracle-node, spitting out "random" numbers it swears no one can predict. A Cakesmith who's read their linear algebra knows better โ that pulse is just arithmetic wearing a disguise.
The values shown below are consecutive outputs X0, X1, X2, ... of a linear congruential generator: X_{n+1} = (a * X_n + c) mod m. The modulus m is given alongside the outputs; a and c are not โ you must recover them from the sequence shown. Once you have a and c, compute the single next output that would follow the last value shown, and submit it as the flag: jack{lcg_N}, where N is that next output written as a plain decimal integer (no commas, no spaces, no leading zeros).
m = 4294967296 outputs = [ 1188505900, 316579651, 380099454, 3611626317, 828083808, 2682490279, 2881992274, 3375007953, 4092128212, 853209931, 3262647142, 1534523285, 546184, 4070020143, 2432077498, 340736921, 1303453564 ]
recover a and c, then predict the next output. flag: jack{lcg_N} with N in plain decimal.
The Keystream Forge Cracks
Twenty scrolls, one careless scribe: the Cakesmiths' old cipher-keeper reused a nonce and never lived it down. His mistake is your opening.
All the hex ciphertexts shown below were XORed against the exact same keystream โ the nonce got reused, which turns an otherwise-unbreakable one-time pad into a many-time pad you can crack. Recover the shared keystream, decrypt every message, and read the flag out of the FIRST message. Heads up: this attack sometimes recovers a letter with the wrong case (an 'e' where it should be 'E', say) โ that's expected, not a sign you did it wrong. Submit as jack{...}, all lowercase is fine since grading is case-insensitive.
c01 = 54bed03dfbca4f971e510949297b95fbd56e155c68941fa45a851b35444233fdc58e93466b9c4b2c34075453b927c173183db46c5cfb1f1e438d88a6c218b20ff2792381eaacfcdc c02 = 4ab7d676e3c54184084e3f4f247dc6ffe6782b4b74da0ea4709c1f320f4b7bf1dfdcc7456bc54e39330e411ee920c6664b37f22b59ef1f1f43889dfcc81ab80fe4353bcfaeacac9d c03 = 50b0dd35e58458840e50331b387b94f0f92f2b126b950aa469965a39415a33e0dfc3820e7edd596d2805541ce92e93640e2aed2b4be8081b08859eeac454b01df96c7ad5a3e1b9dc c04 = 5fb3da31ee845e891e0335523c6683ecfe6a324674da1daf61cf0e3e4a5133f0c4cf800e6f9c5e3f28090012aa3ddc611878e0634cba0e150f9191e8d254a913b76636cebde0a5dc c05 = 4dafd235e5d70a831e57245a352e92f6ef2f21577e8908b3608e17764d5a70f5c3dd820e7ad45834610d4c1ab96fc77a0e78f76a5aff4d1505c488eec454b119e3613fd3b9aca894 c06 = 5fb1ca76f3d05f851e4d221b2368c6fdf8763a46689d0ea075870376435a72e6d8ddc75a66d54e6d24134110bd6fdf77182bfb6509ea1f1f008d8fe3cd0dfd13f9763f81abe2b8dc c07 = 56bec326f984488809573e5f2d77c6f4eb6c2112618813ac259b12330f487bfbdacbc7417cd8583f61044653bd27d6320839ff6e5af7040e0b97dce7cf10fd05f8602881a8feb388 c08 = 4ab7d676f3d05884154422536c6180beeb2f3946759f1dac258c1326475a61b4d2c7825d2ec8552861064f1eac21c7321237e12b5aff031e439094e38107bc11f23531c4b3acaf88 c09 = 52bac722e5d659c1154637496c7a8efbaa622356639619e16a895a22475a33f5dade8f4f6cd9496d201b5016a83d937a0e2af12b44f51f1f438b9af2c41afd08ff743481b3e3a9dc c10 = 51b1d033a0dd45945b4838543b2e92f6ef2f21577eda0fb5778a1b3b0f5a65f1c4d7c75d67d25a21244b4d16ba3cd2750e78fe7e5aee4d1c028890f5811bad19f93533cfeaf5b389 c11 = 5fffc43ff3c10a8415443f55296b94bee46a3c5775da0fa96c9f09765b5776b4dfca82407ad55e2c2d4b431cbc21c7771978e26a45ef085a02878ee9d207fd08e07a7accafffaf9d c12 = 4cbad232e9ca4dc10f4b3348292e96f2eb662446628208e166801623425160b4dfddc75c6bdd5121384b4a06ba3b93610236f3674cba0f031781dce3d917b109e47c2cc4eae3aedc c13 = 4ab7d676edcb47841557764f3b61c6fde37f2257758e19b9719c5a25475e61f196cfc75d7ace582c2c4b541bac26c1320e20f7675ce9040c06c493f48106b80af27436d2eaf8b499 c14 = 58add627f5c14482020337552d629fede37c6a5f669119b2259c12395d4b33e3d9dc8c0e61da1d2c2f120010a623c67f0578f07948ed035a059693eb811baf18fe7b3bd3b3acb992 c15 = 59aad224e4cd44865b427650297795eaf86a2b5f27971db5718a08250f5972e696c3885c6b9c49252005001ea63cc732012dfa6246e84d1e069299eace04b80ee4353fd7affefc9d c16 = 5ba9d624f98446840f5733496c7789ebaa7d2f51688c19b325861476405176b4dbcb945d6fdb586d290a4e17ba6fca7d1e78e0634cba061f1ac49ae9d354bc10fb352ec9afacb388 c17 = 4ab7da25a0d3428e1746765d2d638ff2f32f2554279b08b5648c11250f5772e796cc824b609c56232e1c4e53ba26dd710e78e0634cba081b118895e3d200fd18f66c2981a5eafc8e c18 = 4ab7d676f0c54ec11656254f6c6c83bef86e245668975ca06b8b5a3f5b1f7ee1c5dac74c6b9c483e240f0016b12ed0660721b46447ff4d090a8a9beac454a915fa707ac0a4e8fc92 c19 = 4db0de33f7cc4f931e03371b386b9eeae860255927930fe1728e0838465174b4c5da924a6bd2493e610a421cbc3b9362193df7625aff0103439094efd254bb1dfe792fd3afacb193 c20 = 50bac533f28446840f033554227883f0e36a245162da08a069845a2f404a33fdd8da880e7cd9483e28054753be27d2664b2ff57809f503161ac499f0c406fd11f27434d5eaf8b3dc
a couple of letters may recover with the wrong case โ flag submission is case-insensitive.
The Logarithm Vault
Eight forges deep, the guild keeps a vault that only opens for a hacker-wizard who can unwind a modular exponential by brute wit alone. No brute force allowed here, Jack โ the forge-master sneers at anyone who just counts upward.
You're given a prime p, a base g, and a value y (shown below). Find the exponent x such that g^x โก y (mod p). This is a discrete logarithm problem โ with p around 2^40, checking every exponent one by one will not finish before the forge cools. You need a smarter algorithm. Once you have x, submit the flag as jack{dlog_X}, where X is x written as a plain decimal integer (no leading zeros, no modulus, no extra notation โ just the number itself).
p = 1103460965869 g = 5 y = 281441651329
find x with g^x โก y (mod p). flag: jack{dlog_X} with X in plain decimal.
The Keygen's Last Ward
One gate remains before the final vault, Jack, and this one doesn't hide behind a hash โ it hides behind arithmetic. The Cakesmiths' oldest keygen still runs down there, chewing bytes forward, daring anyone to run it back.
Below is a JavaScript check(input) function and its TARGET array. check() takes your string, transforms it byte-by-byte, and compares the result to TARGET โ return true and the gate opens. Every step in that transform is invertible. Your job: read the function, work out what each operation does to a byte, and invert the whole pipeline in reverse order to recover the original input string from TARGET. Submit the flag as jack{...} using the input string you recover (the recovered bytes, decoded as ASCII, form the flag).
[129, 16, 73, 159, 241, 87, 249, 126, 80, 167, 208, 103, 8, 180, 120, 204, 192, 244, 49, 196, 14, 59, 30, 252, 22, 52, 215, 20, 87, 199]
function check(input) {
var b = [];
for (var i = 0; i < input.length; i++) b.push(input.charCodeAt(i));
for (var i = 0; i < b.length; i++) {
b[i] = (b[i] + ((i * 7) & 0xff)) & 0xff; // position-dependent add
b[i] = b[i] ^ 0x5a; // xor constant
b[i] = ((b[i] << 3) | (b[i] >> 5)) & 0xff; // rotate left 3
}
for (var i = 1; i < b.length; i++) b[i] = b[i] ^ b[i - 1]; // xor chaining
return JSON.stringify(b) === JSON.stringify(TARGET);
}The Cakesmith Gate
Nine runes forged, nine trials survived โ the word is complete in your head, Jack, even if it's never been written down in one place. Now the Order asks you to prove it by turning that word into a key and opening the last door yourself.
This is it โ the final gate. Take the nine runes you've earned across this whole run and assemble them, in order, into a single uppercase word. That word is not the key itself โ it's the seed. Run it through SHA-256 to derive the real 32-byte key, uppercase ASCII bytes in, hash out. Below you'll find an AES-256-CTR ciphertext (hex) and its IV. Decrypt: key = SHA256(RUNE_WORD), mode = AES-256-CTR, IV = the one shown below. The plaintext is your birthday message from the Order, and it ends with the flag in the form jack{...} โ that's what you submit to pass the gate.
algorithm : aes-256-ctr key : SHA-256 of the 9-rune word (uppercase) iv (hex) : a1b2c3d4e5f60718293a4b5c6d7e8f90 ciphertext (hex): 7d41dc3aa7b5808b897467de1f7c0668f117cd4f62de0e88c7d1a883d0d6be74ed684760a967ce87441ec65de9d06eba7fe0c872afcdd7fb79b68cc6a94c5ca12fde7c2d4fce3ff35652e3e643a17b71f2fddfe061319d54a2e164b36f794a4cd70ff8625f5899fd88cf945b285af07c21b656be320e9431df57f4393f36a2d3076c4c55d1d65cdd6bdf65
the nine runes you forged spell the word. that word is the key. look up.