{"record":{"id":"46be1797f84e8581","repo":"golang/go","slug":"ed25519-expected-opts-hash-zero-unhashed-message","errorCode":null,"errorMessage":"ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)","messagePattern":"ed25519: expected opts\\.Hash zero \\(unhashed message, for standard Ed25519\\) or SHA-512 \\(for Ed25519ph\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ed25519/ed25519.go","lineNumber":268,"sourceCode":"\tif l := len(publicKey); l != PublicKeySize {\n\t\tpanic(\"ed25519: bad public key length: \" + strconv.Itoa(l))\n\t}\n\tk, err := ed25519.NewPublicKey(publicKey)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch {\n\tcase opts.Hash == crypto.SHA512: // Ed25519ph\n\t\treturn ed25519.VerifyPH(k, message, sig, opts.Context)\n\tcase opts.Hash == crypto.Hash(0) && opts.Context != \"\": // Ed25519ctx\n\t\tif fips140only.Enforced() {\n\t\t\treturn errors.New(\"crypto/ed25519: use of Ed25519ctx is not allowed in FIPS 140-only mode\")\n\t\t}\n\t\treturn ed25519.VerifyCtx(k, message, sig, opts.Context)\n\tcase opts.Hash == crypto.Hash(0): // Ed25519\n\t\treturn ed25519.Verify(k, message, sig)\n\tdefault:\n\t\treturn errors.New(\"ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)\")\n\t}\n}\n","sourceCodeStart":250,"sourceCodeEnd":271,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ed25519/ed25519.go#L250-L271","documentation":"Thrown by the default switch arm in VerifyWithOptions (ed25519.go:268) when opts.Hash is neither crypto.Hash(0) nor crypto.SHA512. Ed25519 verification only supports the standard and pre-hash (ph) variants; any other hash selection is rejected. Mirrors error 249 on the verify side.","triggerScenarios":"Calling ed25519.VerifyWithOptions with opts.Hash set to crypto.SHA256, BLAKE2b, or any hash other than 0/SHA-512. Often from generic verification code forwarding an arbitrary SignerOpts hash.","commonSituations":"Generic verify plumbing that derives opts.Hash from a JOSE/JWS/COSE alg or an x509 SignatureAlgorithm; misconfiguring an Options struct.","solutions":["Use crypto.Hash(0) for standard Ed25519 verification or crypto.SHA512 for Ed25519ph.","When building opts, branch on the public key type and only set Hash to 0 or SHA-512 for Ed25519.","Validate opts.Hash is 0 or SHA-512 before calling VerifyWithOptions."],"exampleFix":"// before\nopts := &ed25519.Options{Hash: crypto.SHA256}\nerr := ed25519.VerifyWithOptions(pub, msg, sig, opts) // -> error 252\n\n// after\nerr := ed25519.Verify(pub, msg, sig) // standard Ed25519","handlingStrategy":"validation","validationCode":"if opts.Hash != crypto.Hash(0) && opts.Hash != crypto.SHA512 {\n    return errors.New(\"ed25519 verify requires Hash 0 or SHA-512\")\n}","typeGuard":"func validEd25519VerifyHash(h crypto.Hash) bool {\n    return h == crypto.Hash(0) || h == crypto.SHA512\n}","tryCatchPattern":null,"preventionTips":["Use crypto.Hash(0) or crypto.SHA512 for Ed25519 VerifyWithOptions.","Special-case Ed25519 keys in generic verify code.","Validate opts.Hash before calling VerifyWithOptions."],"tags":["go","crypto","ed25519","api-misuse"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}