aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-06-03 23:11:24 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-06-03 23:11:24 +0800
commit02f785af70d9d91d38ce44163a79c16ab288d55f (patch)
treebdcad5df97e544d93698bf587eb98c6ca542d734
parent827bccb64b97dd19918160af99951e8917c2d3f7 (diff)
parentedbd902a1b5e2d8d1fdff8e876594eb1859839e8 (diff)
downloadgo-tangerine-02f785af70d9d91d38ce44163a79c16ab288d55f.tar.gz
go-tangerine-02f785af70d9d91d38ce44163a79c16ab288d55f.tar.zst
go-tangerine-02f785af70d9d91d38ce44163a79c16ab288d55f.zip
Merge pull request #1166 from Gustav-Simonsson/add_ec_sig_validations
Add EC signature validations before call to libsecp256k1
-rw-r--r--core/transaction_pool.go6
-rw-r--r--core/types/transaction.go31
-rw-r--r--crypto/crypto.go16
3 files changed, 31 insertions, 22 deletions
diff --git a/core/transaction_pool.go b/core/transaction_pool.go
index c896488d1..ee6360614 100644
--- a/core/transaction_pool.go
+++ b/core/transaction_pool.go
@@ -112,12 +112,6 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return ErrInvalidSender
}
- // Validate curve param
- v, _, _ := tx.Curve()
- if v > 28 || v < 27 {
- return fmt.Errorf("tx.v != (28 || 27) => %v", v)
- }
-
if !pool.currentState().HasAccount(from) {
return ErrNonExistentAccount
}
diff --git a/core/types/transaction.go b/core/types/transaction.go
index d8dcd7424..3d6d31ae7 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp"
@@ -93,9 +92,9 @@ func (self *Transaction) SetNonce(AccountNonce uint64) {
}
func (self *Transaction) From() (common.Address, error) {
- pubkey := self.PublicKey()
- if len(pubkey) == 0 || pubkey[0] != 4 {
- return common.Address{}, errors.New("invalid public key")
+ pubkey, err := self.PublicKey()
+ if err != nil {
+ return common.Address{}, err
}
var addr common.Address
@@ -110,34 +109,34 @@ func (tx *Transaction) To() *common.Address {
return tx.Recipient
}
-func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
+func (tx *Transaction) GetSignatureValues() (v byte, r []byte, s []byte) {
v = byte(tx.V)
r = common.LeftPadBytes(tx.R.Bytes(), 32)
s = common.LeftPadBytes(tx.S.Bytes(), 32)
return
}
-func (tx *Transaction) Signature(key []byte) []byte {
- hash := tx.Hash()
- sig, _ := secp256k1.Sign(hash[:], key)
- return sig
-}
+func (tx *Transaction) PublicKey() ([]byte, error) {
+ if !crypto.ValidateSignatureValues(tx.V, tx.R, tx.S) {
+ return nil, errors.New("invalid v, r, s values")
+ }
-func (tx *Transaction) PublicKey() []byte {
hash := tx.Hash()
- v, r, s := tx.Curve()
+ v, r, s := tx.GetSignatureValues()
sig := append(r, s...)
sig = append(sig, v-27)
- //pubkey := crypto.Ecrecover(append(hash[:], sig...))
- //pubkey, _ := secp256k1.RecoverPubkey(hash[:], sig)
p, err := crypto.SigToPub(hash[:], sig)
if err != nil {
glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
- return nil
+ return nil, err
}
+
pubkey := crypto.FromECDSAPub(p)
- return pubkey
+ if len(pubkey) == 0 || pubkey[0] != 4 {
+ return nil, errors.New("invalid public key")
+ }
+ return pubkey, nil
}
func (tx *Transaction) SetSignatureValues(sig []byte) error {
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 4bbd62f7f..9aef44863 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -10,6 +10,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "math/big"
"os"
"encoding/hex"
@@ -26,9 +27,12 @@ import (
"golang.org/x/crypto/ripemd160"
)
+var secp256k1n *big.Int
+
func init() {
// specify the params for the s256 curve
ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256)
+ secp256k1n = common.String2Big("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
}
func Sha3(data ...[]byte) []byte {
@@ -151,6 +155,18 @@ func GenerateKey() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(S256(), rand.Reader)
}
+func ValidateSignatureValues(v byte, r, s *big.Int) bool {
+ vint := uint32(v)
+ if r.Cmp(common.Big0) == 0 || s.Cmp(common.Big0) == 0 {
+ return false
+ }
+ if r.Cmp(secp256k1n) < 0 && s.Cmp(secp256k1n) < 0 && (vint == 27 || vint == 28) {
+ return true
+ } else {
+ return false
+ }
+}
+
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
s, err := Ecrecover(hash, sig)
if err != nil {