PQC-XXJTLU · cryptanalysis

HomePublic-key schemes › DARTS

Signature · lattice

DARTS

Design

darts-1

The message digest μ is 512 bits at every level, which caps DARTS-512 at 256 bits

Minor break · Argued · Cause: parameter size

Property: existential unforgeability

Cost against claim: digest collision 2256 against 2512

The message enters DARTS signing and verification only through the digest μ = H1(pk, M), which is 512 bits long at every security level, and the per-signature randomness is derived from (K, μ) with no salt hashed over the message. Two messages with the same μ therefore share every signing target, so a signature obtained on one verifies on the other. A generic collision on μ costs about 2256 classically and about 2171 on a quantum computer, against the 2512 and 2256 that level 512 requires.

Parameter setClaimAttack costVerdict
DARTS-512512 classical, 256 quantum2256 classical; about 2171 quantumMinor break
DARTS-256256 classical2256 (no margin)Holds

What causes it

The specification introduces H1 as the message hash without fixing its output length, and never scales μ with the level: Algorithm 7 (signing) sets μ = H1(pk, M) and derives the per-signature seed from (K, μ); Algorithm 8 (verification) uses M only through μ, at step 7. Every submitted implementation instance (reference, AVX2, NEON and their FIPS202 variants, for the three sets) fixes the length at 64 bytes (CRHBYTES in params.h).

Evidence

Argued from the specification and the code; nothing was run, as a 2256 collision is out of reach and the cost is an exact count. A second member of PQC-X re-read the specification for how the message enters the challenge and re-checked the 64-byte length in all 15 implementation instances.

Cause in the specification, traced to the specification text.

Limits

Generic and far from practical; fixed by scaling μ to twice the level. DARTS-128 is unaffected. The quantum figure is the BHT collision search, which needs quantum-accessible memory.

What PQC-X adds

The quantum cost (about 2171, also below the 2256 quantum requirement of level 512) and the zero margin it leaves DARTS-256.

Credit

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

Implementation

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

darts-i1

The submitted verifier's norm test can never fail; the signature size cap is what bounds a forger

Holds · Argued · Cause: code

Property: conformance; existential unforgeability holds

Cost against claim: none: the norm bound is never enforced, yet forgery stays at least 2140 / 2266 / 2538 core-SVP against the designers' 2137 / 2261 / 2535

The submitted verifier's only norm test compares the squared norm of z1 with its coefficients left in [0, q) (a small negative coefficient counts as nearly q) against B″² scaled by 228; the two errors cancel on honest signatures, so the test vectors pass, but the test can never fail for any signature the unpacker decodes, and the bound of Algorithm 8 is not enforced. What still constrains a forger's z is the fixed signature size: the two rANS-coded streams must fit in 471, 863 or 2649 bytes, and their symbol tables are fitted to honest signatures, so the cap acts as a norm bound at least as tight as B″ for the vectors lattice reduction produces. In the designers' own model, forging against the shipped verifier costs at least 140, 266 and 538 bits of classical core-SVP against their 137, 261 and 535: no level falls, but the code accepts some signatures that Algorithm 8 rejects.

Parameter setClaimAttack costVerdict
all DARTS sets, all implementationsthe norm bound of Algorithm 8 is enforcednone: forgery stays at or above the designers' figuresHolds

What causes it

In sign.c (line 355 in the reference, AVX2 and NEON code, line 380 in the FIPS202 variants), verification rejects only when the sum of the squared norms of z1 and z2 reaches B11SQ·LN·LN, with z1 recomposed from its low and high bits without centring and LN = 214 a fixed-point scale. Algorithm 8, step 12, requires the norm of the centred (z1, z2) to be below B″; the specification is sound on this point.

Evidence

Run on the unmodified DARTS-128 reference code: an honest signature gives a left side of about 5.7·1012 against a threshold of 1.5·1016. An exact bound from the code's constants shows that, for any signature the unpacker decodes, the left side is at most about 5.3·1013, 9.6·1013 and 7.7·1014 at the three levels, against thresholds of 1.5·1016, 1.4·1017 and 1.7·1018, so the test cannot fail; the same line sits in all 15 implementation instances. A second member of PQC-X derived that bound, parsed the rANS tables of the reference code (the resulting model reproduces the sizes of the shipped test vectors within about 1%), and costed forgery under the size cap with a core-SVP estimator and an independent GSA script, which agree within one block size. No non-conformant signature was constructed.

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

Limits

By a linear-programming bound, a sparse z with about 140, 215 or 460 coefficients at the edge of the coding alphabet fits the size cap with a norm of about 1.3 to 1.5 times B″, so the code would accept it and Algorithm 8 would not; this was argued, not demonstrated. The fix is to centre z1 and drop the 228 factor.

Credit

Found by PQC-X.