golang/go · error
Ed25519 verification failure
Error message
Ed25519 verification failure
What it means
Thrown by tls verifyHandshakeSignature when ed25519.Verify returns false for an Ed25519 signature. The pubkey was confirmed to be an ed25519.PublicKey, so the failure is a true signature mismatch: the signature does not authenticate the signed data under that key.
Source
Thrown at src/crypto/tls/auth.go:47
h.Write(signed)
signed = h.Sum(nil)
}
switch sigType {
case signatureECDSA:
pubKey, ok := pubkey.(*ecdsa.PublicKey)
if !ok {
return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
}
if !ecdsa.VerifyASN1(pubKey, signed, sig) {
return errors.New("ECDSA verification failure")
}
case signatureEd25519:
pubKey, ok := pubkey.(ed25519.PublicKey)
if !ok {
return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
}
if !ed25519.Verify(pubKey, signed, sig) {
return errors.New("Ed25519 verification failure")
}
case signatureMLDSA:
pubKey, ok := pubkey.(*mldsa.PublicKey)
if !ok {
return fmt.Errorf("expected an ML-DSA public key, got %T", pubkey)
}
if err := mldsa.Verify(pubKey, signed, sig, nil); err != nil {
return fmt.Errorf("ML-DSA verification failure: %w", err)
}
case signaturePKCS1v15:
pubKey, ok := pubkey.(*rsa.PublicKey)
if !ok {
return fmt.Errorf("expected an RSA public key, got %T", pubkey)
}
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
return err
}
case signatureRSAPSS:View on GitHub (pinned to b6b368adc5)
Solutions
- Confirm the certificate's Ed25519 public key matches the key that produced the signature.
- Trace the exact signed bytes on both sides to rule out transcript divergence.
- Validate the 64-byte signature length and encoding before verification.
- Use crypto/ed25519 for both signing and verifying to guarantee RFC 8032 conformance.
Example fix
// before
ok := ed25519.Verify(pub, wrongMessage, sig) // different bytes
// after
ok := ed25519.Verify(pub, handshakeTranscript, sig)
if !ok { return errors.New("bad ed25519 signature") } Defensive patterns
Strategy: try-catch
Type guard
func isEd25519PubKey(k any) bool {
_, ok := k.(ed25519.PublicKey)
return ok
} Try / catch
if err := tlsConn.VerifyHostname(name); err != nil {
if strings.Contains(err.Error(), "Ed25519 verification failure") {
// likely wrong key, tampered signature, or transcript divergence
}
} Prevention
- Use crypto/ed25519 on both ends to guarantee RFC 8032 semantics.
- Confirm the certificate's Ed25519 public key matches the signer.
- Check signature length is 64 bytes before verifying.
- Trace the signed bytes on both sides when diagnosing failures.
When it happens
Trigger: During a TLS handshake the peer presents an Ed25519-signed handshake message whose signature fails ed25519.Verify(pub, signed, sig). Path: signatureEd25519 in verifyHandshakeSignature.
Common situations: Wrong public key associated with the certificate; signature computed over different transcript bytes (e.g., a MITM altering messages); truncated or altered signature on the wire; an Ed25519 implementation that deviates from RFC 8032.
Related errors
- ECDSA verification failure
- crypto/ed25519: use of Ed25519ctx is not allowed in FIPS 140
- ed25519: expected opts.HashFunc() zero (unhashed message, fo
- crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 1
- ed25519: expected opts.Hash zero (unhashed message, for stan
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/71e0d6cbbdbf549e.
Report an issue: GitHub.