Nala's Blueprint: The Secret Geometry

By Team Cryptonite · 2 min read

About the CTF: Pinaka CTF

Recover corrupted Reed-Solomon symbols, verify pier measurements lie on a parabola, compute the keystone apex, then exploit AEAD nonce-reuse between the manifest and blueprint ciphertexts to break the seal.…

Nala's Blueprint: The Secret Geometry

**Pinaka CTF 2026** · Cryptography · Team Cryptonite · All 44 Pinaka write-ups


Challenge

> Recover corrupted Reed-Solomon symbols, verify pier measurements lie on a parabola, compute the keystone apex, then exploit AEAD nonce-reuse between the manifest and blueprint ciphertexts to break the seal.

> Validator: https://pinaka-s05-cyber-xo-x.vercel.app/

We're given parity.rsc, archive.sealed, blueprint_format.txt and a README.md.

Recon

I opened both files and looked at the headers. parity.rsc starts with PNKSETU1 and archive.sealed starts with PNKSEAL1. They're both custom formats, so I just read through the hex dump.

hex-dump

The erased flag together with the k/n values in parity.rsc looked a lot like a Reed-Solomon code.

Recovering the pier heights

I dropped the 4 erased symbols, which leaves 20 points for 12 unknowns. That's enough slack to correct up to 4 wrong values.

I used Berlekamp-Welch over GF(65537), trying e = 0, 1, 2 and so on. For each e, I checked that the linear system had a solution, that Q/E divided exactly, and that the result disagreed with at most e of the points. e = 0 to 3 have no solution at all, which makes sense, because no degree-11 polynomial fits all 20 points when some of them are wrong. At e = 4 it works: Q/E divides cleanly and the result disagrees with exactly 4 points, at x = 8, 11, 14 and 18.

The recovered pier heights:


[601, 1228, 1795, 2302, 2749, 3136, 3463, 3730, 3937, 4084, 4171, 4198]

The apex

The gaps between the heights go 627, 567, 507, ... and drop by 60 every time, so it's a quadratic:


h(i) = -30*i^2 + 657*i + 601

The apex is C - B^2/(4A) = 503769/120 = 167923/40.

Nala's Blueprint: The Secret Geometry: step screenshot

The seal

blueprintformat.txt gives the exact manifest layout: keystoneapex=<num>/<den>, piers=<k>, one hNN=<height> line per pier, SETU-MANIFEST-v1, then dots up to 512 bytes. I already had the heights and the apex, so I could rebuild the whole plaintext byte for byte.

Then I compared the nonces of the two records, and they were the same (fec3116eaaad0420617b4b5a for both). Nonce reuse, so:


keystream = manifest ciphertext XOR rebuilt manifest
blueprint = blueprint ciphertext XOR keystream

The output was readable text (SETU-BLUEPRINT-v1, engineer=Nala-Setukarma), so I knew it worked.


keystone_seal=3b4c5970eeaf629a1bfb38d05c46166458a654cc4fdb4ce4b7b26506e461bcee

Nala's Blueprint: The Secret Geometry: step screenshot

Submitting

I sent all three values (the measurements, the apex and the seal) in a POST to /setu/keystone with curl and got the flag:

Nala's Blueprint: The Secret Geometry: step screenshot


PINAKA{nala_blueprint_ecc_geometry_and_nonce_reuse}

Summary

  1. parity.rsc holds a Reed-Solomon codeword. Drop the 4 erased symbols and run Berlekamp-Welch over GF(65537). It corrects 4 errors (x = 8, 11, 14, 18) and gives the 12 pier heights.
  2. The heights form a quadratic, -30i^2 + 657i + 601, whose apex is 167923/40.
  3. Both records in archive.sealed use the same nonce. The manifest's layout is public and its values are the heights and apex from steps 1-2, so rebuilding it and XORing gets the keystream back, and that decrypts the blueprint and gives the keystone seal.

Read this post on CyberHx →