golang/go · error

ecdsa: public key does not match curve

Error message

ecdsa: public key does not match curve

What it means

Thrown by fips140/ecdsa.Verify when the public key's curve does not match the operation context curve (pub.curve != c.curve). Verification requires the curve handle, the public key, and (implicitly) the signature to all correspond to the same curve.

Source

Thrown at src/crypto/internal/fips140/ecdsa/ecdsa.go:452

	for i := len(b) - 1; i >= 0; i-- {
		b[i] >>= shift
		if i > 0 {
			b[i] |= b[i-1] << (8 - shift)
		}
	}
	return b
}

// Verify verifies the signature, sig, of hash (which should be the result of
// hashing a larger message) using the public key, pub. If the hash is longer
// than the bit-length of the private key's curve order, the hash will be
// truncated to that length.
//
// The inputs are not considered confidential, and may leak through timing side
// channels, or if an attacker has control of part of the inputs.
func Verify[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature) error {
	if pub.curve != c.curve {
		return errors.New("ecdsa: public key does not match curve")
	}
	if len(hash) == 0 {
		return errors.New("ecdsa: hash cannot be empty")
	}
	fips140.RecordApproved()
	fipsSelfTest()
	return verify(c, pub, hash, sig)
}

func verifyGeneric[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature) error {
	// FIPS 186-5, Section 6.4.2

	Q, err := c.newPoint().SetBytes(pub.q)
	if err != nil {
		return err
	}

	r, err := bigmod.NewNat().SetBytes(sig.R, c.N)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Select c from the same curve the public key was constructed with.
  2. Assert pub.curve == c before calling Verify.
  3. Carry the curve with the public key and pass it as c.

Example fix

// before
err := ecdsa.Verify(ecdsa.P256(), p384Pub, hash, sig)

// after
err := ecdsa.Verify(ecdsa.P384(), p384Pub, hash, sig)
Defensive patterns

Strategy: validation

Validate before calling

if pub.Curve() != c.Curve() {
    return errors.New("public key curve differs from verify context")
}
return ecdsa.Verify(c, pub, hash, sig)

Type guard

func keyMatchesVerifyCurve(c *ecdsa.Curve, pub *ecdsa.PublicKey) bool {
    return pub.Curve() == c.Curve()
}

Prevention

When it happens

Trigger: Calling Verify(c, pub, hash, sig) where c and pub belong to different curves.

Common situations: Verifying a signature with the wrong curve handle, mixing keys from a P-256 and P-384 system, or a verifier that picks a default curve constant.

Related errors


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