PQC-XXJTLU · cryptanalysis

HomePublic-key schemes › WeaverKEM

KEM · lattice

WeaverKEM

Implementation

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

weaverkem-i1

PRF nonce reuse between lifting and r

Holds · Argued · Cause: code

Property: IND-CCA security

Cost against claim: The lifting and the encryption randomness r consume overlapping PRF nonces, giving identical bytes where the design calls for disjoint streams

In every encapsulation (and in decapsulation's internal re-encryption), Weaver's reference code draws the message lifting and the ephemeral randomness r from overlapping PRF nonces instead of the disjoint stream the specification assigns to each. Nonces 1..k-1 are consumed by both uses, so the PRF, which is prefix-consistent, returns identical bytes for the shared nonces, contradicting the independence the IND-CPA proof assumes between the two quantities.

Parameter setClaimAttack costVerdict
WeaverKEM-128, -192, -256 (reference code)independent PRF streams for the lifting and for ridentical PRF bytes on overlapping nonces; no distinguisher builtHolds

What causes it

Algorithm 2 (spec p. 11) fixes one PRF stream at nonce 0 for the lifting and nonces 1..k for r. In the code, indcpa.c passes the lifting's nonce by value into polyvec_invq, so the caller's own counter only ever advances to 1, while polyvec_invq increments a separate, internal copy of the nonce across nonces 0..k-1 for its k polynomials. r is then drawn from prf(coins, 1+i) (indcpa.c:364-365). Nonces 1..k-1 are therefore consumed by both the lifting and r.

Evidence

Traced with a PRF-wrapping harness (prf_trace.c, built with -Wl,--wrap) linked against an unmodified copy of the reference sources whose three KAT files were first reproduced byte for byte. Across 300 encapsulations per parameter set, every run shows the same reused nonces with byte-identical PRF output: 256 bytes shared per encryption at Weaver-640 (nonces 1-4 of 5), 408 bytes at Weaver-1024 (nonces 1-3 of 4), and all four r streams (1088 bytes) at Weaver-2048; the pattern also appears in the re-encryption inside decapsulation. This is the overlap already reported for Loom's embedded core, confirmed independently in Weaver's own submitted code; no exploitation was attempted.

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

Limits

No distinguishing or recovery attack was run; this confirms the code-only byte overlap, not a demonstrated break.

Credit

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