{"record":{"id":"9cb9791056ee2c9f","repo":"golang/go","slug":"ed25519-bad-signature-length-l","errorCode":null,"errorMessage":"ed25519: bad signature length: {l}","messagePattern":"ed25519: bad signature length: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/ed25519/ed25519.go","lineNumber":292,"sourceCode":"\tif l := len(context); l > 255 {\n\t\treturn errors.New(\"ed25519: bad Ed25519ph context length: \" + strconv.Itoa(l))\n\t}\n\treturn verifyWithDom(pub, message, sig, domPrefixPh, context)\n}\n\nfunc VerifyCtx(pub *PublicKey, message []byte, sig []byte, context string) error {\n\tfipsSelfTest()\n\t// FIPS 186-5 specifies Ed25519 and Ed25519ph (with context), but not Ed25519ctx.\n\tfips140.RecordNonApproved()\n\tif l := len(context); l > 255 {\n\t\treturn errors.New(\"ed25519: bad Ed25519ctx context length: \" + strconv.Itoa(l))\n\t}\n\treturn verifyWithDom(pub, message, sig, domPrefixCtx, context)\n}\n\nfunc verifyWithDom(pub *PublicKey, message, sig []byte, domPrefix, context string) error {\n\tif l := len(sig); l != signatureSize {\n\t\treturn errors.New(\"ed25519: bad signature length: \" + strconv.Itoa(l))\n\t}\n\n\tif sig[63]&224 != 0 {\n\t\treturn errors.New(\"ed25519: invalid signature\")\n\t}\n\n\tkh := sha512.New()\n\tif domPrefix != domPrefixPure {\n\t\tkh.Write([]byte(domPrefix))\n\t\tkh.Write([]byte{byte(len(context))})\n\t\tkh.Write([]byte(context))\n\t}\n\tkh.Write(sig[:32])\n\tkh.Write(pub.aBytes[:])\n\tkh.Write(message)\n\thramDigest := make([]byte, 0, sha512Size)\n\thramDigest = kh.Sum(hramDigest)\n\tk, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/ed25519/ed25519.go#L274-L310","documentation":"Returned by verifyWithDom when the signature slice is not exactly signatureSize (64) bytes — a 32-byte R followed by a 32-byte S, per RFC 8032. Apply to Sign/SignPH/SignCtx verification paths and to pure Verify.","triggerScenarios":"Calling Verify / VerifyPH / VerifyCtx with sig of length != 64 — e.g. DER-encoded signature, 96-byte concatenated form, truncated bytes, hex string.","commonSituations":"Passing an ASN.1 DER ECDSA-style signature to Ed25519 verify; passing hex/base64 strings instead of decoded bytes; truncation in transit; off-by-one slice handling.","solutions":["Pass exactly 64 raw bytes for the signature.","Decode hex/base64 first and assert length==64.","If you received a DER signature, you are on the wrong algorithm — Ed25519 uses raw concatenation, not DER."],"exampleFix":"// before\nok := ed25519.Verify(pub, msg, []byte(sigHex))\n\n// after\nb, err := hex.DecodeString(sigHex)\nif err != nil { return err }\nif len(b) != 64 { return fmt.Errorf(\"ed25519 sig must be 64 bytes\") }\nerr = ed25519.Verify(pub, msg, b)","handlingStrategy":"validation","validationCode":"const ed25519SigSize = 64\nif len(sig) != ed25519SigSize {\n    return fmt.Errorf(\"ed25519 signature must be %d bytes, got %d\", ed25519SigSize, len(sig))\n}\nreturn ed25519.Verify(pub, message, sig)","typeGuard":null,"tryCatchPattern":"if err := ed25519.Verify(pub, message, sig); err != nil {\n    if strings.Contains(err.Error(), \"bad signature length\") {\n        return fmt.Errorf(\"received %d-byte sig; expected raw 64-byte Ed25519, not DER\", len(sig))\n    }\n    return err\n}","preventionTips":["Decode hex/base64 signatures at the boundary and assert length 64.","Remember Ed25519 uses raw R||S, not ASN.1 DER.","Validate before calling Verify to give clear errors."],"tags":["crypto","ed25519","fips140","validation","signature"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}