github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/core/wallet/wallet_utils.go (about)

     1  /*
     2  Copyright Ziggurat Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package wallet
     8  
     9  import (
    10  	"crypto/ecdsa"
    11  	"crypto/elliptic"
    12  	"encoding/hex"
    13  	"fmt"
    14  	"math/big"
    15  
    16  	"crypto/sha256"
    17  
    18  	"github.com/golang/protobuf/proto"
    19  	"github.com/inklabsfoundation/inkchain/common/crypto"
    20  	"github.com/inklabsfoundation/inkchain/common/crypto/secp256k1"
    21  	"github.com/inklabsfoundation/inkchain/common/crypto/sha3"
    22  	pb "github.com/inklabsfoundation/inkchain/protos/peer"
    23  )
    24  
    25  //--------------------------------------
    26  func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
    27  	if len(pub) == 0 {
    28  		return nil
    29  	}
    30  	x, y := elliptic.Unmarshal(S256(), pub)
    31  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
    32  }
    33  
    34  func NewECDSAPrivateKeyFromD(c elliptic.Curve, D *big.Int) *ecdsa.PrivateKey {
    35  	priv := new(ecdsa.PrivateKey)
    36  	priv.PublicKey.Curve = c
    37  	priv.D = D
    38  	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(D.Bytes())
    39  	return priv
    40  }
    41  
    42  func SignJson(json []byte, priKey string) ([]byte, error) {
    43  	hashT := sha256.Sum256(json)
    44  	pri, err := HexToECDSA(priKey)
    45  	if err != nil {
    46  		return nil, nil
    47  	}
    48  	signature, err := crypto.Sign(hashT[:], pri)
    49  	if err != nil {
    50  		return nil, nil
    51  	}
    52  	return signature, nil
    53  }
    54  
    55  func GetInvokeHash(chaincodeSpec *pb.ChaincodeSpec, geneAlg string, senderSpec *pb.SenderSpec) ([]byte, error) {
    56  	content := &pb.SignContent{ChaincodeSpec: chaincodeSpec, IdGenerationAlg: geneAlg, SenderSpec: senderSpec}
    57  	protoBytes, err := proto.Marshal(content)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	hashT := sha256.Sum256(protoBytes)
    62  	return hashT[:], nil
    63  }
    64  
    65  func SignInvoke(chaincodeSpec *pb.ChaincodeSpec, geneAlg string, senderSpec *pb.SenderSpec, priKey string) ([]byte, error) {
    66  	content := &pb.SignContent{ChaincodeSpec: chaincodeSpec, IdGenerationAlg: geneAlg, SenderSpec: senderSpec}
    67  	protoBytes, err := proto.Marshal(content)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	return SignJson(protoBytes, priKey)
    72  }
    73  
    74  func GetSenderFromSignature(hashT []byte, signature []byte) (*Address, error) {
    75  	pub, err := crypto.Ecrecover(hashT, signature)
    76  	if err != nil {
    77  		return nil, fmt.Errorf("invalid signature: %v", err)
    78  	}
    79  	return PubkeyToAddress(*ToECDSAPub(pub)), nil
    80  
    81  }
    82  
    83  func GetSenderPubKeyFromSignature(hashT []byte, signature []byte) (string, error) {
    84  	pub, err := crypto.Ecrecover(hashT, signature)
    85  	if err != nil {
    86  		return "", fmt.Errorf("invalid signature: %v", err)
    87  	}
    88  	return hex.EncodeToString(FromECDSAPub(ToECDSAPub(pub))[1:]), nil
    89  
    90  }
    91  
    92  func Keccak256(data ...[]byte) []byte {
    93  	d := sha3.NewKeccak256()
    94  	for _, b := range data {
    95  		d.Write(b)
    96  	}
    97  	return d.Sum(nil)
    98  }
    99  
   100  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
   101  	priv := new(ecdsa.PrivateKey)
   102  	priv.PublicKey.Curve = S256()
   103  	if 8*len(d) != priv.Params().BitSize {
   104  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   105  	}
   106  	priv.D = new(big.Int).SetBytes(d)
   107  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   108  	return priv, nil
   109  }
   110  
   111  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   112  	b, err := hex.DecodeString(hexkey)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	return ToECDSA(b)
   117  }
   118  
   119  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   120  	if pub == nil || pub.X == nil || pub.Y == nil {
   121  		return nil
   122  	}
   123  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   124  }
   125  
   126  func PubkeyToAddress(p ecdsa.PublicKey) *Address {
   127  	pubBytes := FromECDSAPub(&p)
   128  	return BytesToAddress(Keccak256(pubBytes[1:])[12:])
   129  }
   130  
   131  func GetAddressFromPrikey(priKey string) (*Address, error) {
   132  	ecdsa_prikey, err := HexToECDSA(priKey)
   133  	if err != nil {
   134  		return nil, err
   135  	}
   136  	return PubkeyToAddress(ecdsa_prikey.PublicKey), nil
   137  }
   138  
   139  func GetAddressHexFromPrikey(priKey string) (string, error) {
   140  	ecdsa_prikey, err := HexToECDSA(priKey)
   141  	if err != nil {
   142  		return "", err
   143  	}
   144  	return hex.EncodeToString(PubkeyToAddress(ecdsa_prikey.PublicKey).ToBytes()), nil
   145  }
   146  
   147  func CheckAndGetSenderFromSignature(signature string, data []byte) (string, error) {
   148  	signatureBytes, err := SignatureStringToBytes(signature)
   149  	if err != nil {
   150  		return "", err
   151  	}
   152  	hashT := sha256.Sum256(data)
   153  	sender, err := GetSenderFromSignature(hashT[:], signatureBytes)
   154  	if err != nil {
   155  		return "", err
   156  	}
   157  	return sender.ToString(), nil
   158  }
   159  
   160  func HexToAddress(hexKey string) (*Address, error) {
   161  	b, err := hex.DecodeString(hexKey)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	return BytesToAddress(b), nil
   166  }
   167  
   168  func S256() elliptic.Curve {
   169  	return secp256k1.S256()
   170  }