{"record":{"id":"1f03da27b042dab7","repo":"golang/go","slug":"ecdsa-invalid-signature-s-is-zero","errorCode":null,"errorMessage":"ecdsa: invalid signature: s is zero","messagePattern":"ecdsa: invalid signature: s is zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/ecdsa/ecdsa.go","lineNumber":482,"sourceCode":"\n\tQ, err := c.newPoint().SetBytes(pub.q)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tr, err := bigmod.NewNat().SetBytes(sig.R, c.N)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif r.IsZero() == 1 {\n\t\treturn errors.New(\"ecdsa: invalid signature: r is zero\")\n\t}\n\ts, err := bigmod.NewNat().SetBytes(sig.S, c.N)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif s.IsZero() == 1 {\n\t\treturn errors.New(\"ecdsa: invalid signature: s is zero\")\n\t}\n\n\te := bigmod.NewNat()\n\thashToNat(c, e, hash)\n\n\t// w = s⁻¹\n\tw := bigmod.NewNat()\n\tinverse(c, w, s)\n\n\t// p₁ = [e * s⁻¹]G\n\tp1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))\n\tif err != nil {\n\t\treturn err\n\t}\n\t// p₂ = [r * s⁻¹]Q\n\tp2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))\n\tif err != nil {\n\t\treturn err","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/ecdsa/ecdsa.go#L464-L500","documentation":"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.","triggerScenarios":"Verifying a Signature whose S field is all zeros (or reduces to zero mod n) after a successful SetBytes.","commonSituations":"Corrupted/truncated signature, a default zero-filled S field from a struct literal, or a malformed signature from an untrusted source.","solutions":["Reject signatures where sig.S is all-zero before calling Verify.","Ensure signatures are produced by Sign/SignDeterministic, which never emit zero r or s.","Validate fixed-width encoding of R and S before verification."],"exampleFix":"// before\nerr := ecdsa.Verify(curve, pub, hash, sig)\n\n// after\nif isAllZero(sig.S) {\n    return errors.New(\"malformed signature: s is zero\")\n}\nerr := ecdsa.Verify(curve, pub, hash, sig)","handlingStrategy":"validation","validationCode":"if allZero(sig.S) {\n    return errors.New(\"signature s is zero\")\n}\nreturn ecdsa.Verify(c, pub, hash, sig)","typeGuard":"func nonZeroS(sig *ecdsa.Signature) bool {\n    for _, b := range sig.S { if b != 0 { return true } }\n    return false\n}","tryCatchPattern":"if err := ecdsa.Verify(c, pub, hash, sig); err != nil {\n    return err // do not retry verification on the same inputs\n}","preventionTips":["Validate both R and S are non-zero before verifying.","Use fixed-width encoding for signature components in transit.","Reject signatures from untrusted sources that fail structural checks."],"tags":["go","crypto","fips","ecdsa","verification","signature"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}