Skip to content

fix: secp256k1 coordinate validation and libsecp256k1 update#66

Merged
eomti-wm merged 5 commits intodevfrom
fix/secp256k1-curve-validation
Mar 31, 2026
Merged

fix: secp256k1 coordinate validation and libsecp256k1 update#66
eomti-wm merged 5 commits intodevfrom
fix/secp256k1-curve-validation

Conversation

@eomti-wm
Copy link
Copy Markdown
Contributor

Summary

This PR hardens the secp256k1 elliptic curve implementation against invalid public key inputs. The core fix adds coordinate range checks before curve operations — points with coordinates ≥ P (the field prime) are now rejected as invalid, preventing potential undefined behavior in the underlying C library.

To apply this fix cleanly, the upstream libsecp256k1 C library was updated to a newer version and related refactoring commits were ported.

Upstream References

Reference Description
PR #29889 refactor: change receiver variable name to lowercase
PR #31100 fix: add IsOnCurve check in UnmarshalPubkey
PR #31242 feat: update libsecp256k1
PR #32430 refactor: use ReadBits from common/math
commit 9b78f45 fix: coordinate check

Security Fixes

1. Coordinate range check in IsOnCurve (curve.go)
Points with x ≥ P or y ≥ P are now rejected before the curve equation is evaluated. Previously, such coordinates would wrap around modulo P and could produce a false positive.

2. Field element validation in scalar multiplication (ext.h)
secp256k1_fe_set_b32_limit() return value is now checked. If the input point coordinates exceed the field prime, the operation returns early with an error instead of proceeding with invalid values.

3. IsOnCurve override in btCurve (signature_nocgo.go)
The pure-Go fallback path (btCurve) also gains an explicit coordinate range check, ensuring the no-cgo build has the same validation as the cgo path.

4. UnmarshalPubkey curve validation (crypto.go)
S256().IsOnCurve(x, y) is now called after parsing the public key bytes, so any key with coordinates not on the curve is rejected at deserialization time.

Other Changes

  • Updated embedded libsecp256k1 C library to a newer upstream version.
  • Receiver variable renamed to lowercase for Go convention consistency.
  • math.ReadBits from common/math used instead of manual bit extraction.

suiyuan1314 and others added 5 commits March 24, 2026 11:28
Updates the libsecp256k1 dependency to commit:
c0d9480fbbf8eccbd4be23ed27f6f2af6f3b211e

PR:
```
BenchmarkSign-24    	   57756	     21214 ns/op	     164 B/op	       3 allocs/op
BenchmarkRecover-24    	   37156	     33044 ns/op	      80 B/op	       1 allocs/op
BenchmarkEcrecoverSignature-24    	   36889	     32935 ns/op	      80 B/op	       1 allocs/op
BenchmarkVerifySignature-24    	   41163	     29207 ns/op	       0 B/op	       0 allocs/op
BenchmarkDecompressPubkey-24    	  318624	      4062 ns/op	     304 B/op	       6 allocs/op
```

Master:
```
BenchmarkSign-24    	   34509	     35330 ns/op	     164 B/op	       3 allocs/op
BenchmarkRecover-24    	   25418	     47725 ns/op	      80 B/op	       1 allocs/op
BenchmarkEcrecoverSignature-24    	   25735	     47591 ns/op	      80 B/op	       1 allocs/op
BenchmarkVerifySignature-24    	   29108	     41097 ns/op	       0 B/op	       0 allocs/op
BenchmarkDecompressPubkey-24    	  294747	      4143 ns/op	     304 B/op	       6 allocs/op
```

Performance seems to be improved significantly:
```
Sign-24      34.86µ ± 3%   21.66µ ± 2%  -37.86% (p=0.000 n=10)
Recover-24   46.14µ ± 3%   33.24µ ± 2%  -27.95% (p=0.000 n=10)
```
@eomti-wm eomti-wm self-assigned this Mar 24, 2026
@eomti-wm eomti-wm added the bug Something isn't working label Mar 24, 2026
Copy link
Copy Markdown
Member

@0xmhha 0xmhha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Collaborator

@hominlee-wemade hominlee-wemade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

@colinkim colinkim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@eomti-wm eomti-wm merged commit f867ab6 into dev Mar 31, 2026
3 checks passed
@hominlee-wemade hominlee-wemade deleted the fix/secp256k1-curve-validation branch April 8, 2026 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants