forked from cerc-io/plugeth
Merge pull request #1166 from Gustav-Simonsson/add_ec_sig_validations
Add EC signature validations before call to libsecp256k1
This commit is contained in:
commit
02f785af70
@ -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"
|
||||||
@ -26,9 +27,12 @@ import (
|
|||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var secp256k1n *big.Int
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// specify the params for the s256 curve
|
// specify the params for the s256 curve
|
||||||
ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256)
|
ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256)
|
||||||
|
secp256k1n = common.String2Big("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sha3(data ...[]byte) []byte {
|
func Sha3(data ...[]byte) []byte {
|
||||||
@ -151,6 +155,18 @@ 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 {
|
||||||
|
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…
Reference in New Issue
Block a user