Noisy Vault Challenge Scenario
HackTheBox
Task: recover a 64-bit vault key from a single noisy Qiskit oracle while satisfying structural ancilla-validation constraints. Solution: submit the smallest valid CX-only circuit, aggregate 4096 measurement results with per-bit majority voting, then reverse the recovered bitstring to match Qiskit's endianness.
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Noisy Vault Challenge Scenario — HackTheBox
Description
Noisy Vault Challenge Scenario
The archive contained quantum_noisy_vault/server.py. The service prepares a random 64-bit secret key on 64 data qubits and exposes 16 ancilla qubits. We are allowed exactly one oracle query and one final unlock attempt, so the whole attack must recover the secret from a single noisy measurement batch.
Summary
The key idea is to satisfy the validator with the smallest possible corrective circuit, so we do not disturb the already-encoded secret more than necessary. A chain of 16 CX gates from data qubits 0..15 into ancillas 64..79 passes validation after transpilation, while leaving the data qubits themselves unchanged in the computational basis.
The oracle then returns noisy measurement counts over 4096 shots. Because the circuit mostly preserves the prepared basis state and the noise rates are modest, each secret bit still appears more often than its flipped value. Taking a per-bit majority vote across all returned bitstrings recovers the full key, and reversing the final bitstring fixes Qiskit's classical-bit endianness.
Analysis
Reading server.py shows the important constraints:
visible_bits = 64ancilla_qubits = 16- one oracle call only:
max_oracle_calls = 1 - one unlock attempt only
- noise model uses depolarizing error on single-qubit gates, two-qubit gates, and measurement
- oracle output is
get_counts()from 4096 noisy shots
The validator does not care whether our circuit actually corrects noise. It only checks structural activity after transpile(..., optimization_level=3):
- at least
total_data_qubits // 4 = 16data-ancilla links - at least
ancilla_qubits // 4 = 4active ancillas
So the goal is not fancy error correction. The goal is to pass validation while touching the data register as little as possible.
Minimal valid circuit
This was enough:
CX:0,64;CX:1,65;CX:2,66;CX:3,67;CX:4,68;CX:5,69;CX:6,70;CX:7,71;CX:8,72;CX:9,73;CX:10,74;CX:11,75;CX:12,76;CX:13,77;CX:14,78;CX:15,79
Why this works:
...
$ grep --similar
Similar writeups
- [ml][free]leaky-gradient— TJCTF 2026
- [crypto][free]quant?— umdctf
- [hardware][free]Project Power Challenge Scenario— hackthebox
- [crypto][free]Twisted Entanglement— HackTheBox
- [crypto][free]Untrusted Node— HackTheBox