From d5cc72dc278d87ec4c348af7f80cba17aa992ffc Mon Sep 17 00:00:00 2001 From: Jimmy Song Date: Mon, 29 Sep 2014 16:31:26 -0500 Subject: [PATCH] use btcec structs instead of ecdsa structs --- opcode.go | 6 ++-- script.go | 26 +++++++-------- script_test.go | 87 +++++++++++++++----------------------------------- 3 files changed, 39 insertions(+), 80 deletions(-) diff --git a/opcode.go b/opcode.go index aa983b0a5..990718026 100644 --- a/opcode.go +++ b/opcode.go @@ -6,7 +6,6 @@ package btcscript import ( "bytes" - "crypto/ecdsa" "crypto/sha1" "encoding/binary" "encoding/hex" @@ -1812,7 +1811,7 @@ func opcodeCheckSig(op *parsedOpcode, s *Script) error { hex.Dump(pkStr), pubKey.X, pubKey.Y, signature.R, signature.S, hex.Dump(hash)) })) - ok := ecdsa.Verify(pubKey.ToECDSA(), hash, signature.R, signature.S) + ok := signature.Verify(hash, pubKey) s.dstack.PushBool(ok) return nil } @@ -1947,8 +1946,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error { continue } } - success = ecdsa.Verify(pubKeys[curPk].ToECDSA(), hash, - signatures[i].s.R, signatures[i].s.S) + success = signatures[i].s.Verify(hash, pubKeys[curPk]) if success { break inner } diff --git a/script.go b/script.go index 255be56bd..a1e86c072 100644 --- a/script.go +++ b/script.go @@ -6,7 +6,6 @@ package btcscript import ( "bytes" - "crypto/ecdsa" "crypto/rand" "encoding/binary" "errors" @@ -1100,7 +1099,7 @@ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er // serialized in either a compressed or uncompressed format based on // compress. This format must match the same format used to generate // the payment address, or the script validation will fail. -func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType SigHashType, privKey *ecdsa.PrivateKey, compress bool) ([]byte, error) { +func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType SigHashType, privKey *btcec.PrivateKey, compress bool) ([]byte, error) { sig, err := signTxOutput(tx, idx, subscript, hashType, privKey) if err != nil { return nil, err @@ -1118,29 +1117,28 @@ func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType SigH } func signTxOutput(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType, - key *ecdsa.PrivateKey) ([]byte, error) { + key *btcec.PrivateKey) ([]byte, error) { return signTxOutputCustomReader(rand.Reader, tx, idx, subScript, hashType, key) } func signTxOutputCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int, - subScript []byte, hashType SigHashType, key *ecdsa.PrivateKey) ([]byte, error) { + subScript []byte, hashType SigHashType, key *btcec.PrivateKey) ([]byte, error) { parsedScript, err := parseScript(subScript) if err != nil { return nil, fmt.Errorf("cannot parse output script: %v", err) } hash := calcScriptHash(parsedScript, hashType, tx, idx) - r, s, err := ecdsa.Sign(reader, key, hash) + signature, err := key.Sign(hash) if err != nil { return nil, fmt.Errorf("cannot sign tx input: %s", err) } - return append((&btcec.Signature{R: r, S: s}).Serialize(), - byte(hashType)), nil + return append(signature.Serialize(), byte(hashType)), nil } -func p2pkSignatureScript(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType, privKey *ecdsa.PrivateKey) ([]byte, error) { +func p2pkSignatureScript(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType, privKey *btcec.PrivateKey) ([]byte, error) { sig, err := signTxOutput(tx, idx, subScript, hashType, privKey) if err != nil { return nil, err @@ -1384,9 +1382,7 @@ sigLoop: // If it matches we put it in the map. We only // can take one signature per public key so if we // already have one, we can throw this away. - if ecdsa.Verify(pubKey.ToECDSA(), hash, - pSig.R, pSig.S) { - + if pSig.Verify(hash, pubKey) { aStr := addr.EncodeAddress() if _, ok := addrToSig[aStr]; !ok { addrToSig[aStr] = sig @@ -1424,14 +1420,14 @@ sigLoop: // KeyDB is an interface type provided to SignTxOutput, it encapsulates // any user state required to get the private keys for an address. type KeyDB interface { - GetKey(btcutil.Address) (*ecdsa.PrivateKey, bool, error) + GetKey(btcutil.Address) (*btcec.PrivateKey, bool, error) } -// KeyClosure implements KeyDB with a closure -type KeyClosure func(btcutil.Address) (*ecdsa.PrivateKey, bool, error) +// KeyClosure implements ScriptDB with a closure +type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, error) // GetKey implements KeyDB by returning the result of calling the closure -func (kc KeyClosure) GetKey(address btcutil.Address) (*ecdsa.PrivateKey, +func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, bool, error) { return kc(address) } diff --git a/script_test.go b/script_test.go index b859fae6f..ec097c573 100644 --- a/script_test.go +++ b/script_test.go @@ -6,11 +6,8 @@ package btcscript_test import ( "bytes" - "crypto/ecdsa" - "crypto/rand" "errors" "fmt" - "math/big" "testing" "github.com/conformal/btcec" @@ -2766,17 +2763,7 @@ var SigScriptTests = []TstSigScript{ // created for the MsgTxs in txTests, since they come from the blockchain // and we don't have the private keys. func TestSignatureScript(t *testing.T) { - privKey := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: btcec.S256(), - X: new(big.Int), - Y: new(big.Int), - }, - D: new(big.Int), - } - privKey.D.SetBytes(privKeyD) - privKey.PublicKey.X.SetBytes(pubkeyX) - privKey.PublicKey.Y.SetBytes(pubkeyY) + privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD) nexttest: for i := range SigScriptTests { @@ -3272,18 +3259,18 @@ func checkScripts(msg string, tx *btcwire.MsgTx, idx int, } type addressToKey struct { - key *ecdsa.PrivateKey + key *btcec.PrivateKey compressed bool } func mkGetKey(keys map[string]addressToKey) btcscript.KeyDB { if keys == nil { - return btcscript.KeyClosure(func(addr btcutil.Address) (*ecdsa.PrivateKey, + return btcscript.KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey, bool, error) { return nil, false, errors.New("nope") }) } - return btcscript.KeyClosure(func(addr btcutil.Address) (*ecdsa.PrivateKey, + return btcscript.KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey, bool, error) { a2k, ok := keys[addr.EncodeAddress()] if !ok { @@ -3366,8 +3353,7 @@ func TestSignTxOutput(t *testing.T) { for _, hashType := range hashTypes { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3404,8 +3390,7 @@ func TestSignTxOutput(t *testing.T) { for _, hashType := range hashTypes { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3466,8 +3451,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3505,8 +3489,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3567,8 +3550,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3606,8 +3588,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3668,8 +3649,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3707,8 +3687,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3769,8 +3748,7 @@ func TestSignTxOutput(t *testing.T) { for _, hashType := range hashTypes { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3827,8 +3805,7 @@ func TestSignTxOutput(t *testing.T) { for _, hashType := range hashTypes { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3910,8 +3887,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -3968,8 +3944,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4050,8 +4025,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4108,8 +4082,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4190,8 +4163,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4248,8 +4220,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4330,8 +4301,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key1, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key1, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4348,8 +4318,7 @@ func TestSignTxOutput(t *testing.T) { break } - key2, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key2, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey 2 for %s: %v", msg, err) @@ -4409,8 +4378,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key1, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key1, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4427,8 +4395,7 @@ func TestSignTxOutput(t *testing.T) { break } - key2, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key2, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey 2 for %s: %v", msg, err) @@ -4518,8 +4485,7 @@ func TestSignTxOutput(t *testing.T) { for i := range tx.TxIn { msg := fmt.Sprintf("%d:%d", hashType, i) - key1, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key1, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey for %s: %v", msg, err) @@ -4536,8 +4502,7 @@ func TestSignTxOutput(t *testing.T) { break } - key2, err := ecdsa.GenerateKey(btcec.S256(), - rand.Reader) + key2, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { t.Errorf("failed to make privKey 2 for %s: %v", msg, err)