Skip to content

Commit

Permalink
chore(deps): update btcec to the latest version (#1329)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajnavarro authored Nov 23, 2023
1 parent 899a156 commit 6d05a37
Show file tree
Hide file tree
Showing 14 changed files with 276 additions and 99 deletions.
7 changes: 4 additions & 3 deletions contribs/gnokeykc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ require (

require (
github.com/alessio/shellescape v1.4.1 // indirect
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c // indirect
github.com/btcsuite/btcd/btcutil v1.0.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/danieljoos/wincred v1.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dgraph-io/badger/v3 v3.2103.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
Expand All @@ -44,7 +45,7 @@ require (
go.opencensus.io v0.22.5 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.14.0 // indirect
Expand Down
68 changes: 61 additions & 7 deletions contribs/gnokeykc/go.sum

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ module github.com/gnolang/gno
go 1.20

require (
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c
github.com/btcsuite/btcd/btcutil v1.0.0
github.com/btcsuite/btcutil v1.0.2
github.com/btcsuite/btcd/btcutil v1.1.3
github.com/cockroachdb/apd v1.1.0
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/dgraph-io/badger/v3 v3.2103.4
github.com/fortytw2/leaktest v1.3.0
github.com/gdamore/tcell/v2 v2.6.0
Expand All @@ -32,7 +31,7 @@ require (
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c
go.etcd.io/bbolt v1.3.8
go.uber.org/multierr v1.9.0
golang.org/x/crypto v0.14.0
golang.org/x/crypto v0.15.0
golang.org/x/mod v0.14.0
golang.org/x/net v0.17.0
golang.org/x/term v0.14.0
Expand All @@ -42,6 +41,8 @@ require (
)

require (
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
Expand All @@ -67,6 +68,6 @@ require (
go.opencensus.io v0.22.5 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
69 changes: 60 additions & 9 deletions go.sum

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions misc/loop/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ require (
)

require (
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c // indirect
github.com/btcsuite/btcd/btcutil v1.0.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dgraph-io/badger/v3 v3.2103.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
Expand All @@ -39,7 +40,7 @@ require (
go.opencensus.io v0.22.5 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.14.0 // indirect
Expand Down
68 changes: 61 additions & 7 deletions misc/loop/go.sum

Large diffs are not rendered by default.

22 changes: 20 additions & 2 deletions tm2/pkg/crypto/ed25519/ed25519_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package ed25519_test

import (
"encoding/hex"
"testing"

"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/crypto/ed25519"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/crypto/ed25519"
)

func TestSignAndValidateEd25519(t *testing.T) {
Expand All @@ -28,3 +30,19 @@ func TestSignAndValidateEd25519(t *testing.T) {

assert.False(t, pubKey.VerifyBytes(msg, sig))
}

const (
privKeySecretGolden = "secret_golden"
msgGolden = "msg_golden"
signedGolden = "f9d4e6a665dfb6cd7e2fedf0d46a1725472e640a5e93d654ce4caa986e5defd23c8b3af76aa6e39c24c582f0ebee860f66254b29cf6d034ce461ae2773133703"
)

func TestSignAndVerifyGolden(t *testing.T) {
privKey := ed25519.GenPrivKeyFromSecret([]byte(privKeySecretGolden))
// pubKey := privKey.PubKey()
out, err := privKey.Sign([]byte(msgGolden))
require.NoError(t, err)

hexOut := hex.EncodeToString(out)
require.Equal(t, signedGolden, hexOut)
}
4 changes: 2 additions & 2 deletions tm2/pkg/crypto/hd/hdpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"strconv"
"strings"

"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/btcec/v2"
)

// BIP44Params wraps BIP 44 params (5 level BIP 32 path).
Expand Down Expand Up @@ -212,7 +212,7 @@ func derivePrivateKey(privKeyBytes [32]byte, chainCode [32]byte, index uint32, h
data = append([]byte{byte(0)}, privKeyBytes[:]...)
} else {
// this can't return an error:
_, ecPub := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes[:])
_, ecPub := btcec.PrivKeyFromBytes(privKeyBytes[:])
pubkeyBytes := ecPub.SerializeCompressed()
data = pubkeyBytes

Expand Down
13 changes: 7 additions & 6 deletions tm2/pkg/crypto/ledger/ledger_secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import (
"fmt"
"os"

"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"

"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand Down Expand Up @@ -166,12 +167,12 @@ func warnIfErrors(f func() error) {
}

func convertDERtoBER(signatureDER []byte) ([]byte, error) {
sigDER, err := btcec.ParseDERSignature(signatureDER[:], btcec.S256())
sigDER, err := ecdsa.ParseDERSignature(signatureDER[:])
if err != nil {
return nil, err
}
sigBER := btcec.Signature{R: sigDER.R, S: sigDER.S}
return sigBER.Serialize(), nil

return sigDER.Serialize(), nil
}

func getLedgerDevice() (LedgerSECP256K1, error) {
Expand Down Expand Up @@ -235,7 +236,7 @@ func getPubKeyUnsafe(device LedgerSECP256K1, path hd.BIP44Params) (crypto.PubKey
}

// re-serialize in the 33-byte compressed format
cmp, err := btcec.ParsePubKey(publicKey[:], btcec.S256())
cmp, err := btcec.ParsePubKey(publicKey[:])
if err != nil {
return nil, fmt.Errorf("error parsing public key: %w", err)
}
Expand All @@ -259,7 +260,7 @@ func getPubKeyAddrSafe(device LedgerSECP256K1, path hd.BIP44Params, hrp string)
}

// re-serialize in the 33-byte compressed format
cmp, err := btcec.ParsePubKey(publicKey[:], btcec.S256())
cmp, err := btcec.ParsePubKey(publicKey[:])
if err != nil {
return nil, "", fmt.Errorf("error parsing public key: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions tm2/pkg/crypto/secp256k1/secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"io"
"math/big"

secp256k1 "github.com/btcsuite/btcd/btcec/v2"
"golang.org/x/crypto/ripemd160"

secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/crypto"
)
Expand All @@ -29,7 +29,7 @@ func (privKey PrivKeySecp256k1) Bytes() []byte {
// PubKey performs the point-scalar multiplication from the privKey on the
// generator point to get the pubkey.
func (privKey PrivKeySecp256k1) PubKey() crypto.PubKey {
_, pubkeyObject := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
_, pubkeyObject := secp256k1.PrivKeyFromBytes(privKey[:])
var pubkeyBytes PubKeySecp256k1
copy(pubkeyBytes[:], pubkeyObject.SerializeCompressed())
return pubkeyBytes
Expand Down
3 changes: 1 addition & 2 deletions tm2/pkg/crypto/secp256k1/secp256k1_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (
"math/big"
"testing"

underlyingSecp256k1 "github.com/btcsuite/btcd/btcec/v2"
"github.com/stretchr/testify/require"

underlyingSecp256k1 "github.com/btcsuite/btcd/btcec"
)

func Test_genPrivKey(t *testing.T) {
Expand Down
65 changes: 30 additions & 35 deletions tm2/pkg/crypto/secp256k1/secp256k1_nocgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,25 @@
package secp256k1

import (
"math/big"

secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/decred/dcrd/dcrec/secp256k1/v4"

"github.com/gnolang/gno/tm2/pkg/crypto"
)

// used to reject malleable signatures
// see:
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)

// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
// The returned signature will be of the form R || S (in lower-S form).
func (privKey PrivKeySecp256k1) Sign(msg []byte) ([]byte, error) {
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
sig, err := priv.Sign(crypto.Sha256(msg))
priv, _ := btcec.PrivKeyFromBytes(privKey[:])

sig, err := ecdsa.SignCompact(priv, crypto.Sha256(msg), false) // ref uncompressed pubkey
if err != nil {
return nil, err
}
sigBytes := serializeSig(sig)
return sigBytes, nil

// remove compact sig recovery code byte at the beginning
return sig[1:], nil
}

// VerifyBytes verifies a signature of the form R || S.
Expand All @@ -34,37 +30,36 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sigStr []byte) bool {
if len(sigStr) != 64 {
return false
}
pub, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())

pub, err := secp256k1.ParsePubKey(pubKey[:])
if err != nil {
return false
}
// parse the signature:
signature := signatureFromBytes(sigStr)
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
// see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
if signature.S.Cmp(secp256k1halfN) > 0 {

psig, ok := signatureFromBytes(sigStr)
if !ok {
return false
}
return signature.Verify(crypto.Sha256(msg), pub)

return psig.Verify(crypto.Sha256(msg), pub)
}

// Read Signature struct from R || S. Caller needs to ensure
// that len(sigStr) == 64.
func signatureFromBytes(sigStr []byte) *secp256k1.Signature {
return &secp256k1.Signature{
R: new(big.Int).SetBytes(sigStr[:32]),
S: new(big.Int).SetBytes(sigStr[32:64]),
func signatureFromBytes(sigStr []byte) (*ecdsa.Signature, bool) {
// parse the signature:
var r, s secp256k1.ModNScalar
if r.SetByteSlice(sigStr[:32]) {
return nil, false // overflow
}
if s.SetByteSlice(sigStr[32:]) {
return nil, false
}

// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
if s.IsOverHalfOrder() {
return nil, false
}
}

// Serialize signature to R || S.
// R, S are padded to 32 bytes respectively.
func serializeSig(sig *secp256k1.Signature) []byte {
rBytes := sig.R.Bytes()
sBytes := sig.S.Bytes()
sigBytes := make([]byte, 64)
// 0 pad the byte arrays from the left if they aren't big enough.
copy(sigBytes[32-len(rBytes):32], rBytes)
copy(sigBytes[64-len(sBytes):64], sBytes)
return sigBytes
return ecdsa.NewSignature(&r, &s), true
}
27 changes: 15 additions & 12 deletions tm2/pkg/crypto/secp256k1/secp256k1_nocgo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package secp256k1
import (
"testing"

secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/stretchr/testify/require"
)

Expand All @@ -20,21 +19,25 @@ func TestSignatureVerificationAndRejectUpperS(t *testing.T) {
priv := GenPrivKey()
sigStr, err := priv.Sign(msg)
require.NoError(t, err)
sig := signatureFromBytes(sigStr)
require.False(t, sig.S.Cmp(secp256k1halfN) > 0)
_, ok := signatureFromBytes(sigStr)
require.True(t, ok)

pub := priv.PubKey()
require.True(t, pub.VerifyBytes(msg, sigStr))
}
}

func BenchmarkVerify(b *testing.B) {
priv := GenPrivKey()
msg := []byte("We have lingered long enough on the shores of the cosmic ocean.")
sigStr, err := priv.Sign(msg)
require.NoError(b, err)

// malleate:
sig.S.Sub(secp256k1.S256().CurveParams.N, sig.S)
require.True(t, sig.S.Cmp(secp256k1halfN) > 0)
malSigStr := serializeSig(sig)
pub := priv.PubKey()
b.ResetTimer()

require.False(t, pub.VerifyBytes(msg, malSigStr),
"VerifyBytes incorrect with malleated & invalid S. sig=%v, key=%v",
sig,
priv,
)
for i := 0; i < b.N; i++ {
ok := pub.VerifyBytes(msg, sigStr)
require.True(b, ok)
}
}
7 changes: 3 additions & 4 deletions tm2/pkg/crypto/secp256k1/secp256k1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"math/big"
"testing"

"github.com/btcsuite/btcutil/base58"
underlyingSecp256k1 "github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil/base58"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/crypto/secp256k1"

underlyingSecp256k1 "github.com/btcsuite/btcd/btcec"
)

type keyData struct {
Expand Down Expand Up @@ -82,7 +81,7 @@ func TestSecp256k1LoadPrivkeyAndSerializeIsIdentity(t *testing.T) {

// This function creates a private and public key in the underlying libraries format.
// The private key is basically calling new(big.Int).SetBytes(pk), which removes leading zero bytes
priv, _ := underlyingSecp256k1.PrivKeyFromBytes(underlyingSecp256k1.S256(), privKeyBytes[:])
priv, _ := underlyingSecp256k1.PrivKeyFromBytes(privKeyBytes[:])
// this takes the bytes returned by `(big int).Bytes()`, and if the length is less than 32 bytes,
// pads the bytes from the left with zero bytes. Therefore these two functions composed
// result in the identity function on privKeyBytes, hence the following equality check
Expand Down

0 comments on commit 6d05a37

Please sign in to comment.