Add EC signature validations before call to libsecp256k1

pull/1166/head
Gustav Simonsson 10 years ago
parent 5b14fdb94b
commit 32e1b104f8
  1. 6
      core/transaction_pool.go
  2. 31
      core/types/transaction.go
  3. 14
      crypto/crypto.go

@ -112,12 +112,6 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
return ErrInvalidSender 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) { if !pool.currentState().HasAccount(from) {
return ErrNonExistentAccount return ErrNonExistentAccount
} }

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "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"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@ -93,9 +92,9 @@ func (self *Transaction) SetNonce(AccountNonce uint64) {
} }
func (self *Transaction) From() (common.Address, error) { func (self *Transaction) From() (common.Address, error) {
pubkey := self.PublicKey() pubkey, err := self.PublicKey()
if len(pubkey) == 0 || pubkey[0] != 4 { if err != nil {
return common.Address{}, errors.New("invalid public key") return common.Address{}, err
} }
var addr common.Address var addr common.Address
@ -110,34 +109,34 @@ func (tx *Transaction) To() *common.Address {
return tx.Recipient 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) v = byte(tx.V)
r = common.LeftPadBytes(tx.R.Bytes(), 32) r = common.LeftPadBytes(tx.R.Bytes(), 32)
s = common.LeftPadBytes(tx.S.Bytes(), 32) s = common.LeftPadBytes(tx.S.Bytes(), 32)
return return
} }
func (tx *Transaction) Signature(key []byte) []byte { func (tx *Transaction) PublicKey() ([]byte, error) {
hash := tx.Hash() if !crypto.ValidateSignatureValues(tx.V, tx.R, tx.S) {
sig, _ := secp256k1.Sign(hash[:], key) return nil, errors.New("invalid v, r, s values")
return sig }
}
func (tx *Transaction) PublicKey() []byte {
hash := tx.Hash() hash := tx.Hash()
v, r, s := tx.Curve() v, r, s := tx.GetSignatureValues()
sig := append(r, s...) sig := append(r, s...)
sig = append(sig, v-27) sig = append(sig, v-27)
//pubkey := crypto.Ecrecover(append(hash[:], sig...))
//pubkey, _ := secp256k1.RecoverPubkey(hash[:], sig)
p, err := crypto.SigToPub(hash[:], sig) p, err := crypto.SigToPub(hash[:], sig)
if err != nil { if err != nil {
glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err) glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
return nil return nil, err
} }
pubkey := crypto.FromECDSAPub(p) 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 { func (tx *Transaction) SetSignatureValues(sig []byte) error {

@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/big"
"os" "os"
"encoding/hex" "encoding/hex"
@ -151,6 +152,19 @@ func GenerateKey() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(S256(), rand.Reader) return ecdsa.GenerateKey(S256(), rand.Reader)
} }
func ValidateSignatureValues(v byte, r, s *big.Int) bool {
secp256k1n := common.String2Big("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
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) { func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
s, err := Ecrecover(hash, sig) s, err := Ecrecover(hash, sig)
if err != nil { if err != nil {

Loading…
Cancel
Save