From ae28fe6d97b5eb7344e4fe66948e1876c967707d Mon Sep 17 00:00:00 2001 From: Jimmy Song Date: Mon, 29 Sep 2014 16:32:26 -0500 Subject: [PATCH] Use btcec structs instead of ecdsa structs everywhere. This change should make it so that only btcec relies on the crypto/ecdsa package for secp256k1 math. --- bench_test.go | 13 +++++++------ btcec_test.go | 24 +++++++++++------------- privkey.go | 15 +++++++++++++++ signature_test.go | 3 +-- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/bench_test.go b/bench_test.go index b17ee2e1..b06326be 100644 --- a/bench_test.go +++ b/bench_test.go @@ -5,7 +5,6 @@ package btcec_test import ( - "crypto/ecdsa" "testing" "github.com/conformal/btcec" @@ -75,7 +74,7 @@ func BenchmarkSigVerify(b *testing.B) { b.StopTimer() // Randomly generated keypair. // Private key: 9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d - pubKey := ecdsa.PublicKey{ + pubKey := btcec.PublicKey{ Curve: btcec.S256(), X: fromHex("d2e670a19c6d753d1a6d8b20bd045df8a08fb162cf508956c31268c6d81ffdab"), Y: fromHex("ab65528eefbb8057aa85d597258a3fbd481a24633bc9b47a9aa045c91371de52"), @@ -83,16 +82,18 @@ func BenchmarkSigVerify(b *testing.B) { // Double sha256 of []byte{0x01, 0x02, 0x03, 0x04} msgHash := fromHex("8de472e2399610baaa7f84840547cd409434e31f5d3bd71e4d947f283874f9c0") - sigR := fromHex("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c") - sigS := fromHex("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f") + sig := btcec.Signature{ + R: fromHex("fef45d2892953aa5bbcdb057b5e98b208f1617a7498af7eb765574e29b5d9c2c"), + S: fromHex("d47563f52aac6b04b55de236b7c515eb9311757db01e02cff079c3ca6efb063f"), + } - if !ecdsa.Verify(&pubKey, msgHash.Bytes(), sigR, sigS) { + if !sig.Verify(msgHash.Bytes(), &pubKey) { b.Errorf("Signature failed to verify") return } b.StartTimer() for i := 0; i < b.N; i++ { - ecdsa.Verify(&pubKey, msgHash.Bytes(), sigR, sigS) + sig.Verify(msgHash.Bytes(), &pubKey) } } diff --git a/btcec_test.go b/btcec_test.go index 4b59fb0e..9009cedf 100644 --- a/btcec_test.go +++ b/btcec_test.go @@ -7,8 +7,6 @@ package btcec_test import ( - "crypto/ecdsa" - "crypto/elliptic" "crypto/rand" "crypto/sha1" "encoding/hex" @@ -591,8 +589,8 @@ func BenchmarkBaseMult(b *testing.B) { // Test this curve's usage with the ecdsa package. -func testKeyGeneration(t *testing.T, c elliptic.Curve, tag string) { - priv, err := ecdsa.GenerateKey(c, rand.Reader) +func testKeyGeneration(t *testing.T, c *btcec.KoblitzCurve, tag string) { + priv, err := btcec.NewPrivateKey(c) if err != nil { t.Errorf("%s: error: %s", tag, err) return @@ -606,22 +604,23 @@ func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, btcec.S256(), "S256") } -func testSignAndVerify(t *testing.T, c elliptic.Curve, tag string) { - priv, _ := ecdsa.GenerateKey(c, rand.Reader) +func testSignAndVerify(t *testing.T, c *btcec.KoblitzCurve, tag string) { + priv, _ := btcec.NewPrivateKey(c) + pub := priv.PubKey() hashed := []byte("testing") - r, s, err := ecdsa.Sign(rand.Reader, priv, hashed) + sig, err := priv.Sign(hashed) if err != nil { t.Errorf("%s: error signing: %s", tag, err) return } - if !ecdsa.Verify(&priv.PublicKey, hashed, r, s) { + if !sig.Verify(hashed, pub) { t.Errorf("%s: Verify failed", tag) } hashed[0] ^= 0xff - if ecdsa.Verify(&priv.PublicKey, hashed, r, s) { + if sig.Verify(hashed, pub) { t.Errorf("%s: Verify always works!", tag) } } @@ -778,7 +777,7 @@ func TestVectors(t *testing.T) { sha := sha1.New() for i, test := range testVectors { - pub := ecdsa.PublicKey{ + pub := btcec.PublicKey{ Curve: btcec.S256(), X: fromHex(test.Qx), Y: fromHex(test.Qy), @@ -787,9 +786,8 @@ func TestVectors(t *testing.T) { sha.Reset() sha.Write(msg) hashed := sha.Sum(nil) - r := fromHex(test.r) - s := fromHex(test.s) - if fuck := ecdsa.Verify(&pub, hashed, r, s); fuck != test.ok { + sig := btcec.Signature{R: fromHex(test.r), S: fromHex(test.s)} + if fuck := sig.Verify(hashed, &pub); fuck != test.ok { //t.Errorf("%d: bad result %v %v", i, pub, hashed) t.Errorf("%d: bad result %v instead of %v", i, fuck, test.ok) diff --git a/privkey.go b/privkey.go index bad0f41e..f89b0950 100644 --- a/privkey.go +++ b/privkey.go @@ -33,6 +33,21 @@ func PrivKeyFromBytes(curve *KoblitzCurve, pk []byte) (*PrivateKey, return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey) } +// NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey +// instead of the normal ecdsa.PrivateKey. +func NewPrivateKey(curve *KoblitzCurve) (*PrivateKey, error) { + key, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, err + } + return (*PrivateKey)(key), nil +} + +// PubKey returns the PublicKey corresponding to this private key. +func (p *PrivateKey) PubKey() *PublicKey { + return (*PublicKey)(&p.PublicKey) +} + // ToECDSA returns the private key as a *ecdsa.PrivateKey. func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { return (*ecdsa.PrivateKey)(p) diff --git a/signature_test.go b/signature_test.go index 087f329e..b9a14db3 100644 --- a/signature_test.go +++ b/signature_test.go @@ -6,7 +6,6 @@ package btcec_test import ( "bytes" - "crypto/ecdsa" "crypto/rand" "fmt" "math/big" @@ -427,7 +426,7 @@ func TestSignatureSerialize(t *testing.T) { func testSignCompact(t *testing.T, tag string, curve *btcec.KoblitzCurve, data []byte, isCompressed bool) { - tmp, _ := ecdsa.GenerateKey(curve, rand.Reader) + tmp, _ := btcec.NewPrivateKey(curve) priv := (*btcec.PrivateKey)(tmp) hashed := []byte("testing")