cryptofreemedium

Minerva's Stopwatch

tjctf

Task: ECDSA P-256 timing side-channel attack with 1600 signatures leaking nonce bit-length (Minerva / CVE-2024-23342). Solution: calibrate timing model, solve Hidden Number Problem via CVP lattice with fpylll, decrypt flag using SHA256-CTR custom stream cipher.

$ ls tags/ techniques/
minerva_timing_attackhidden_number_problemlattice_cvptiming_model_calibrationcustom_stream_cipher_decryption

$ cat /etc/rate-limit

Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.

Minerva's Stopwatch — TJCTF 2026

Description

listen closely, it has a lot to say

We are given three files:

  • trace.csv — 1600 ECDSA P-256 signatures with columns: id, msg_hex, h, r, s, elapsed_ns
  • public_key.txt — P-256 public key coordinates (Qx, Qy)
  • flag.enc — 35 bytes of hex-encoded ciphertext

The goal is to recover the ECDSA private key using the timing side-channel and decrypt the flag.

Analysis

Identifying the vulnerability

The challenge name "Minerva's Stopwatch" and the elapsed_ns column directly reference CVE-2024-23342 — the Minerva timing vulnerability in the python-ecdsa library. The core issue: the time taken to compute an ECDSA signature leaks information about the bit-length of the nonce k, because scalar multiplication time is proportional to the number of bits in k.

Timing model calibration

The timing side-channel leaks the bit-length of each nonce. By analyzing the distribution of elapsed_ns values, we calibrate a linear timing model:

  • Center for 256-bit nonces: 197530 ns
  • Time per bit: 265 ns
  • Formula: est_bits = round(256 - (197530 - elapsed_ns) / 265)

The resulting distribution matches the expected geometric distribution perfectly:

  • 256-bit: 781 signatures (~50%)
  • 255-bit: 430 (~25%)
  • 254-bit: 197 (~12.5%)
  • 253-bit: 82 (~6%)
  • 252-bit: 50 (~3%)

Crucially, 6 extreme outliers have very short nonces: 38-bit, 73-bit, 73-bit, 89-bit, 90-bit, and 129-bit — these provide massive leakage.

Hidden Number Problem (HNP)

The ECDSA signing equation is:

s_i * k_i ≡ h_i + d * r_i  (mod n)

Rearranging: k_i = s_i^{-1} * h_i + s_i^{-1} * r_i * d (mod n)

...

$ grep --similar

Similar writeups