golang/go · error

ecdsa: invalid signature: s is zero

Error message

ecdsa: invalid signature: s is zero

What it means

Thrown by fips140/ecdsa.verifyGeneric when the signature's s component is zero after parsing into the curve order field. Per FIPS 186-5 §6.4.2 s must be non-zero; a zero s makes s^-1 undefined and the verification equation invalid.

Source

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

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

	r, err := bigmod.NewNat().SetBytes(sig.R, c.N)
	if err != nil {
		return err
	}
	if r.IsZero() == 1 {
		return errors.New("ecdsa: invalid signature: r is zero")
	}
	s, err := bigmod.NewNat().SetBytes(sig.S, c.N)
	if err != nil {
		return err
	}
	if s.IsZero() == 1 {
		return errors.New("ecdsa: invalid signature: s is zero")
	}

	e := bigmod.NewNat()
	hashToNat(c, e, hash)

	// w = s⁻¹
	w := bigmod.NewNat()
	inverse(c, w, s)

	// p₁ = [e * s⁻¹]G
	p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
	if err != nil {
		return err
	}
	// p₂ = [r * s⁻¹]Q
	p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
	if err != nil {
		return err

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Reject signatures where sig.S is all-zero before calling Verify.
  2. Ensure signatures are produced by Sign/SignDeterministic, which never emit zero r or s.
  3. Validate fixed-width encoding of R and S before verification.

Example fix

// before
err := ecdsa.Verify(curve, pub, hash, sig)

// after
if isAllZero(sig.S) {
    return errors.New("malformed signature: s is zero")
}
err := ecdsa.Verify(curve, pub, hash, sig)
Defensive patterns

Strategy: validation

Validate before calling

if allZero(sig.S) {
    return errors.New("signature s is zero")
}
return ecdsa.Verify(c, pub, hash, sig)

Type guard

func nonZeroS(sig *ecdsa.Signature) bool {
    for _, b := range sig.S { if b != 0 { return true } }
    return false
}

Try / catch

if err := ecdsa.Verify(c, pub, hash, sig); err != nil {
    return err // do not retry verification on the same inputs
}

Prevention

When it happens

Trigger: Verifying a Signature whose S field is all zeros (or reduces to zero mod n) after a successful SetBytes.

Common situations: Corrupted/truncated signature, a default zero-filled S field from a struct literal, or a malformed signature from an untrusted source.

Related errors


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