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 }