golang/go · error
ed25519: invalid signature
Error message
ed25519: invalid signature
What it means
Returned by verifyWithDom when sig[63] & 224 != 0 — i.e. the high three bits of the 32-byte S scalar are non-zero. Ed25519 mandates S be canonical (less than the group order L, ~2^252), so the high bits must be zero. A signature failing this check is malformed or crafted to exploit non-canonical scalars.
Source
Thrown at src/crypto/internal/fips140/ed25519/ed25519.go:296
}
func VerifyCtx(pub *PublicKey, message []byte, sig []byte, context string) error {
fipsSelfTest()
// FIPS 186-5 specifies Ed25519 and Ed25519ph (with context), but not Ed25519ctx.
fips140.RecordNonApproved()
if l := len(context); l > 255 {
return errors.New("ed25519: bad Ed25519ctx context length: " + strconv.Itoa(l))
}
return verifyWithDom(pub, message, sig, domPrefixCtx, context)
}
func verifyWithDom(pub *PublicKey, message, sig []byte, domPrefix, context string) error {
if l := len(sig); l != signatureSize {
return errors.New("ed25519: bad signature length: " + strconv.Itoa(l))
}
if sig[63]&224 != 0 {
return errors.New("ed25519: invalid signature")
}
kh := sha512.New()
if domPrefix != domPrefixPure {
kh.Write([]byte(domPrefix))
kh.Write([]byte{byte(len(context))})
kh.Write([]byte(context))
}
kh.Write(sig[:32])
kh.Write(pub.aBytes[:])
kh.Write(message)
hramDigest := make([]byte, 0, sha512Size)
hramDigest = kh.Sum(hramDigest)
k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)
if err != nil {
panic("ed25519: internal error: setting scalar failed")
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Reject the signature as malformed — do not attempt to 'normalize' it.
- Audit the signer if many signatures fail this check; it likely is not producing canonical S.
- Verify against a reference implementation (e.g. the standard ed25519 package) to confirm the bytes are genuinely malformed.
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap pre-check: high 3 bits of S must be zero (S < 2^252 is enforced more strictly next).
if len(sig) == 64 && sig[63]&224 != 0 {
return ErrMalformedSignature
}
return ed25519.Verify(pub, message, sig) Try / catch
if err := ed25519.Verify(pub, message, sig); err != nil {
if strings.Contains(err.Error(), "invalid signature") {
// covers high-bits-set, non-canonical S, and equation failure
return ErrSignatureRejected
}
return err
} Prevention
- Reject high-bit-set signatures early as malformed.
- Audit signers that produce non-canonical S.
- Never attempt to normalize a malformed signature.
When it happens
Trigger: Calling an Ed25519 Verify variant with a 64-byte signature whose trailing 32 bytes encode an S value >= L (high bits set).
Common situations: Corrupted signature bytes; signature from a buggy signer that did not reduce S mod L; adversarial input probing for verification malleability; byte-swap or endianness mistake.
Related errors
- ed25519: bad signature length: {l}
- invalid signature
- ed25519: bad seed length: {l}
- ed25519: bad private key length: {l}
- ed25519: bad public key length: {l}
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/06c438f35ef2ab0d.
Report an issue: GitHub.