PQC-XXJTLU · cryptanalysis

HomePublic-key schemes › Aigis-Sig+

Signature · lattice

Aigis-Sig+

Design

aigis-sig-plus-1

The 384- and 768-bit message digest µ caps PARAMS II at 2192 and PARAMS III at 2384

Minor break · Argued · Cause: parameter size

Property: existential unforgeability

Cost against claim: digest collision 2192 against 2256 (PARAMS II), 2384 against 2512 (PARAMS III)

Signing and verification read the message only through µ = CRH(tr‖M), where tr is a hash of the public key and µ has 384 bits at PARAMS I and II and 768 bits at PARAMS III. Any valid signature on M therefore verifies for every M′ with the same µ, and because signing is deterministic in the secret key and µ, the two messages would even receive byte-identical signatures: a signature obtained on M is a forgery on M′. A generic collision on µ costs 2192 evaluations at PARAMS II and 2384 at PARAMS III, against 256 and 512 bits claimed; PARAMS I keeps 2192 against 128.

Parameter setClaimAttack costVerdict
PARAMS II256 classical, 128 quantum2192 classical; 2128 quantum (on the requirement)Minor break
PARAMS III512 classical, 256 quantum2384 classical; 2256 quantum (on the requirement)Minor break
PARAMS I128 classical, 80 quantum2192 classical (above the claim)Holds

What causes it

Table 3 fixes the CRH output at κ2 = 48, 48 and 96 bytes for the three sets. Algorithm 30 (Sign) uses M only at line 3, µ := CRH(tr‖M), and derives the mask (line 7) and the challenge (line 11) from µ; Algorithm 31 (Verify) uses M only at line 5, µ := CRH(CRH(pk)‖M). Section 8.4 states that the hash is collision resistant at the level of the concrete parameters, which a 384-bit output cannot be at 256 bits. The reference code follows the specification on this point (CRHBYTES = 48, 48, 96).

Evidence

An exact count from the lengths the specification fixes, not a run. A second member of PQC-X re-read Table 3, Algorithms 30 and 31 and the code paths that consume the message (the digest and ExpandMask), re-derived the costs (2192 and 2384 evaluations with parallel collision search, about 2209 and 2403 bit operations, still below 256 and 512) and the quantum side (2128 and 2256 with the BHT collision search, exactly the call's quantum requirement, so the shortfall is classical only), and checked determinism on the reference code: signing the same message twice with the random generator advanced in between gave byte-identical signatures in 5 of 5 trials per set.

Cause in the specification, traced to the specification text.

Limits

Generic and far from practical; fixed by lengthening µ to twice the level. PARAMS I is unaffected. The transfer does not depend on determinism: verification reads M only through µ, so a valid signature on M verifies for M′ regardless.

Credit

Found by PQC-X.

The same 384-bit µ is in the round-2 Dilithium specification (Ducas et al., NIST PQC submission); Dilithium's round-3 specification, version 3.1, lengthened µ to 512 bits.

Implementation

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

aigis-sig-plus-i1

Every submitted implementation keeps one sign bit of the challenge at PARAMS I and II

Minor break · Argued · Cause: code

Property: existential unforgeability

Cost against claim: forgery by challenge guessing 2213.5 against 2256 (PARAMS II)

Scope: Every submitted implementation (reference, AVX2, aarch64, NEON) at PARAMS I and II, and the official test vectors of those two sets.

The specified challenge has τ nonzero coefficients with independent signs, a space of about 2160 at PARAMS I and 2256 at PARAMS II. The submitted sampler clears its sign word after the first placement, so every challenge has at most one negative coefficient and its min-entropy falls to 137.2 and 213.5 bits. A forger who fixes an all-positive challenge, z = 0 and an empty hint (the verifier's range checks pass for them) needs only a message whose hash yields that challenge: 2213.5 trials at PARAMS II, below the 256-bit claim, with no signing query at all.

Parameter setClaimAttack costVerdict
PARAMS II256 classical, 128 quantum2213.5 classical; 2106.7 quantum (Grover oracle calls, about 2126 Toffoli gates)Minor break
PARAMS I128 classical, 80 quantum2137.2 classical; 268.6 Grover oracle calls, about 287 Toffoli gatesHolds

What causes it

In unpack_c, the branch for τ ≤ 64 (PARAMS I and II) sets the sign word to zero after reading its first bit instead of shifting it, so every later coefficient gets the sign +1 (reference polyvec.c; the same line is in the AVX2, aarch64 and NEON sources). Algorithm 24 of the specification draws a fresh sign bit for each placement and is correct; the branch for τ > 64, used by PARAMS III, is correct too. Signing and verification share the sampler, so the official test vectors of PARAMS I and II were produced with the defect.

Evidence

On a fresh, unmodified build of the reference code, 200,000 challenges per set (two independent seed streams, in the SHA3 instantiation of Table 3 and in the call's ICCS build): at PARAMS I and II the sampler never matches Algorithm 24 (0 of 200,000) and always matches Algorithm 24 with every sign after the first forced to +1 (200,000 of 200,000); each challenge has 0 or 1 negative coefficient, uniformly placed. PARAMS III matches Algorithm 24 in 200,000 of 200,000 draws. With the one-line fix the sampler matches Algorithm 24 in 100,000 of 100,000 draws, and a verifier built with it rejects all 10 official test-vector signatures of PARAMS I and II while accepting all 10 of PARAMS III; the unmodified verifier accepts all 30. The forgery costs are computed from the measured distribution, not run. A second member of PQC-X re-ran these measurements on an independent copy of the submission, re-derived the entropy and cost figures, and checked by reading that the AVX2, aarch64 and NEON sources carry the same line.

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

Limits

PARAMS I stays above its classical claim (2137.2 against 2128). Its Grover search takes 268.6 oracle calls but about 287 Toffoli gates, so it meets the call's 80-bit quantum floor when Grover is counted in gates and falls under it only when counted in oracle calls; it is not rated a break. PARAMS III is unaffected. The optimised implementations were checked by reading, not run. The one-line fix makes the code follow Algorithm 24 but invalidates the official test vectors of PARAMS I and II.

Designers' response

In reply to other reports on the submitted code, the designers posted an updated implementation and new test vectors on the PKC forum (2026-09-22). PQC-X has not checked whether they change the challenge sampler.

Credit

Found by PQC-X.