{"record":{"id":"e47fb95965abf0ad","repo":"golang/go","slug":"ed25519-bad-ed25519ph-context-length-l","errorCode":null,"errorMessage":"ed25519: bad Ed25519ph context length: {l}","messagePattern":"ed25519: bad Ed25519ph context length: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/ed25519/ed25519.go","lineNumber":193,"sourceCode":"\tfips140.RecordApproved()\n\treturn signWithDom(signature, priv, message, domPrefixPure, \"\")\n}\n\nfunc SignPH(priv *PrivateKey, message []byte, context string) ([]byte, error) {\n\t// Outline the function body so that the returned signature can be\n\t// stack-allocated.\n\tsignature := make([]byte, signatureSize)\n\treturn signPH(signature, priv, message, context)\n}\n\nfunc signPH(signature []byte, priv *PrivateKey, message []byte, context string) ([]byte, error) {\n\tfipsSelfTest()\n\tfips140.RecordApproved()\n\tif l := len(message); l != sha512Size {\n\t\treturn nil, errors.New(\"ed25519: bad Ed25519ph message hash length: \" + strconv.Itoa(l))\n\t}\n\tif l := len(context); l > 255 {\n\t\treturn nil, errors.New(\"ed25519: bad Ed25519ph context length: \" + strconv.Itoa(l))\n\t}\n\treturn signWithDom(signature, priv, message, domPrefixPh, context), nil\n}\n\nfunc SignCtx(priv *PrivateKey, message []byte, context string) ([]byte, error) {\n\t// Outline the function body so that the returned signature can be\n\t// stack-allocated.\n\tsignature := make([]byte, signatureSize)\n\treturn signCtx(signature, priv, message, context)\n}\n\nfunc signCtx(signature []byte, priv *PrivateKey, message []byte, context string) ([]byte, error) {\n\tfipsSelfTest()\n\t// FIPS 186-5 specifies Ed25519 and Ed25519ph (with context), but not Ed25519ctx.\n\tfips140.RecordNonApproved()\n\t// Note that per RFC 8032, Section 5.1, the context SHOULD NOT be empty.\n\tif l := len(context); l > 255 {\n\t\treturn nil, errors.New(\"ed25519: bad Ed25519ctx context length: \" + strconv.Itoa(l))","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/ed25519/ed25519.go#L175-L211","documentation":"Returned by SignPH when the context string exceeds 255 bytes. RFC 8032 encodes the context length in a single leading byte, so 255 is the hard ceiling for Ed25519ph and Ed25519ctx.","triggerScenarios":"Calling fips140/ed25519.SignPH(priv, digest, context) with len(context) > 255 — e.g. passing a full URL, certificate, or arbitrary blob as the context.","commonSituations":"Stuffing domain-separation metadata, paths, or JSON into the context field; concatenating multiple context values without first hashing them down.","solutions":["Keep the context string to <= 255 bytes; ideally a short stable identifier.","If you need more domain separation, hash the longer blob to 32 bytes and use that as the context (or fold it into the message).","Pass an empty context if no context binding is required for Ed25519ph."],"exampleFix":"// before\nsig, err := ed25519.SignPH(priv, digest, longPolicyDocument)\n\n// after\nctxID := sha256.Sum256([]byte(longPolicyDocument))\nsig, err := ed25519.SignPH(priv, digest, string(ctxID[:]))","handlingStrategy":"validation","validationCode":"if len(context) > 255 {\n    h := sha256.Sum256([]byte(context))\n    context = string(h[:])\n}\nsig, err := ed25519.SignPH(priv, digest, context)","typeGuard":null,"tryCatchPattern":"sig, err := ed25519.SignPH(priv, digest, context)\nif err != nil {\n    if strings.Contains(err.Error(), \"bad Ed25519ph context length\") {\n        return nil, fmt.Errorf(\"context too long (%d > 255)\", len(context))\n    }\n    return nil, err\n}","preventionTips":["Use short stable identifiers as context.","Hash long domain-separation strings to 32 bytes before passing.","Share the canonical context between signer and verifier."],"tags":["crypto","ed25519","ed25519ph","fips140","validation","context"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}