github.com/cranelv/ethereum_mpc@v0.0.0-20191031014521-23aeb1415092/mpcService/step/txsign_calsign_step.go (about)

     1  package step
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"math/big"
     6  	"github.com/ethereum/go-ethereum/mpcService/protocol"
     7  	"github.com/ethereum/go-ethereum/log"
     8  	"github.com/ethereum/go-ethereum/crypto/secp256k1"
     9  	"github.com/ethereum/go-ethereum/mpcService/crypto"
    10  	manCrypto "github.com/ethereum/go-ethereum/crypto"
    11  	"github.com/ethereum/go-ethereum/common"
    12  	"errors"
    13  	"github.com/ethereum/go-ethereum/accounts/keystore"
    14  )
    15  
    16  type TxSign_CalSignStep struct {
    17  	TXSign_Lagrange_Step
    18  }
    19  
    20  func CreateTxSign_CalSignStep(result protocol.MpcResultInterface,nodeinfo protocol.MpcNodeInterface, resultKey string) *TxSign_CalSignStep {
    21  	log.Info("CreateTxSign_CalSignStep begin")
    22  
    23  	signSeedKeys := []string{protocol.MpcTxSignSeed}
    24  	resultKeys := []string{resultKey}
    25  	mpc := &TxSign_CalSignStep{*CreateTXSign_Lagrange_Step(result,nodeinfo, signSeedKeys, resultKeys)}
    26  	return mpc
    27  }
    28  
    29  func (txStep *TxSign_CalSignStep) InitStep() error {
    30  	log.Info("TxSign_CalSignStep.InitStep begin")
    31  
    32  	privateKey, err := txStep.mpcResult.GetValue(protocol.MpcPrivateShare)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	ar, err := txStep.mpcResult.GetValue(protocol.MpcSignARResult)
    37  	if err != nil {
    38  		return err
    39  	}
    40  //	log.Error("ARVALUE2","ar",ar.(*big.Int))
    41  	aPoint, err := txStep.mpcResult.GetValue(protocol.MpcSignAPoint)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	r, err := txStep.mpcResult.GetValue(protocol.MpcSignR)
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	c, err := txStep.mpcResult.GetValue(protocol.MpcSignC)
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	txHash, err := txStep.mpcResult.GetValue(protocol.MpcTxHash)
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	arInv := new(big.Int).Set(ar.(*big.Int))
    62  	arInv.ModInverse(arInv, crypto.Secp256k1N)
    63  	invRPoint := new(ecdsa.PublicKey)
    64  	invRPoint.Curve = secp256k1.S256()
    65  	pointA := aPoint.([2]*big.Int)
    66  	invRPoint.X, invRPoint.Y = secp256k1.S256().ScalarMult(pointA[0], pointA[1], arInv.Bytes())
    67  	if invRPoint.X == nil || invRPoint.Y == nil {
    68  		log.Error("TxSign_CalSignStep.InitStep, invalid r point")
    69  		return protocol.ErrPointZero
    70  	}
    71  
    72  //	log.Error("TxSign_CalSignStep.InitStep","InvR-X",invRPoint.X,"InvR-Y", invRPoint.Y)
    73  	SignSeed := new(big.Int).Set(invRPoint.X)
    74  	SignSeed.Mod(SignSeed, crypto.Secp256k1N)
    75  	var v uint64
    76  	if invRPoint.X.Cmp(SignSeed) == 0 {
    77  		v = 0
    78  	} else {
    79  		v = 2
    80  	}
    81  
    82  	invRPoint.Y.Mod(invRPoint.Y, big.NewInt(2))
    83  	if invRPoint.Y.Cmp(big.NewInt(0)) != 0 {
    84  		v |= 1
    85  	}
    86  
    87  	txStep.mpcResult.SetValue(protocol.MpcTxSignResultR, new(big.Int).Set(SignSeed))
    88  //	log.Error("TxSign_CalSignStep.InitStep","ResultR", SignSeed)
    89  	txStep.mpcResult.SetValue(protocol.MpcTxSignResultV,v)
    90  	priKey := privateKey.(*big.Int)
    91  	SignSeed.Mul(SignSeed, priKey)
    92  	SignSeed.Mod(SignSeed, crypto.Secp256k1N)
    93  	hash := new(big.Int).SetBytes(txHash.([]byte))
    94  	SignSeed.Add(SignSeed, hash)
    95  	SignSeed.Mod(SignSeed, crypto.Secp256k1N)
    96  	SignSeed.Mul(SignSeed, r.(*big.Int))
    97  	SignSeed.Mod(SignSeed, crypto.Secp256k1N)
    98  	SignSeed.Add(SignSeed, c.(*big.Int))
    99  	SignSeed.Mod(SignSeed, crypto.Secp256k1N)
   100  
   101  	txStep.mpcResult.SetValue(protocol.MpcTxSignSeed ,SignSeed )
   102  
   103  	err = txStep.TXSign_Lagrange_Step.InitStep()
   104  	if err != nil {
   105  		log.Info("TxSign_CalSignStep.InitStep, initStep fail, err:%s", err.Error())
   106  		return err
   107  	} else {
   108  		log.Info("TxSign_CalSignStep.InitStep succeed")
   109  		return nil
   110  	}
   111  }
   112  
   113  func (txStep *TxSign_CalSignStep) FinishStep( mpc protocol.MpcManager) error {
   114  	log.Info("TxSign_CalSignStep.FinishStep begin")
   115  
   116  	err := txStep.TXSign_Lagrange_Step.FinishStep(mpc)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	R, err := txStep.mpcResult.GetValue(protocol.MpcTxSignResultR)
   122  	if err != nil {
   123  		log.Error("MpcDistributor.SignTransaction, GetValue fail.","key", protocol.MpcTxSignResultR)
   124  		return err
   125  	}
   126  	V, err := txStep.mpcResult.GetValue(protocol.MpcTxSignResultV)
   127  	if err != nil {
   128  		log.Error("MpcDistributor.SignTransaction, GetValue fail.","key", protocol.MpcTxSignResultV)
   129  		return err
   130  	}
   131  
   132  	S, err := txStep.mpcResult.GetValue(protocol.MpcTxSignResult)
   133  	if err != nil {
   134  		log.Error("MpcDistributor.SignTransaction, GetValue fail.","key", protocol.MpcTxSignResult)
   135  		return err
   136  	}
   137  	txHash, err := txStep.mpcResult.GetValue(protocol.MpcTxHash)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	from, err := txStep.mpcResult.GetValue(protocol.MpcAddress)
   142  	if err != nil {
   143  		return err
   144  	}
   145  
   146  	err = mpc.SignTransaction(txStep.mpcResult)
   147  	if err != nil {
   148  		return err
   149  	}
   150  	sign,err := crypto.TransSignature(R.(*big.Int),S.(*big.Int),V.(uint64))
   151  	if err != nil {
   152  		return err
   153  	}
   154  //	log.Error("TxSign_CalSignStep","calSign",common.ToHex(sign))
   155  	hash := common.BytesToHash(txHash.([]byte))
   156  	pub, err := manCrypto.Ecrecover(hash[:], sign)
   157  //	log.Error("TxSign_CalSignStep","calSign",common.ToHex(sign),"hash",hash.String())
   158  	if err != nil {
   159  		return err
   160  	}
   161  	if len(pub) == 0 || pub[0] != 4 {
   162  		return errors.New("invalid public key")
   163  	}
   164  	pubKey := manCrypto.ToECDSAPub(pub)
   165  	addr := keystore.PubkeyToMpcAddress(*pubKey)
   166  	fromAddr := common.BytesToMpcAddress(from.([]byte))
   167  	if fromAddr != addr{
   168  		log.Error("TxSign_CalSignStep Error","hash",hash,"from",fromAddr,"Sign",addr)
   169  	}
   170  	txStep.mpcResult.SetValue(protocol.MpcContextResult,sign)
   171  	log.Info("TxSign_CalSignStep.FinishStep succeed")
   172  	return nil
   173  }