yuanyang-kem-1
Failure rate far above the claim: the overflow locator accepts false matches
Holds · Tested at small scale · Cause: specification text
Property: IND-CCA security
Cost against claim: Failure rate 2-112.8 / 2-237.1 / 2-472.9 against 2-130.5 / 2-270.2 / 2-531.5 claimed; no failure within 280 queries
When exactly one coefficient overflows, decryption locates it by testing every shift of f⁻¹ for containment rather than equality, and sums every shift that passes. A wrong shift passes with probability 2-49.0 / 2-102.2 / 2-208.4, which, times the single overflow rate, gives a failure rate 17.7 to 58.6 bits above the designers' figures and above their own criterion δ < 2^-λ at every level.
| Parameter set | Claim | Attack cost | Verdict |
|---|
| YuanYang.KEM-512 | failure rate 2-130.5 | failure rate 2-112.8; 2-32.8 expected failures in 280 queries | Holds |
| YuanYang.KEM-1024 | failure rate 2-270.2 | failure rate 2-237.1 | Holds |
| YuanYang.KEM-2048 | failure rate 2-531.5 | failure rate 2-472.9 | Holds |
What causes it
Specification Alg. 6, line 8 accepts every shift i with ⟨u, f̄Xⁱ⟩ = Hamming(u), a containment test, whereas Alg. 5, line 5 tests equality, High(m′) = 0. The designers' failure analysis (independent Gaussian coefficients, at least two overflows) omits this false match event. The code (kem.c, lines 205 to 220) uses the same test.
Evidence
The false match probability was computed exactly with a path formula checked by brute force over all 216 vectors at n = 16; a Monte Carlo of Alg. 6 as written, with real keys, gave 0.091 at d = 64 (formula 0.127) and 1.9e-3 at d = 128 (formula 1.56e-3, 38 events). The per coefficient tail, 2-72.7 / 2-144.9 / 2-275.5, was recomputed by a saddle point method independent of the original convolution. A second member of PQC-X re-derived all of it with independent code; the designers' own two overflow term re-derives to 2-131.1 / 2-269.1 / 2-531.7, close to their claim.
Cause in the specification, traced to the specification text.
Limits
No attack: 2-32.8 expected failures in 280 queries at level 128, and the 2-41 fraction of keys with a bad shift cannot be identified. The failure boosting cost was not re-checked.
Credit
Found by PQC-X.
Bugs in the submitted code; the specification is sound on these points.
yuanyang-kem-i1
Encryption samples the error polynomial e but never adds it
Security proof gap · Demonstrated · Cause: code
Property: message recovery
Cost against claim: Implemented instance at level 128: 2121.2 core-SVP against 128 claimed, 2139.4 and more in MATZOV
Every implementation computes the ciphertext from h·s plus the message term only, so the sole noise left is the compression rounding, and the official test vectors are the output of this code. The security theorem, which relies on the RLWE mask hs + e, does not cover what is shipped. Message recovery on the implemented instance falls below the level 128 claim in the designers' core-SVP metric, by under 8 bits with the real mix of samples, while the MATZOV estimates stay above target at every level.
| Parameter set | Claim | Attack cost | Verdict |
|---|
| YuanYang.KEM-512 | 128 classical, 116 quantum (core-SVP) | 2121.2 core-SVP with the real sample mix (2115.9 if every sample were message free); 2139.4 to 2144.9 MATZOV | Security proof gap |
| YuanYang.KEM-1024 | 256 classical, 232 quantum (core-SVP) | 2256.1 core-SVP with the real sample mix (2246.7 if every sample were message free); 2267.6 to 2275.8 MATZOV | Security proof gap |
| YuanYang.KEM-2048 | 520 classical, 472 quantum (core-SVP) | 2522.7 core-SVP with the real sample mix (2506.6 if every sample were message free); 2519.7 to 2536.4 MATZOV | Security proof gap |
What causes it
Specification Alg. 3, line 4 sets c̄ = hs + e + m·p⁻¹ before compression, and Theorem 5.3 relies on hs + e. In kem.c, yy_encrypt (identical in all six trees, reference and optimized, three sets), line 120 fills e with ring_samp, line 121 computes h·s through a three argument NTT product, and lines 124 to 128 add only the message term and compress; e is never used again.
Evidence
All six unmodified trees build and reproduce the 30 official vectors byte for byte. Encapsulating to the all zero public key, 0 of 12,800 / 25,600 / 51,200 message free coefficients differ from Compress(0), where the specification predicts about 30 to 35% non zero. A maximum likelihood fit on the official vectors recovers the secret variance correctly (3.02 / 1.98 / 1.97 against 3.00 / 1.97 / 1.97) and an error variance of 0.64 / 1.20 / 1.27, which is rounding alone (0.667 / 1.25 / 1.25), far from the specified 3.135 / 2.906 / 2.242. Lattice costs come from the lattice estimator with caps lifted, modelling that only half of the ciphertext coefficients are free of message bits. A second member of PQC-X rebuilt every tree, wrote the zero key test and the fit, and re-ran the estimates independently.
Cause in the submitted code; the specification is not affected.
Limits
Not a break under our rules: the level 128 shortfall is under 8 bits with the real sample mix and appears in core-SVP only; levels 256 and 512 hold. The 2048 set sits at block sizes far beyond any measured point.
Credit
First public report: Yijian Liu (ngcc.dev kem-40-1, 2026-09-22). Found independently by PQC-X.