{"record":{"id":"3757e0f720508bb5","repo":"golang/go","slug":"mldsa-invalid-signature-length","errorCode":null,"errorMessage":"mldsa: invalid signature length","messagePattern":"mldsa: invalid signature length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/mldsa/mldsa.go","lineNumber":625,"sourceCode":"\t\t\tif constantTimeAbs(r0) >= bound {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase 88:\n\t\tfor i := range w {\n\t\t\t_, r0 := decompose88(w[i])\n\t\t\tif constantTimeAbs(r0) >= bound {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tpanic(\"mldsa: internal error: unsupported γ2\")\n\t}\n\treturn false\n}\n\nvar (\n\terrInvalidSignatureLength           = errors.New(\"mldsa: invalid signature length\")\n\terrInvalidSignatureCoeffBounds      = errors.New(\"mldsa: invalid signature\")\n\terrInvalidSignatureChallenge        = errors.New(\"mldsa: invalid signature\")\n\terrInvalidSignatureHintLimits       = errors.New(\"mldsa: invalid signature encoding\")\n\terrInvalidSignatureHintIndexOrder   = errors.New(\"mldsa: invalid signature encoding\")\n\terrInvalidSignatureHintExtraIndices = errors.New(\"mldsa: invalid signature encoding\")\n)\n\nfunc Verify(pub *PublicKey, msg, sig []byte, context string) error {\n\tfipsSelfTest()\n\tfips140.RecordApproved()\n\tμ, err := computeMessageHash(pub.tr[:], msg, context)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn verifyInternal(pub, &μ, sig)\n}\n\nfunc VerifyExternalMu(pub *PublicKey, μ []byte, sig []byte) error {","sourceCodeStart":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/mldsa/mldsa.go#L607-L643","documentation":"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.","triggerScenarios":"Calling mldsa.Verify(pub, msg, sig, context) where len(sig) does not equal the parameter set's SignatureSize.","commonSituations":"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.","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."],"exampleFix":"// before\nok := mldsa.Verify(pub, msg, base64Sig, ctx) == nil  // still encoded\n\n// after\nsig, err := base64.StdEncoding.DecodeString(base64Sig)\nif err != nil { return err }\nerr = mldsa.Verify(pub, msg, sig, ctx)","handlingStrategy":"validation","validationCode":"if len(sig) != wantSize { // 2420/3309/4627\n    return fmt.Errorf(\"signature must be %d bytes, got %d\", wantSize, len(sig))\n}","typeGuard":"func isMLDSA44Signature(sig []byte) bool { return len(sig) == 2420 }","tryCatchPattern":null,"preventionTips":["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."],"tags":["crypto","mldsa","fips","validation","input-length"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}