golang/go · error
mldsa: invalid signature length
Error message
mldsa: invalid signature length
What it means
An ML-DSA signature is a fixed-size byte string: 2420 bytes for ML-DSA-44, 3309 for ML-DSA-65, 4627 for ML-DSA-87. Verify performs a length check up front (errInvalidSignatureLength) before any decoding; a blob of the wrong size is reported as malformed rather than as a forgery. This separates transport/encoding bugs from genuine cryptographic failures.
Source
Thrown at src/crypto/internal/fips140/mldsa/mldsa.go:625
if constantTimeAbs(r0) >= bound {
return true
}
}
case 88:
for i := range w {
_, r0 := decompose88(w[i])
if constantTimeAbs(r0) >= bound {
return true
}
}
default:
panic("mldsa: internal error: unsupported γ2")
}
return false
}
var (
errInvalidSignatureLength = errors.New("mldsa: invalid signature length")
errInvalidSignatureCoeffBounds = errors.New("mldsa: invalid signature")
errInvalidSignatureChallenge = errors.New("mldsa: invalid signature")
errInvalidSignatureHintLimits = errors.New("mldsa: invalid signature encoding")
errInvalidSignatureHintIndexOrder = errors.New("mldsa: invalid signature encoding")
errInvalidSignatureHintExtraIndices = errors.New("mldsa: invalid signature encoding")
)
func Verify(pub *PublicKey, msg, sig []byte, context string) error {
fipsSelfTest()
fips140.RecordApproved()
μ, err := computeMessageHash(pub.tr[:], msg, context)
if err != nil {
return err
}
return verifyInternal(pub, &μ, sig)
}
func VerifyExternalMu(pub *PublicKey, μ []byte, sig []byte) error {View on GitHub (pinned to b6b368adc5)
Solutions
- Decode base64/hex before calling Verify and assert the decoded length equals the expected SignatureSize constant.
- Persist the parameter set next to the signature and verify against the matching variant's public key.
- Trim trailing whitespace/NULs after reading the signature from a text medium.
- Add a length assertion at the deserialization boundary so the error message names the transport bug, not the crypto API.
Example fix
// before
ok := mldsa.Verify(pub, msg, base64Sig, ctx) == nil // still encoded
// after
sig, err := base64.StdEncoding.DecodeString(base64Sig)
if err != nil { return err }
err = mldsa.Verify(pub, msg, sig, ctx) Defensive patterns
Strategy: validation
Validate before calling
if len(sig) != wantSize { // 2420/3309/4627
return fmt.Errorf("signature must be %d bytes, got %d", wantSize, len(sig))
} Type guard
func isMLDSA44Signature(sig []byte) bool { return len(sig) == 2420 } Prevention
- Decode base64/hex at the boundary and assert decoded length.
- Store the parameter set alongside signatures and dispatch to the matching Verify.
- Trim trailing whitespace/NULs after reading from text media.
When it happens
Trigger: Calling mldsa.Verify(pub, msg, sig, context) where len(sig) does not equal the parameter set's SignatureSize.
Common situations: Signature transported base64/hex-encoded and not decoded; mixing ML-DSA-44 signatures with an ML-DSA-65 public key; truncation in a length-prefixed or URL-safe channel; trailing newline or NUL padding included in the slice.
Related errors
- mldsa: invalid seed length
- mldsa: invalid public key length
- mldsa: context too long
- mldsa: invalid message hash length
- mldsa: invalid semi-expanded private key size
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/3757e0f720508bb5.
Report an issue: GitHub.