The specification itself has no trapdoor: the secret key is a public linear function of the public key
Practical · Demonstrated · Cause: construction
Property: key recovery
Cost against claim: one N by N linear solve, under 3 seconds, recovers the secret key from the public key alone at every level, against the claimed IND-CCA security
The specification samples the secret O as a Haar-random orthogonal matrix but publishes B_pk = O·B_red, where B_red is built from public parameters alone, with no unimodular re-randomisation. Because level 0 has rate 1, its block of B_red equals the polar transform, a unimodular matrix, so LLL reduction of B_red returns a signed permutation matrix and O = B_pk·B_red^-1 follows from one linear solve. This defeats the specification's own IND-CPA proof, which assumes a uniformly random basis is published.
| Parameter set | Claim | Attack cost | Verdict |
|---|---|---|---|
| PolarKEM-128 | 128 classical, 64 quantum | one 512x512 linear solve, 2.1 s, exact recovery | Practical |
| PolarKEM-256 | 256 classical, 128 quantum | one 1024x1024 linear solve, 0.09 s, recovery to 3.4e-15 | Practical |
| PolarKEM-512 | 512 classical, 256 quantum | one 2048x2048 linear solve, 0.70 s, recovery to 3.8e-15 | Practical |
What causes it
Algorithm 1 (p.11) samples O uniformly and sets sk = O, but derives the reduced basis B_red deterministically from public parameters (Algorithm 10, p.29) with no re-randomisation of the lattice it generates. The rate progression fixes K_0 = N at level 0 (Sec. 2.4.3 p.7, Sec. 4.5.1 p.12), so the level-0 block of the basis is the polar transform G_N, which is unimodular; the lattice is therefore ZN and LLL reduction recovers B_red as a signed permutation of the identity for every set. This contradicts the random-basis assumption behind Definitions 2.6 and 5.1 (pp.7, 16) and the IND-CPA proof (Appendix B.1, Game 1, p.29).
Evidence
PQC-X first found this key recovery live in the reference and optimised code (10/10 and 200/200 matches across all sets). A second member of PQC-X then ran the recovery directly against the specification's own construction, independent of the code: at PolarKEM-128 (N=512), LLL reduction of B_red (2.1 s) returned a signed permutation matrix and O was recovered exactly (max|O'-O| = 0); at PolarKEM-256 (N=1024) and PolarKEM-512 (N=2048), LLL was replaced by the public polar-transform basis in place of B_red (LLL itself exceeded a 700 MB memory cap), recovering O to within 3.4e-15 in 0.09 s and 3.8e-15 in 0.70 s. In every run the recovered O inverted the ciphertext to the same value the honest decapsulator computes, to within 3e-10. This upgrades the finding from an implementation-only defect to a specification-level one: the missing trapdoor is in the normative algorithm text itself, not only in the reference code.
Cause in the specification, traced to the specification text.
Limits
As written, the normative specification does not itself decrypt for anyone, including the legitimate receiver: it gives no representation for its real-valued keys and ciphertexts, and the level-0 channel it would need carries near-zero capacity. On a strict reading the break is therefore that the secret is public, rather than an observed exchange of a shared secret; the code-level attack, which does complete such an exchange, was already reported publicly.
Credit
First public report: M.-J. Saarinen (ngcc.dev kem-29-1, 2026-09-21). Found independently by PQC-X.