mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
btcec/v2: create new ecdsa package
In this commit, we create a new package to house the ECDSA-specific logic in the new `btcec/v2` pacakge. Thsi c hange is meant to mirror the structure of the `dcrec` package, as we'll soon slot in our own custom BIP-340 implementation.
This commit is contained in:
parent
a27738721a
commit
eb61742c5d
@ -164,35 +164,6 @@ func hexToModNScalar(s string) *ModNScalar {
|
||||
return &scalar
|
||||
}
|
||||
|
||||
// BenchmarkSigVerify benchmarks how long it takes the secp256k1 curve to
|
||||
// verify signatures.
|
||||
func BenchmarkSigVerify(b *testing.B) {
|
||||
b.StopTimer()
|
||||
// Randomly generated keypair.
|
||||
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
|
||||
pubKey := NewPublicKey(
|
||||
hexToFieldVal("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab"),
|
||||
hexToFieldVal("ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52"),
|
||||
)
|
||||
|
||||
// Double sha256 of []byte{0x01, 0x02, 0x03, 0x04}
|
||||
msgHash := fromHex("8de472e2399610baaa7f84840547cd409434e31f5d3bd71e4d947f283874f9c0")
|
||||
sig := NewSignature(
|
||||
hexToModNScalar("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c"),
|
||||
hexToModNScalar("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f"),
|
||||
)
|
||||
|
||||
if !sig.Verify(msgHash.Bytes(), pubKey) {
|
||||
b.Errorf("Signature failed to verify")
|
||||
return
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
sig.Verify(msgHash.Bytes(), pubKey)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkFieldNormalize benchmarks how long it takes the internal field
|
||||
// to perform normalization (which includes modular reduction).
|
||||
func BenchmarkFieldNormalize(b *testing.B) {
|
||||
|
@ -851,27 +851,6 @@ func TestKeyGeneration(t *testing.T) {
|
||||
testKeyGeneration(t, S256(), "S256")
|
||||
}
|
||||
|
||||
func testSignAndVerify(t *testing.T, c *KoblitzCurve, tag string) {
|
||||
priv, _ := NewPrivateKey()
|
||||
pub := priv.PubKey()
|
||||
|
||||
hashed := []byte("testing")
|
||||
sig := Sign(priv, hashed)
|
||||
|
||||
if !sig.Verify(hashed, pub) {
|
||||
t.Errorf("%s: Verify failed", tag)
|
||||
}
|
||||
|
||||
hashed[0] ^= 0xff
|
||||
if sig.Verify(hashed, pub) {
|
||||
t.Errorf("%s: Verify always works!", tag)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignAndVerify(t *testing.T) {
|
||||
testSignAndVerify(t, S256(), "S256")
|
||||
}
|
||||
|
||||
// checkNAFEncoding returns an error if the provided positive and negative
|
||||
// portions of an overall NAF encoding do not adhere to the requirements or they
|
||||
// do not sum back to the provided original value.
|
||||
|
210
btcec/ecdsa/bench_test.go
Normal file
210
btcec/ecdsa/bench_test.go
Normal file
@ -0,0 +1,210 @@
|
||||
// Copyright 2013-2016 The btcsuite developers
|
||||
// Copyright (c) 2015-2021 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
)
|
||||
|
||||
// hexToBytes converts the passed hex string into bytes and will panic if there
|
||||
// is an error. This is only provided for the hard-coded constants so errors in
|
||||
// the source code can be detected. It will only (and must only) be called with
|
||||
// hard-coded values.
|
||||
func hexToBytes(s string) []byte {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// hexToModNScalar converts the passed hex string into a ModNScalar and will
|
||||
// panic if there is an error. This is only provided for the hard-coded
|
||||
// constants so errors in the source code can be detected. It will only (and
|
||||
// must only) be called with hard-coded values.
|
||||
func hexToModNScalar(s string) *btcec.ModNScalar {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
var scalar btcec.ModNScalar
|
||||
if overflow := scalar.SetByteSlice(b); overflow {
|
||||
panic("hex in source file overflows mod N scalar: " + s)
|
||||
}
|
||||
return &scalar
|
||||
}
|
||||
|
||||
// hexToFieldVal converts the passed hex string into a FieldVal and will panic
|
||||
// if there is an error. This is only provided for the hard-coded constants so
|
||||
// errors in the source code can be detected. It will only (and must only) be
|
||||
// called with hard-coded values.
|
||||
func hexToFieldVal(s string) *btcec.FieldVal {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
var f btcec.FieldVal
|
||||
if overflow := f.SetByteSlice(b); overflow {
|
||||
panic("hex in source file overflows mod P: " + s)
|
||||
}
|
||||
return &f
|
||||
}
|
||||
|
||||
// fromHex converts the passed hex string into a big integer pointer and will
|
||||
// panic is there is an error. This is only provided for the hard-coded
|
||||
// constants so errors in the source code can bet detected. It will only (and
|
||||
// must only) be called for initialization purposes.
|
||||
func fromHex(s string) *big.Int {
|
||||
if s == "" {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
r, ok := new(big.Int).SetString(s, 16)
|
||||
if !ok {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// BenchmarkSigVerify benchmarks how long it takes the secp256k1 curve to
|
||||
// verify signatures.
|
||||
func BenchmarkSigVerify(b *testing.B) {
|
||||
b.StopTimer()
|
||||
// Randomly generated keypair.
|
||||
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
|
||||
pubKey := btcec.NewPublicKey(
|
||||
hexToFieldVal("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab"),
|
||||
hexToFieldVal("ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52"),
|
||||
)
|
||||
|
||||
// Double sha256 of []byte{0x01, 0x02, 0x03, 0x04}
|
||||
msgHash := fromHex("8de472e2399610baaa7f84840547cd409434e31f5d3bd71e4d947f283874f9c0")
|
||||
sig := NewSignature(
|
||||
hexToModNScalar("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c"),
|
||||
hexToModNScalar("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f"),
|
||||
)
|
||||
|
||||
if !sig.Verify(msgHash.Bytes(), pubKey) {
|
||||
b.Errorf("Signature failed to verify")
|
||||
return
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
sig.Verify(msgHash.Bytes(), pubKey)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkSign benchmarks how long it takes to sign a message.
|
||||
func BenchmarkSign(b *testing.B) {
|
||||
// Randomly generated keypair.
|
||||
d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
|
||||
privKey := secp256k1.NewPrivateKey(d)
|
||||
|
||||
// blake256 of []byte{0x01, 0x02, 0x03, 0x04}.
|
||||
msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sign(privKey, msgHash)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkSigSerialize benchmarks how long it takes to serialize a typical
|
||||
// signature with the strict DER encoding.
|
||||
func BenchmarkSigSerialize(b *testing.B) {
|
||||
// Randomly generated keypair.
|
||||
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
|
||||
// Signature for double sha256 of []byte{0x01, 0x02, 0x03, 0x04}.
|
||||
sig := NewSignature(
|
||||
hexToModNScalar("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c"),
|
||||
hexToModNScalar("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f"),
|
||||
)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sig.Serialize()
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkNonceRFC6979 benchmarks how long it takes to generate a
|
||||
// deterministic nonce according to RFC6979.
|
||||
func BenchmarkNonceRFC6979(b *testing.B) {
|
||||
// Randomly generated keypair.
|
||||
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
|
||||
// X: d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab
|
||||
// Y: ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52
|
||||
privKeyStr := "9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d"
|
||||
privKey := hexToBytes(privKeyStr)
|
||||
|
||||
// BLAKE-256 of []byte{0x01, 0x02, 0x03, 0x04}.
|
||||
msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
var noElideNonce *secp256k1.ModNScalar
|
||||
for i := 0; i < b.N; i++ {
|
||||
noElideNonce = secp256k1.NonceRFC6979(privKey, msgHash, nil, nil, 0)
|
||||
}
|
||||
_ = noElideNonce
|
||||
}
|
||||
|
||||
// BenchmarkSignCompact benchmarks how long it takes to produce a compact
|
||||
// signature for a message.
|
||||
func BenchmarkSignCompact(b *testing.B) {
|
||||
d := hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
|
||||
privKey := secp256k1.NewPrivateKey(d)
|
||||
|
||||
// blake256 of []byte{0x01, 0x02, 0x03, 0x04}.
|
||||
msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = SignCompact(privKey, msgHash, true)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkSignCompact benchmarks how long it takes to recover a public key
|
||||
// given a compact signature and message.
|
||||
func BenchmarkRecoverCompact(b *testing.B) {
|
||||
// Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d
|
||||
wantPubKey := secp256k1.NewPublicKey(
|
||||
hexToFieldVal("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab"),
|
||||
hexToFieldVal("ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52"),
|
||||
)
|
||||
|
||||
compactSig := hexToBytes("205978b7896bc71676ba2e459882a8f52e1299449596c4f" +
|
||||
"93c59bf1fbfa2f9d3b76ecd0c99406f61a6de2bb5a8937c061c176ecf381d0231e0d" +
|
||||
"af73b922c8952c7")
|
||||
|
||||
// blake256 of []byte{0x01, 0x02, 0x03, 0x04}.
|
||||
msgHash := hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
|
||||
|
||||
// Ensure a valid compact signature is being benchmarked.
|
||||
pubKey, wasCompressed, err := RecoverCompact(compactSig, msgHash)
|
||||
if err != nil {
|
||||
b.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
if !wasCompressed {
|
||||
b.Fatal("recover claims uncompressed pubkey")
|
||||
}
|
||||
if !pubKey.IsEqual(wantPubKey) {
|
||||
b.Fatal("recover returned unexpected pubkey")
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, _ = RecoverCompact(compactSig, msgHash)
|
||||
}
|
||||
}
|
18
btcec/ecdsa/error.go
Normal file
18
btcec/ecdsa/error.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2013-2021 The btcsuite developers
|
||||
// Copyright (c) 2015-2021 The Decred developers
|
||||
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
secp_ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
)
|
||||
|
||||
// ErrorKind identifies a kind of error. It has full support for
|
||||
// errors.Is and errors.As, so the caller can directly check against
|
||||
// an error kind when determining the reason for an error.
|
||||
type ErrorKind = secp_ecdsa.ErrorKind
|
||||
|
||||
// Error identifies an error related to an ECDSA signature. It has full
|
||||
// support for errors.Is and errors.As, so the caller can ascertain the
|
||||
// specific reason for the error by checking the underlying error.
|
||||
type Error = secp_ecdsa.ErrorKind
|
@ -2,13 +2,14 @@
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec_test
|
||||
package ecdsa_test
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
@ -27,7 +28,7 @@ func Example_signMessage() {
|
||||
// Sign a message using the private key.
|
||||
message := "test message"
|
||||
messageHash := chainhash.DoubleHashB([]byte(message))
|
||||
signature := btcec.Sign(privKey, messageHash)
|
||||
signature := ecdsa.Sign(privKey, messageHash)
|
||||
|
||||
// Serialize and display the signature.
|
||||
fmt.Printf("Serialized Signature: %x\n", signature.Serialize())
|
||||
@ -67,7 +68,7 @@ func Example_verifySignature() {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
signature, err := btcec.ParseSignature(sigBytes)
|
||||
signature, err := ecdsa.ParseSignature(sigBytes)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
@ -1,14 +1,16 @@
|
||||
// Copyright (c) 2013-2017 The btcsuite developers
|
||||
// Copyright (c) 2015-2021 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
secp_ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
)
|
||||
|
||||
@ -22,7 +24,7 @@ var (
|
||||
type Signature = secp_ecdsa.Signature
|
||||
|
||||
// NewSignature instantiates a new signature given some r and s values.
|
||||
func NewSignature(r, s *ModNScalar) *Signature {
|
||||
func NewSignature(r, s *btcec.ModNScalar) *Signature {
|
||||
return secp_ecdsa.NewSignature(r, s)
|
||||
}
|
||||
|
||||
@ -122,7 +124,7 @@ func parseSig(sigStr []byte, der bool) (*Signature, error) {
|
||||
// R must be in the range [1, N-1]. Notice the check for the maximum number
|
||||
// of bytes is required because SetByteSlice truncates as noted in its
|
||||
// comment so it could otherwise fail to detect the overflow.
|
||||
var r ModNScalar
|
||||
var r btcec.ModNScalar
|
||||
if len(rBytes) > 32 {
|
||||
str := "invalid signature: R is larger than 256 bits"
|
||||
return nil, errors.New(str)
|
||||
@ -169,7 +171,7 @@ func parseSig(sigStr []byte, der bool) (*Signature, error) {
|
||||
// S must be in the range [1, N-1]. Notice the check for the maximum number
|
||||
// of bytes is required because SetByteSlice truncates as noted in its
|
||||
// comment so it could otherwise fail to detect the overflow.
|
||||
var s ModNScalar
|
||||
var s btcec.ModNScalar
|
||||
if len(sBytes) > 32 {
|
||||
str := "invalid signature: S is larger than 256 bits"
|
||||
return nil, errors.New(str)
|
||||
@ -214,7 +216,7 @@ func ParseDERSignature(sigStr []byte) (*Signature, error) {
|
||||
// returned in the format:
|
||||
// <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R><padded bytes for signature S>
|
||||
// where the R and S parameters are padde up to the bitlengh of the curve.
|
||||
func SignCompact(key *PrivateKey, hash []byte,
|
||||
func SignCompact(key *btcec.PrivateKey, hash []byte,
|
||||
isCompressedKey bool) ([]byte, error) {
|
||||
|
||||
return secp_ecdsa.SignCompact(key, hash, isCompressedKey), nil
|
||||
@ -224,7 +226,7 @@ func SignCompact(key *PrivateKey, hash []byte,
|
||||
// Koblitz curve in "curve". If the signature matches then the recovered public
|
||||
// key will be returned as well as a boolean if the original key was compressed
|
||||
// or not, else an error will be returned.
|
||||
func RecoverCompact(signature, hash []byte) (*PublicKey, bool, error) {
|
||||
func RecoverCompact(signature, hash []byte) (*btcec.PublicKey, bool, error) {
|
||||
return secp_ecdsa.RecoverCompact(signature, hash)
|
||||
}
|
||||
|
||||
@ -233,6 +235,6 @@ func RecoverCompact(signature, hash []byte) (*PublicKey, bool, error) {
|
||||
// given private key. The produced signature is deterministic (same message and
|
||||
// same key yield the same signature) and canonical in accordance with RFC6979
|
||||
// and BIP0062.
|
||||
func Sign(key *PrivateKey, hash []byte) *Signature {
|
||||
func Sign(key *btcec.PrivateKey, hash []byte) *Signature {
|
||||
return secp_ecdsa.Sign(key, hash)
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
// Copyright (c) 2013-2017 The btcsuite developers
|
||||
// Copyright (c) 2015-2021 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -12,6 +13,8 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
)
|
||||
|
||||
type signatureTest struct {
|
||||
@ -344,9 +347,7 @@ func TestSignatures(t *testing.T) {
|
||||
if test.isValid {
|
||||
t.Errorf("%s signature failed when shouldn't %v",
|
||||
test.name, err)
|
||||
} /* else {
|
||||
t.Errorf("%s got error %v", test.name, err)
|
||||
} */
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !test.isValid {
|
||||
@ -443,7 +444,7 @@ func TestSignatureSerialize(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"zero signature",
|
||||
NewSignature(&ModNScalar{}, &ModNScalar{}),
|
||||
NewSignature(&btcec.ModNScalar{}, &btcec.ModNScalar{}),
|
||||
[]byte{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00},
|
||||
},
|
||||
}
|
||||
@ -458,9 +459,9 @@ func TestSignatureSerialize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testSignCompact(t *testing.T, tag string, curve *KoblitzCurve,
|
||||
func testSignCompact(t *testing.T, tag string, curve *btcec.KoblitzCurve,
|
||||
data []byte, isCompressed bool) {
|
||||
priv, _ := NewPrivateKey()
|
||||
priv, _ := btcec.NewPrivateKey()
|
||||
|
||||
hashed := []byte("testing")
|
||||
sig, err := SignCompact(priv, hashed, isCompressed)
|
||||
@ -523,7 +524,7 @@ func TestSignCompact(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
compressed := i%2 != 0
|
||||
testSignCompact(t, name, S256(), data, compressed)
|
||||
testSignCompact(t, name, btcec.S256(), data, compressed)
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,7 +621,7 @@ func TestRecoverCompact(t *testing.T) {
|
||||
}
|
||||
|
||||
// Otherwise, ensure the correct public key was recovered.
|
||||
exPub, _ := ParsePubKey(decodeHex(test.pub))
|
||||
exPub, _ := btcec.ParsePubKey(decodeHex(test.pub))
|
||||
if !exPub.IsEqual(pub) {
|
||||
t.Errorf("unexpected recovered public key #%d: "+
|
||||
"want %v, got %v", i, exPub, pub)
|
||||
@ -679,11 +680,11 @@ func TestRFC6979(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
privKey, _ := PrivKeyFromBytes(decodeHex(test.key))
|
||||
privKey, _ := btcec.PrivKeyFromBytes(decodeHex(test.key))
|
||||
hash := sha256.Sum256([]byte(test.msg))
|
||||
|
||||
// Ensure deterministically generated nonce is the expected value.
|
||||
gotNonce := NonceRFC6979(privKey.Serialize(), hash[:], nil, nil, 0).Bytes()
|
||||
gotNonce := btcec.NonceRFC6979(privKey.Serialize(), hash[:], nil, nil, 0).Bytes()
|
||||
wantNonce := decodeHex(test.nonce)
|
||||
if !bytes.Equal(gotNonce[:], wantNonce) {
|
||||
t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
|
||||
@ -726,3 +727,65 @@ func TestSignatureIsEqual(t *testing.T) {
|
||||
"equal to %v", sig1, sig2)
|
||||
}
|
||||
}
|
||||
|
||||
func testSignAndVerify(t *testing.T, c *btcec.KoblitzCurve, tag string) {
|
||||
priv, _ := btcec.NewPrivateKey()
|
||||
pub := priv.PubKey()
|
||||
|
||||
hashed := []byte("testing")
|
||||
sig := Sign(priv, hashed)
|
||||
|
||||
if !sig.Verify(hashed, pub) {
|
||||
t.Errorf("%s: Verify failed", tag)
|
||||
}
|
||||
|
||||
hashed[0] ^= 0xff
|
||||
if sig.Verify(hashed, pub) {
|
||||
t.Errorf("%s: Verify always works!", tag)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignAndVerify(t *testing.T) {
|
||||
testSignAndVerify(t, btcec.S256(), "S256")
|
||||
}
|
||||
|
||||
func TestPrivKeys(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
key []byte
|
||||
}{
|
||||
{
|
||||
name: "check curve",
|
||||
key: []byte{
|
||||
0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6,
|
||||
0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c,
|
||||
0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9,
|
||||
0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
priv, pub := btcec.PrivKeyFromBytes(test.key)
|
||||
|
||||
_, err := btcec.ParsePubKey(pub.SerializeUncompressed())
|
||||
if err != nil {
|
||||
t.Errorf("%s privkey: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}
|
||||
sig := Sign(priv, hash)
|
||||
|
||||
if !sig.Verify(hash, pub) {
|
||||
t.Errorf("%s could not verify: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
serializedKey := priv.Serialize()
|
||||
if !bytes.Equal(serializedKey, test.key) {
|
||||
t.Errorf("%s unexpected serialized bytes - got: %x, "+
|
||||
"want: %x", test.name, serializedKey, test.key)
|
||||
}
|
||||
}
|
||||
}
|
@ -7,3 +7,9 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
|
||||
)
|
||||
|
||||
require github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
|
||||
|
||||
// We depend on chainhash as is, so we need to replace to use the version of
|
||||
// chainhash included in the version of btcd we're building in.
|
||||
replace github.com/btcsuite/btcd => ../
|
||||
|
56
btcec/go.sum
56
btcec/go.sum
@ -1,18 +1,12 @@
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c h1:lnAMg3ra/Gw4AkRMxrxYs8nrprWsHowg8H9zaYsJOo4=
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.0.0/go.mod h1:vu+77Lro3alBlmsmlDnkZtgGiNo6OBwMHSb1XTGDwGo=
|
||||
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||
@ -20,65 +14,17 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrivKeys(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
key []byte
|
||||
}{
|
||||
{
|
||||
name: "check curve",
|
||||
key: []byte{
|
||||
0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6,
|
||||
0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c,
|
||||
0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9,
|
||||
0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
priv, pub := PrivKeyFromBytes(test.key)
|
||||
|
||||
_, err := ParsePubKey(pub.SerializeUncompressed())
|
||||
if err != nil {
|
||||
t.Errorf("%s privkey: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}
|
||||
sig := Sign(priv, hash)
|
||||
|
||||
if !sig.Verify(hash, pub) {
|
||||
t.Errorf("%s could not verify: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
serializedKey := priv.Serialize()
|
||||
if !bytes.Equal(serializedKey, test.key) {
|
||||
t.Errorf("%s unexpected serialized bytes - got: %x, "+
|
||||
"want: %x", test.name, serializedKey, test.key)
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
)
|
||||
|
||||
// PartialSig encapsulate a (BTC public key, ECDSA signature)
|
||||
@ -38,7 +39,7 @@ func validatePubkey(pubKey []byte) bool {
|
||||
// ECDSA signature, including the sighash flag. It does *not* of course
|
||||
// validate the signature against any message or public key.
|
||||
func validateSignature(sig []byte) bool {
|
||||
_, err := btcec.ParseDERSignature(sig)
|
||||
_, err := ecdsa.ParseDERSignature(sig)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/blockchain/indexers"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcjson"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
@ -3520,7 +3520,7 @@ func handleSignMessageWithPrivKey(s *rpcServer, cmd interface{}, closeChan <-cha
|
||||
wire.WriteVarString(&buf, 0, c.Message)
|
||||
messageHash := chainhash.DoubleHashB(buf.Bytes())
|
||||
|
||||
sig, err := btcec.SignCompact(wif.PrivKey,
|
||||
sig, err := ecdsa.SignCompact(wif.PrivKey,
|
||||
messageHash, wif.CompressPubKey)
|
||||
if err != nil {
|
||||
return nil, &btcjson.RPCError{
|
||||
@ -3715,7 +3715,7 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||
wire.WriteVarString(&buf, 0, messageSignatureHeader)
|
||||
wire.WriteVarString(&buf, 0, c.Message)
|
||||
expectedMessageHash := chainhash.DoubleHashB(buf.Bytes())
|
||||
pk, wasCompressed, err := btcec.RecoverCompact(sig,
|
||||
pk, wasCompressed, err := ecdsa.RecoverCompact(sig,
|
||||
expectedMessageHash)
|
||||
if err != nil {
|
||||
// Mirror Bitcoin Core behavior, which treats error in
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
@ -1935,13 +1936,13 @@ func opcodeCheckSig(op *opcode, data []byte, vm *Engine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var signature *btcec.Signature
|
||||
var signature *ecdsa.Signature
|
||||
if vm.hasFlag(ScriptVerifyStrictEncoding) ||
|
||||
vm.hasFlag(ScriptVerifyDERSignatures) {
|
||||
|
||||
signature, err = btcec.ParseDERSignature(sigBytes)
|
||||
signature, err = ecdsa.ParseDERSignature(sigBytes)
|
||||
} else {
|
||||
signature, err = btcec.ParseSignature(sigBytes)
|
||||
signature, err = ecdsa.ParseSignature(sigBytes)
|
||||
}
|
||||
if err != nil {
|
||||
vm.dstack.PushBool(false)
|
||||
@ -1989,7 +1990,7 @@ func opcodeCheckSigVerify(op *opcode, data []byte, vm *Engine) error {
|
||||
// the same signature multiple times when verifying a multisig.
|
||||
type parsedSigInfo struct {
|
||||
signature []byte
|
||||
parsedSignature *btcec.Signature
|
||||
parsedSignature *ecdsa.Signature
|
||||
parsed bool
|
||||
}
|
||||
|
||||
@ -2134,7 +2135,7 @@ func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error {
|
||||
signature := rawSig[:len(rawSig)-1]
|
||||
|
||||
// Only parse and check the signature encoding once.
|
||||
var parsedSig *btcec.Signature
|
||||
var parsedSig *ecdsa.Signature
|
||||
if !sigInfo.parsed {
|
||||
if err := vm.checkHashTypeEncoding(hashType); err != nil {
|
||||
return err
|
||||
@ -2148,9 +2149,9 @@ func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error {
|
||||
if vm.hasFlag(ScriptVerifyStrictEncoding) ||
|
||||
vm.hasFlag(ScriptVerifyDERSignatures) {
|
||||
|
||||
parsedSig, err = btcec.ParseDERSignature(signature)
|
||||
parsedSig, err = ecdsa.ParseDERSignature(signature)
|
||||
} else {
|
||||
parsedSig, err = btcec.ParseSignature(signature)
|
||||
parsedSig, err = ecdsa.ParseSignature(signature)
|
||||
}
|
||||
sigInfo.parsed = true
|
||||
if err != nil {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
@ -20,7 +21,7 @@ const (
|
||||
// Signature hash type (1 byte)
|
||||
// Public key length (1 byte)
|
||||
// Public key (33 byte)
|
||||
minPubKeyHashSigScriptLen = 1 + btcec.MinSigLen + 1 + 1 + 33
|
||||
minPubKeyHashSigScriptLen = 1 + ecdsa.MinSigLen + 1 + 1 + 33
|
||||
|
||||
// maxPubKeyHashSigScriptLen is the maximum length of a signature script
|
||||
// that spends a P2PKH output. The length is composed of the following:
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
@ -18,7 +19,7 @@ import (
|
||||
// match. In the occasion that two sigHashes collide, the newer sigHash will
|
||||
// simply overwrite the existing entry.
|
||||
type sigCacheEntry struct {
|
||||
sig *btcec.Signature
|
||||
sig *ecdsa.Signature
|
||||
pubKey *btcec.PublicKey
|
||||
}
|
||||
|
||||
@ -55,7 +56,7 @@ func NewSigCache(maxEntries uint) *SigCache {
|
||||
//
|
||||
// NOTE: This function is safe for concurrent access. Readers won't be blocked
|
||||
// unless there exists a writer, adding an entry to the SigCache.
|
||||
func (s *SigCache) Exists(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) bool {
|
||||
func (s *SigCache) Exists(sigHash chainhash.Hash, sig *ecdsa.Signature, pubKey *btcec.PublicKey) bool {
|
||||
s.RLock()
|
||||
entry, ok := s.validSigs[sigHash]
|
||||
s.RUnlock()
|
||||
@ -70,7 +71,7 @@ func (s *SigCache) Exists(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *
|
||||
//
|
||||
// NOTE: This function is safe for concurrent access. Writers will block
|
||||
// simultaneous readers until function execution has concluded.
|
||||
func (s *SigCache) Add(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) {
|
||||
func (s *SigCache) Add(sigHash chainhash.Hash, sig *ecdsa.Signature, pubKey *btcec.PublicKey) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
|
@ -9,13 +9,14 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
// genRandomSig returns a random message, a signature of the message under the
|
||||
// public key and the public key. This function is used to generate randomized
|
||||
// test data.
|
||||
func genRandomSig() (*chainhash.Hash, *btcec.Signature, *btcec.PublicKey, error) {
|
||||
func genRandomSig() (*chainhash.Hash, *ecdsa.Signature, *btcec.PublicKey, error) {
|
||||
privKey, err := btcec.NewPrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
@ -26,7 +27,7 @@ func genRandomSig() (*chainhash.Hash, *btcec.Signature, *btcec.PublicKey, error)
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
sig := btcec.Sign(privKey, msgHash[:])
|
||||
sig := ecdsa.Sign(privKey, msgHash[:])
|
||||
|
||||
return &msgHash, sig, privKey.PubKey(), nil
|
||||
}
|
||||
@ -46,7 +47,7 @@ func TestSigCacheAddExists(t *testing.T) {
|
||||
sigCache.Add(*msg1, sig1, key1)
|
||||
|
||||
// The previously added triplet should now be found within the sigcache.
|
||||
sig1Copy, _ := btcec.ParseSignature(sig1.Serialize())
|
||||
sig1Copy, _ := ecdsa.ParseSignature(sig1.Serialize())
|
||||
key1Copy, _ := btcec.ParsePubKey(key1.SerializeCompressed())
|
||||
if !sigCache.Exists(*msg1, sig1Copy, key1Copy) {
|
||||
t.Errorf("previously added item not found in signature cache")
|
||||
@ -70,7 +71,7 @@ func TestSigCacheAddEvictEntry(t *testing.T) {
|
||||
|
||||
sigCache.Add(*msg, sig, key)
|
||||
|
||||
sigCopy, err := btcec.ParseSignature(sig.Serialize())
|
||||
sigCopy, err := ecdsa.ParseSignature(sig.Serialize())
|
||||
if err != nil {
|
||||
t.Fatalf("unable to parse sig: %v", err)
|
||||
}
|
||||
@ -105,7 +106,7 @@ func TestSigCacheAddEvictEntry(t *testing.T) {
|
||||
}
|
||||
|
||||
// The entry added above should be found within the sigcache.
|
||||
sigNewCopy, _ := btcec.ParseSignature(sigNew.Serialize())
|
||||
sigNewCopy, _ := ecdsa.ParseSignature(sigNew.Serialize())
|
||||
keyNewCopy, _ := btcec.ParsePubKey(keyNew.SerializeCompressed())
|
||||
if !sigCache.Exists(*msgNew, sigNewCopy, keyNewCopy) {
|
||||
t.Fatalf("previously added item not found in signature cache")
|
||||
@ -128,7 +129,7 @@ func TestSigCacheAddMaxEntriesZeroOrNegative(t *testing.T) {
|
||||
sigCache.Add(*msg1, sig1, key1)
|
||||
|
||||
// The generated triplet should not be found.
|
||||
sig1Copy, _ := btcec.ParseSignature(sig1.Serialize())
|
||||
sig1Copy, _ := ecdsa.ParseSignature(sig1.Serialize())
|
||||
key1Copy, _ := btcec.ParsePubKey(key1.SerializeCompressed())
|
||||
if sigCache.Exists(*msg1, sig1Copy, key1Copy) {
|
||||
t.Errorf("previously added signature found in sigcache, but" +
|
||||
|
@ -7,6 +7,8 @@ package txscript
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
@ -27,7 +29,7 @@ func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature := btcec.Sign(key, hash)
|
||||
signature := ecdsa.Sign(key, hash)
|
||||
|
||||
return append(signature.Serialize(), byte(hashType)), nil
|
||||
}
|
||||
@ -69,7 +71,7 @@ func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signature := btcec.Sign(key, hash)
|
||||
signature := ecdsa.Sign(key, hash)
|
||||
|
||||
return append(signature.Serialize(), byte(hashType)), nil
|
||||
}
|
||||
@ -263,7 +265,7 @@ sigLoop:
|
||||
tSig := sig[:len(sig)-1]
|
||||
hashType := SigHashType(sig[len(sig)-1])
|
||||
|
||||
pSig, err := btcec.ParseDERSignature(tSig)
|
||||
pSig, err := ecdsa.ParseDERSignature(tSig)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user