fix: cgosecp256k1 verification (backport #11298) (#11360)

* fix: cgosecp256k1 verification (#11298)

## Description

Closes: #10747

- update secp256k1 cgo fork,
- debug verify bytes

```
benchmark                     old ns/op     new ns/op     delta
BenchmarkKeyGeneration-10     407           413           +1.35%
BenchmarkSigning-10           95099         36754         -61.35%
BenchmarkVerification-10      215551        48053         -77.71%

benchmark                     old allocs     new allocs     delta
BenchmarkKeyGeneration-10     2              2              +0.00%
BenchmarkSigning-10           83             4              -95.18%
BenchmarkVerification-10      74             1              -98.65%

benchmark                     old bytes     new bytes     delta
BenchmarkKeyGeneration-10     96            96            +0.00%
BenchmarkSigning-10           5283          196           -96.29%
BenchmarkVerification-10      3537          32            -99.10%
```

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)

(cherry picked from commit 361c837e52)

# Conflicts:
#	CHANGELOG.md
#	crypto/keys/secp256k1/internal/secp256k1/README.md

* fix conflicts

Co-authored-by: Marko <marbar3778@yahoo.com>
This commit is contained in:
mergify[bot] 2022-03-11 12:09:50 +01:00 committed by GitHub
parent b073f35f82
commit a4644a3797
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 463 additions and 90 deletions

View File

@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (store) [\#11177](https://github.com/cosmos/cosmos-sdk/pull/11177) Update the prune `everything` strategy to store the last two heights.
* (store) [\#11117](https://github.com/cosmos/cosmos-sdk/pull/11117) Fix data race in store trace component
* (x/authz) [\#11252](https://github.com/cosmos/cosmos-sdk/pull/11252) Allow insufficient funds error for authz simulation
* (crypto) [\#11298](https://github.com/cosmos/cosmos-sdk/pull/11298) Fix cgo secp signature verification and update libscep256k1 library.
### Improvements

View File

@ -46,6 +46,10 @@ ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
build_tags += gcc
endif
ifeq (secp,$(findstring secp,$(COSMOS_BUILD_OPTIONS)))
build_tags += libsecp256k1_sdk
endif
whitespace :=
whitespace += $(whitespace)
comma := ,

View File

@ -1,3 +1,5 @@
This package is copied from https://github.com/ethereum/go-ethereum/tree/729bf365b5f17325be9107b63b233da54100eec6/crypto/secp256k1
# secp256k1
Unlike the rest of go-ethereum it is MIT licensed so compatible with our Apache2.0 license. We opt to copy in here rather than depend on go-ethereum to avoid issues with vendoring of the GPL parts of that repository by downstream.
This package is copied from https://github.com/ethereum/go-ethereum/tree/8fddf27a989e246659fd018ea9be37b2b4f55326/crypto/secp256k1
Unlike the rest of go-ethereum it is [3-clause BSD](https://opensource.org/licenses/BSD-3-Clause) licensed so compatible with our Apache2.0 license. We opt to copy in here rather than depend on go-ethereum to avoid issues with vendoring of the GPL parts of that repository by downstream.

View File

@ -30,23 +30,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// nolint:gocritic
package secp256k1
import (
"crypto/elliptic"
"math/big"
"unsafe"
)
/*
#include "libsecp256k1/include/secp256k1.h"
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx,
const unsigned char *point,
const unsigned char *scalar);
*/
import "C"
const (
// number of bits in a big.Word
wordBits = 32 << (uint64(^big.Word(0)) >> 63)
@ -119,6 +109,10 @@ func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
// affineFromJacobian reverses the Jacobian transform. See the comment at the
// top of the file.
func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
if z.Sign() == 0 {
return new(big.Int), new(big.Int)
}
zinv := new(big.Int).ModInverse(z, BitCurve.P)
zinvsq := new(big.Int).Mul(zinv, zinv)
@ -132,7 +126,18 @@ func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.
// Add returns the sum of (x1,y1) and (x2,y2)
func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
// If one point is at infinity, return the other point.
// Adding the point at infinity to any point will preserve the other point.
if x1.Sign() == 0 && y1.Sign() == 0 {
return x2, y2
}
if x2.Sign() == 0 && y2.Sign() == 0 {
return x1, y1
}
z := new(big.Int).SetInt64(1)
if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 {
return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z))
}
return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
}
@ -241,41 +246,6 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int,
return x3, y3, z3
}
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
// Ensure scalar is exactly 32 bytes. We pad always, even if
// scalar is 32 bytes long, to avoid a timing side channel.
if len(scalar) > 32 {
panic("can't handle scalars > 256 bits")
}
// NOTE: potential timing issue
padded := make([]byte, 32)
copy(padded[32-len(scalar):], scalar)
scalar = padded
// Do the multiplication in C, updating point.
point := make([]byte, 64)
readBits(Bx, point[:32])
readBits(By, point[32:])
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
// Unpack the result and clear temporaries.
x := new(big.Int).SetBytes(point[:32])
y := new(big.Int).SetBytes(point[32:])
for i := range point {
point[i] = 0
}
for i := range padded {
scalar[i] = 0
}
if res != 1 {
return nil, nil
}
return x, y
}
// ScalarBaseMult returns k*G, where G is the base point of the group and k is
// an integer in big-endian form.
func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {

View File

@ -0,0 +1,21 @@
//go:build dummy
// +build dummy
// This file is part of a workaround for `go mod vendor` which won't vendor
// C files if there's no Go file in the same directory.
// This would prevent the crypto/secp256k1/libsecp256k1/include/secp256k1.h file to be vendored.
//
// This Go file imports the c directory where there is another dummy.go file which
// is the second part of this workaround.
//
// These two files combined make it so `go mod vendor` behaves correctly.
//
// See this issue for reference: https://github.com/golang/go/issues/26366
package secp256k1
import (
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/include"
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src"
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src/modules/recovery"
)

View File

@ -8,7 +8,6 @@ Optimized C library for EC operations on curve secp256k1.
This library is a work in progress and is being used to research best practices. Use at your own risk.
Features:
* secp256k1 ECDSA signing/verification and key generation.
* Adding/multiplying private/public keys.
* Serialization/parsing of private keys, public keys, signatures.
@ -55,8 +54,8 @@ Build steps
libsecp256k1 is built using autotools:
./autogen.sh
./configure
make
./tests
sudo make install # optional
$ ./autogen.sh
$ ./configure
$ make
$ ./tests
$ sudo make install # optional

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package contrib

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package libsecp256k1

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package include

View File

@ -11,7 +11,7 @@ Note:
- To avoid unnecessary loads and make use of available registers, two
'passes' have every time been interleaved, with the odd passes accumulating c' and d'
which will be added to c and d respectively in the the even passes
which will be added to c and d respectively in the even passes
*/
@ -23,7 +23,7 @@ Note:
.eabi_attribute 10, 0 @ Tag_FP_arch = none
.eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte
.eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed
.eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6
.text

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package src

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package module

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package ecdh

View File

@ -0,0 +1,7 @@
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package recovery

View File

@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
package secp256k1
import "C"

View File

@ -0,0 +1,57 @@
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
package secp256k1
import (
"math/big"
"unsafe"
)
/*
#include "libsecp256k1/include/secp256k1.h"
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
*/
import "C"
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
// Ensure scalar is exactly 32 bytes. We pad always, even if
// scalar is 32 bytes long, to avoid a timing side channel.
if len(scalar) > 32 {
panic("can't handle scalars > 256 bits")
}
// NOTE: potential timing issue
padded := make([]byte, 32)
copy(padded[32-len(scalar):], scalar)
scalar = padded
// Do the multiplication in C, updating point.
point := make([]byte, 64)
readBits(Bx, point[:32])
readBits(By, point[32:])
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
// Unpack the result and clear temporaries.
x := new(big.Int).SetBytes(point[:32])
y := new(big.Int).SetBytes(point[32:])
for i := range point {
point[i] = 0
}
for i := range padded {
scalar[i] = 0
}
if res != 1 {
return nil, nil
}
return x, y
}

View File

@ -0,0 +1,14 @@
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build gofuzz || !cgo
// +build gofuzz !cgo
package secp256k1
import "math/big"
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
panic("ScalarMult is not available when secp256k1 is built without cgo")
}

View File

@ -2,16 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
// Package secp256k1 wraps the bitcoin secp256k1 C library.
package secp256k1
/*
#cgo CFLAGS: -I./libsecp256k1
#cgo CFLAGS: -I./libsecp256k1/src/
#ifdef __SIZEOF_INT128__
# define HAVE___INT128
# define USE_FIELD_5X52
# define USE_SCALAR_4X64
#else
# define USE_FIELD_10X26
# define USE_SCALAR_8X32
#endif
#define USE_ENDOMORPHISM
#define USE_NUM_NONE
#define USE_FIELD_10X26
#define USE_FIELD_INV_BUILTIN
#define USE_SCALAR_8X32
#define USE_SCALAR_INV_BUILTIN
#define NDEBUG
#include "./libsecp256k1/src/secp256k1.c"

View File

@ -0,0 +1,238 @@
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package secp256k1
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/hex"
"io"
"testing"
)
const TestCount = 1000
func generateKeyPair() (pubkey, privkey []byte) {
key, err := ecdsa.GenerateKey(S256(), rand.Reader)
if err != nil {
panic(err)
}
pubkey = elliptic.Marshal(S256(), key.X, key.Y)
privkey = make([]byte, 32)
blob := key.D.Bytes()
copy(privkey[32-len(blob):], blob)
return pubkey, privkey
}
func csprngEntropy(n int) []byte {
buf := make([]byte, n)
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
panic("reading from crypto/rand failed: " + err.Error())
}
return buf
}
func randSig() []byte {
sig := csprngEntropy(65)
sig[32] &= 0x70
sig[64] %= 4
return sig
}
// tests for malleability
// highest bit of signature ECDSA s value must be 0, in the 33th byte
func compactSigCheck(t *testing.T, sig []byte) {
var b = int(sig[32])
if b < 0 {
t.Errorf("highest bit is negative: %d", b)
}
if ((b >> 7) == 1) != ((b & 0x80) == 0x80) {
t.Errorf("highest bit: %d bit >> 7: %d", b, b>>7)
}
if (b & 0x80) == 0x80 {
t.Errorf("highest bit: %d bit & 0x80: %d", b, b&0x80)
}
}
func TestSignatureValidity(t *testing.T) {
pubkey, seckey := generateKeyPair()
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Errorf("signature error: %s", err)
}
compactSigCheck(t, sig)
if len(pubkey) != 65 {
t.Errorf("pubkey length mismatch: want: 65 have: %d", len(pubkey))
}
if len(seckey) != 32 {
t.Errorf("seckey length mismatch: want: 32 have: %d", len(seckey))
}
if len(sig) != 65 {
t.Errorf("sig length mismatch: want: 65 have: %d", len(sig))
}
recid := int(sig[64])
if recid > 4 || recid < 0 {
t.Errorf("sig recid mismatch: want: within 0 to 4 have: %d", int(sig[64]))
}
}
func TestInvalidRecoveryID(t *testing.T) {
_, seckey := generateKeyPair()
msg := csprngEntropy(32)
sig, _ := Sign(msg, seckey)
sig[64] = 99
_, err := RecoverPubkey(msg, sig)
if err != ErrInvalidRecoveryID {
t.Fatalf("got %q, want %q", err, ErrInvalidRecoveryID)
}
}
func TestSignAndRecover(t *testing.T) {
pubkey1, seckey := generateKeyPair()
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Errorf("signature error: %s", err)
}
pubkey2, err := RecoverPubkey(msg, sig)
if err != nil {
t.Errorf("recover error: %s", err)
}
if !bytes.Equal(pubkey1, pubkey2) {
t.Errorf("pubkey mismatch: want: %x have: %x", pubkey1, pubkey2)
}
}
func TestSignDeterministic(t *testing.T) {
_, seckey := generateKeyPair()
msg := make([]byte, 32)
copy(msg, "hi there")
sig1, err := Sign(msg, seckey)
if err != nil {
t.Fatal(err)
}
sig2, err := Sign(msg, seckey)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(sig1, sig2) {
t.Fatal("signatures not equal")
}
}
func TestRandomMessagesWithSameKey(t *testing.T) {
pubkey, seckey := generateKeyPair()
keys := func() ([]byte, []byte) {
return pubkey, seckey
}
signAndRecoverWithRandomMessages(t, keys)
}
func TestRandomMessagesWithRandomKeys(t *testing.T) {
keys := func() ([]byte, []byte) {
pubkey, seckey := generateKeyPair()
return pubkey, seckey
}
signAndRecoverWithRandomMessages(t, keys)
}
func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) {
for i := 0; i < TestCount; i++ {
pubkey1, seckey := keys()
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Fatalf("signature error: %s", err)
}
if sig == nil {
t.Fatal("signature is nil")
}
compactSigCheck(t, sig)
// TODO: why do we flip around the recovery id?
sig[len(sig)-1] %= 4
pubkey2, err := RecoverPubkey(msg, sig)
if err != nil {
t.Fatalf("recover error: %s", err)
}
if pubkey2 == nil {
t.Error("pubkey is nil")
}
if !bytes.Equal(pubkey1, pubkey2) {
t.Fatalf("pubkey mismatch: want: %x have: %x", pubkey1, pubkey2)
}
}
}
func TestRecoveryOfRandomSignature(t *testing.T) {
pubkey1, _ := generateKeyPair()
msg := csprngEntropy(32)
for i := 0; i < TestCount; i++ {
// recovery can sometimes work, but if so should always give wrong pubkey
pubkey2, _ := RecoverPubkey(msg, randSig())
if bytes.Equal(pubkey1, pubkey2) {
t.Fatalf("iteration: %d: pubkey mismatch: do NOT want %x: ", i, pubkey2)
}
}
}
func TestRandomMessagesAgainstValidSig(t *testing.T) {
pubkey1, seckey := generateKeyPair()
msg := csprngEntropy(32)
sig, _ := Sign(msg, seckey)
for i := 0; i < TestCount; i++ {
msg = csprngEntropy(32)
pubkey2, _ := RecoverPubkey(msg, sig)
// recovery can sometimes work, but if so should always give wrong pubkey
if bytes.Equal(pubkey1, pubkey2) {
t.Fatalf("iteration: %d: pubkey mismatch: do NOT want %x: ", i, pubkey2)
}
}
}
// Useful when the underlying libsecp256k1 API changes to quickly
// check only recover function without use of signature function
func TestRecoverSanity(t *testing.T) {
msg, _ := hex.DecodeString("ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008")
sig, _ := hex.DecodeString("90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc9301")
pubkey1, _ := hex.DecodeString("04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652")
pubkey2, err := RecoverPubkey(msg, sig)
if err != nil {
t.Fatalf("recover error: %s", err)
}
if !bytes.Equal(pubkey1, pubkey2) {
t.Errorf("pubkey mismatch: want: %x have: %x", pubkey1, pubkey2)
}
}
func BenchmarkSign(b *testing.B) {
_, seckey := generateKeyPair()
msg := csprngEntropy(32)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sign(msg, seckey)
}
}
func BenchmarkRecover(b *testing.B) {
msg := csprngEntropy(32)
_, seckey := generateKeyPair()
sig, _ := Sign(msg, seckey)
b.ResetTimer()
for i := 0; i < b.N; i++ {
RecoverPubkey(msg, sig)
}
}

View File

@ -1,4 +1,5 @@
// +build libsecp256k1
//go:build libsecp256k1_sdk
// +build libsecp256k1_sdk
package secp256k1
@ -21,6 +22,6 @@ func (privKey *PrivKey) Sign(msg []byte) ([]byte, error) {
// VerifySignature validates the signature.
// The msg will be hashed prior to signature verification.
func (pubKey *PrivKey) VerifySignature(msg []byte, sig []byte) bool {
return secp256k1.VerifySignature(pubKey.Key, crypto.Sha256(msg), sig)
func (pubKey *PubKey) VerifySignature(msg []byte, sigStr []byte) bool {
return secp256k1.VerifySignature(pubKey.Bytes(), crypto.Sha256(msg), sigStr)
}

View File

@ -1,4 +1,5 @@
// +build libsecp256k1
//go:build libsecp256k1_sdk
// +build libsecp256k1_sdk
package secp256k1
@ -20,7 +21,7 @@ func TestPrivKeySecp256k1SignVerify(t *testing.T) {
wantVerifyPasses bool
}{
{name: "valid sign-verify round", privKey: priv, wantSignErr: false, wantVerifyPasses: true},
{name: "invalid private key", privKey: &*PrivKey{Key: [32]byte{}}, wantSignErr: true, wantVerifyPasses: false},
{name: "invalid private key", privKey: &PrivKey{Key: []byte{}}, wantSignErr: true, wantVerifyPasses: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -34,7 +35,7 @@ func TestPrivKeySecp256k1SignVerify(t *testing.T) {
require.NotNil(t, got)
pub := tt.privKey.PubKey()
assert.Equal(t, tt.wantVerifyPasses, pub.VerifyBytes(msg, got))
assert.Equal(t, tt.wantVerifyPasses, pub.VerifySignature(msg, got))
})
}
}

View File

@ -1,5 +1,5 @@
//go:build !libsecp256k1
// +build !libsecp256k1
//go:build !libsecp256k1_sdk
// +build !libsecp256k1_sdk
package secp256k1

View File

@ -1,4 +1,5 @@
// +build !libsecp256k1
//go:build !libsecp256k1_sdk
// +build !libsecp256k1_sdk
package secp256k1