golang/go · error

ed25519: expected opts.Hash zero (unhashed message, for stan

Error message

ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)

What it means

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.

Source

Thrown at src/crypto/ed25519/ed25519.go:268

	if l := len(publicKey); l != PublicKeySize {
		panic("ed25519: bad public key length: " + strconv.Itoa(l))
	}
	k, err := ed25519.NewPublicKey(publicKey)
	if err != nil {
		return err
	}
	switch {
	case opts.Hash == crypto.SHA512: // Ed25519ph
		return ed25519.VerifyPH(k, message, sig, opts.Context)
	case opts.Hash == crypto.Hash(0) && opts.Context != "": // Ed25519ctx
		if fips140only.Enforced() {
			return errors.New("crypto/ed25519: use of Ed25519ctx is not allowed in FIPS 140-only mode")
		}
		return ed25519.VerifyCtx(k, message, sig, opts.Context)
	case opts.Hash == crypto.Hash(0): // Ed25519
		return ed25519.Verify(k, message, sig)
	default:
		return errors.New("ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
	}
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use crypto.Hash(0) for standard Ed25519 verification or crypto.SHA512 for Ed25519ph.
  2. When building opts, branch on the public key type and only set Hash to 0 or SHA-512 for Ed25519.
  3. Validate opts.Hash is 0 or SHA-512 before calling VerifyWithOptions.

Example fix

// before
opts := &ed25519.Options{Hash: crypto.SHA256}
err := ed25519.VerifyWithOptions(pub, msg, sig, opts) // -> error 252

// after
err := ed25519.Verify(pub, msg, sig) // standard Ed25519
Defensive patterns

Strategy: validation

Validate before calling

if opts.Hash != crypto.Hash(0) && opts.Hash != crypto.SHA512 {
    return errors.New("ed25519 verify requires Hash 0 or SHA-512")
}

Type guard

func validEd25519VerifyHash(h crypto.Hash) bool {
    return h == crypto.Hash(0) || h == crypto.SHA512
}

Prevention

When it happens

Trigger: 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.

Common situations: Generic verify plumbing that derives opts.Hash from a JOSE/JWS/COSE alg or an x509 SignatureAlgorithm; misconfiguring an Options struct.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/46be1797f84e8581. Report an issue: GitHub.