PQC-XXJTLU · cryptanalysis

HomePublic-key schemes › MORNING-Scabbard

KEM · lattice

MORNING-Scabbard

Design

morning-scabbard-1

The decryption failure rate of Scabbard-256 is 2-58.62, not the claimed 2-125.53: a first failure fits within the call's 280 decapsulations

Security proof gap · Argued · Cause: specification text

Property: IND-CCA security (the failure-rate argument)

Cost against claim: failure rate 2-58.62 against 2-125.53 claimed; about 221 honest failures within the call's 280 decapsulations

The specification's Table 7 claims a decryption-failure rate of 2-125.53 for Scabbard-256, derived from a tool that models the ciphertext term v's compression error as a centred, symmetric round trip. Traced exactly through Algorithms 10 and 11, v is instead floored with no recentring constant, which biases the error to a mean of about +254 per coordinate and gives an actual rate of 2-58.62, a 67-bit gap. Within the call's 280-query budget, honest ciphertexts then fail about 221 times, and the spec's own proof bound (Theorem 5, 264 times the claimed rate) is vacuous at that rate.

Parameter setClaimAttack costVerdict
Scabbard-256failure rate 2-125.53 (Table 7); IND-CCA at 256 bitsfailure rate 2-58.62; about 221 honest failures within the call's 280 decapsulations; key recovery from failures not run or costedSecurity proof gap

What causes it

The designers' DFR tool (dfr_analysis/joint_distribution_2d.c, prob_dist_1d_init_as_compress_decompress_error) models the v-compression error as centred, matching neither Algorithm 10 line 5 nor Algorithm 11 line 8 (spec p. 11), which floor v with no compensating term.

Evidence

Exact per-coordinate distributions (integer counts, python-flint) reproduce the designers' own 2-125.53 under their model and give 2-58.62 under the spec's actual equations. A C harness built from a fresh, unmodified copy of the reference code, which reproduces the official KATs byte for byte, measured 30.7 million noise samples over 40 keys and matched the predicted tails to within 10 to 35 percent down to probability 1e-6. A second member of PQC-X re-ran both the exact computation and the harness independently and got the same figures.

Cause in the specification: the attack also works on a model built from the specification alone.

Limits

Key recovery from the failures (D'Anvers et al., PKC 2019; D'Anvers, Rossi and Virdia, EUROCRYPT 2020) was neither run nor costed, so no attack below the claim is known. Scabbard-512 is unaffected, the same bias costs only a few bits there. Scabbard-128 has the same mechanism but its exact rate under it was not computed.

Credit

Found by PQC-X.

Implementation

Bugs in the submitted code; the specification is sound on these points.

morning-scabbard-2

Encryption floors the ciphertext term u with no rounding constant at Scabbard-128 and -256, widening the decryption-failure rate further

Security proof gap · Demonstrated · Cause: code

Property: IND-CCA security (the failure-rate argument)

Cost against claim: reference, AVX2 and Cortex-M4 code omit the spec's +h1 term on u at 128 and 256; DFR at 256 moves from 2-58.62 to 2-35.65, matching the official KATs

The reference, AVX2 and Cortex-M4 code compute the ciphertext term u by flooring with no added constant at Scabbard-128 and -256, while the 512 code and the specification (Algorithm 10 line 5, p. 11) add h1 before flooring. The official known-answer tests match the code, not the specification, so a spec-conformant implementation would fail them. The extra bias raises the noise standard deviation and moves the Scabbard-256 decryption-failure rate from 2-58.62 (spec as written) to 2-35.65.

Parameter setClaimAttack costVerdict
Scabbard-256failure rate 2-58.62 under the specification as writtenfailure rate 2-35.65 in the shipped code; matches the official KATsSecurity proof gap

What causes it

indcpa.c lines 64 to 69 (256) and 66 to 71 (128) floor u with no h1 add; line 68 of the same file adds it for 512. The Optimized_Implementation (AVX2) and the Cortex-M4 code show the same pattern, h1 only at 512. Algorithm 10 line 5 (spec p. 11) specifies u = ((As' + h) mod q) >> (eq minus ep) at every level.

Evidence

PQC-X built a fresh, unmodified copy of the reference code, reproduced KAT_KEM_scabbard256.txt byte for byte, and measured a noise mean of +252.2 against +256.0 for a copy patched to add h1, over 40 keys times 6000 ciphertexts times 128 coordinates. The AVX2 and Cortex-M4 sources were read line by line for the same omission. A second member of PQC-X reread the three code trees independently and confirmed the same lines.

Cause in the submitted code; the specification is not affected.

Limits

Scabbard-128 has the same code pattern; its exact failure rate under this deviation was not computed. Two further code deviations in the same decoder, a codeword constant off by one unit and an edge-case threshold, shift results by under 0.5 bit of DFR and carry no measurable security consequence.

Credit

First public report: M.-J. Saarinen (ngcc.dev kem-24-1, 2026-09-21). Found independently by PQC-X.