Skip to content

Commit 30ce173

Browse files
authored
crypto: use decred secp256k1 directly (#30595)
Use `github.com/decred/dcrd/dcrec/secp256k1/v4` directly rather than `github.com/btcsuite/btcd/btcec/v2` which is just a wrapper around the underlying decred library. Inspired by cosmos/cosmos-sdk#15018 `github.com/btcsuite/btcd/btcec/v2` has a very annoying breaking change when upgrading from `v2.3.3` to `v2.3.4`. The easiest way to workaround this is to just remove the wrapper. Would be very nice if you could backport this to the release branches. References: - btcsuite/btcd#2221 - cometbft/cometbft#4294 - cometbft/cometbft#3728 - zeta-chain/node#2934
1 parent 4b9c782 commit 30ce173

File tree

4 files changed

+21
-26
lines changed

4 files changed

+21
-26
lines changed

crypto/signature_nocgo.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import (
2525
"fmt"
2626
"math/big"
2727

28-
"github.com/btcsuite/btcd/btcec/v2"
29-
btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa"
28+
"github.com/decred/dcrd/dcrec/secp256k1/v4"
29+
decred_ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
3030
)
3131

3232
// Ecrecover returns the uncompressed public key that created the given signature.
@@ -39,16 +39,16 @@ func Ecrecover(hash, sig []byte) ([]byte, error) {
3939
return bytes, err
4040
}
4141

42-
func sigToPub(hash, sig []byte) (*btcec.PublicKey, error) {
42+
func sigToPub(hash, sig []byte) (*secp256k1.PublicKey, error) {
4343
if len(sig) != SignatureLength {
4444
return nil, errors.New("invalid signature")
4545
}
46-
// Convert to btcec input format with 'recovery id' v at the beginning.
46+
// Convert to secp256k1 input format with 'recovery id' v at the beginning.
4747
btcsig := make([]byte, SignatureLength)
4848
btcsig[0] = sig[RecoveryIDOffset] + 27
4949
copy(btcsig[1:], sig)
5050

51-
pub, _, err := btc_ecdsa.RecoverCompact(btcsig, hash)
51+
pub, _, err := decred_ecdsa.RecoverCompact(btcsig, hash)
5252
return pub, err
5353
}
5454

@@ -82,13 +82,13 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) {
8282
if prv.Curve != S256() {
8383
return nil, errors.New("private key curve is not secp256k1")
8484
}
85-
// ecdsa.PrivateKey -> btcec.PrivateKey
86-
var priv btcec.PrivateKey
85+
// ecdsa.PrivateKey -> secp256k1.PrivateKey
86+
var priv secp256k1.PrivateKey
8787
if overflow := priv.Key.SetByteSlice(prv.D.Bytes()); overflow || priv.Key.IsZero() {
8888
return nil, errors.New("invalid private key")
8989
}
9090
defer priv.Zero()
91-
sig := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey
91+
sig := decred_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey
9292
// Convert to Ethereum signature format with 'recovery id' v at the end.
9393
v := sig[0] - 27
9494
copy(sig, sig[1:])
@@ -103,19 +103,19 @@ func VerifySignature(pubkey, hash, signature []byte) bool {
103103
if len(signature) != 64 {
104104
return false
105105
}
106-
var r, s btcec.ModNScalar
106+
var r, s secp256k1.ModNScalar
107107
if r.SetByteSlice(signature[:32]) {
108108
return false // overflow
109109
}
110110
if s.SetByteSlice(signature[32:]) {
111111
return false
112112
}
113-
sig := btc_ecdsa.NewSignature(&r, &s)
114-
key, err := btcec.ParsePubKey(pubkey)
113+
sig := decred_ecdsa.NewSignature(&r, &s)
114+
key, err := secp256k1.ParsePubKey(pubkey)
115115
if err != nil {
116116
return false
117117
}
118-
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
118+
// Reject malleable signatures. libsecp256k1 does this check but decred doesn't.
119119
if s.IsOverHalfOrder() {
120120
return false
121121
}
@@ -127,7 +127,7 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
127127
if len(pubkey) != 33 {
128128
return nil, errors.New("invalid compressed public key length")
129129
}
130-
key, err := btcec.ParsePubKey(pubkey)
130+
key, err := secp256k1.ParsePubKey(pubkey)
131131
if err != nil {
132132
return nil, err
133133
}
@@ -148,20 +148,20 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
148148
// when constructing a PrivateKey.
149149
func CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
150150
// NOTE: the coordinates may be validated with
151-
// btcec.ParsePubKey(FromECDSAPub(pubkey))
152-
var x, y btcec.FieldVal
151+
// secp256k1.ParsePubKey(FromECDSAPub(pubkey))
152+
var x, y secp256k1.FieldVal
153153
x.SetByteSlice(pubkey.X.Bytes())
154154
y.SetByteSlice(pubkey.Y.Bytes())
155-
return btcec.NewPublicKey(&x, &y).SerializeCompressed()
155+
return secp256k1.NewPublicKey(&x, &y).SerializeCompressed()
156156
}
157157

158158
// S256 returns an instance of the secp256k1 curve.
159159
func S256() EllipticCurve {
160-
return btCurve{btcec.S256()}
160+
return btCurve{secp256k1.S256()}
161161
}
162162

163163
type btCurve struct {
164-
*btcec.KoblitzCurve
164+
*secp256k1.KoblitzCurve
165165
}
166166

167167
// Marshal converts a point given as (x, y) into a byte slice.

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ require (
1212
github.com/aws/aws-sdk-go-v2/config v1.18.45
1313
github.com/aws/aws-sdk-go-v2/credentials v1.13.43
1414
github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2
15-
github.com/btcsuite/btcd/btcec/v2 v2.3.4
1615
github.com/cespare/cp v0.1.0
1716
github.com/cloudflare/cloudflare-go v0.79.0
1817
github.com/cockroachdb/pebble v1.1.2
@@ -21,6 +20,7 @@ require (
2120
github.com/crate-crypto/go-kzg-4844 v1.0.0
2221
github.com/davecgh/go-spew v1.1.1
2322
github.com/deckarep/golang-set/v2 v2.6.0
23+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
2424
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0
2525
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3
2626
github.com/ethereum/c-kzg-4844 v1.0.0
@@ -102,7 +102,6 @@ require (
102102
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
103103
github.com/consensys/bavard v0.1.13 // indirect
104104
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
105-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
106105
github.com/deepmap/oapi-codegen v1.6.0 // indirect
107106
github.com/dlclark/regexp2 v1.7.0 // indirect
108107
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect

go.sum

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
9292
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
9393
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
9494
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
95-
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
96-
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
97-
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
98-
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
9995
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
10096
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
10197
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=

tests/fuzzers/secp256k1/secp_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"fmt"
2121
"testing"
2222

23-
"github.com/btcsuite/btcd/btcec/v2"
23+
dcred_secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
2424
"github.com/ethereum/go-ethereum/crypto/secp256k1"
2525
)
2626

@@ -38,7 +38,7 @@ func Fuzz(f *testing.F) {
3838
func fuzz(dataP1, dataP2 []byte) {
3939
var (
4040
curveA = secp256k1.S256()
41-
curveB = btcec.S256()
41+
curveB = dcred_secp256k1.S256()
4242
)
4343
// first point
4444
x1, y1 := curveB.ScalarBaseMult(dataP1)

0 commit comments

Comments
 (0)