func B58Deserialize(data string) (*Key, error) {
	b, err := base58Decode(data)
	if err != nil {
		return nil, err
	}
	return Deserialize(b)
}
B58Deserialize deserializes a Key encoded in base58 encoding
package bip32
import (
	"bytes"
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha512"
	"encoding/hex"
	"errors"
)
const (
	FirstHardenedChild = uint32(0x80000000)
	PublicKeyCompressedLength = 33
)
var (
	PrivateWalletVersion, _ = hex.DecodeString("0488ADE4")
	PublicWalletVersion, _ = hex.DecodeString("0488B21E")
	ErrSerializedKeyWrongSize = errors.New("Serialized keys should by exactly 82 bytes")
	ErrHardnedChildPublicKey = errors.New("Can't create hardened child for public key")
	ErrInvalidChecksum = errors.New("Checksum doesn't match")
	ErrInvalidPrivateKey = errors.New("Invalid private key")
	ErrInvalidPublicKey = errors.New("Invalid public key")
)
type Key struct {
	Key         []byte  
	Version     []byte  
	ChildNumber []byte  
	FingerPrint []byte  
	ChainCode   []byte  
	Depth       byte    
	IsPrivate   bool    
}
func NewMasterKey(seed []byte) (*Key, error) {
	hmac := hmac.New(sha512.New, []byte("Bitcoin seed"))
	_, err := hmac.Write(seed)
	if err != nil {
		return nil, err
	}
	intermediary := hmac.Sum(nil)
	keyBytes := intermediary[:32]
	chainCode := intermediary[32:]
	err = validatePrivateKey(keyBytes)
	if err != nil {
		return nil, err
	}
	key := &Key{
		Version:     PrivateWalletVersion,
		ChainCode:   chainCode,
		Key:         keyBytes,
		Depth:       0x0,
		ChildNumber: []byte{0x00, 0x00, 0x00, 0x00},
		FingerPrint: []byte{0x00, 0x00, 0x00, 0x00},
		IsPrivate:   true,
	}
	return key, nil
}
func (key *Key) NewChildKey(childIdx uint32) (*Key, error) {
	if !key.IsPrivate && childIdx >= FirstHardenedChild {
		return nil, ErrHardnedChildPublicKey
	}
	intermediary, err := key.getIntermediary(childIdx)
	if err != nil {
		return nil, err
	}
	childKey := &Key{
		ChildNumber: uint32Bytes(childIdx),
		ChainCode:   intermediary[32:],
		Depth:       key.Depth + 1,
		IsPrivate:   key.IsPrivate,
	}
	if key.IsPrivate {
		childKey.Version = PrivateWalletVersion
		fingerprint, err := hash160(publicKeyForPrivateKey(key.Key))
		if err != nil {
			return nil, err
		}
		childKey.FingerPrint = fingerprint[:4]
		childKey.Key = addPrivateKeys(intermediary[:32], key.Key)
		err = validatePrivateKey(childKey.Key)
		if err != nil {
			return nil, err
		}
	} else {
		keyBytes := publicKeyForPrivateKey(intermediary[:32])
		err := validateChildPublicKey(keyBytes)
		if err != nil {
			return nil, err
		}
		childKey.Version = PublicWalletVersion
		fingerprint, err := hash160(key.Key)
		if err != nil {
			return nil, err
		}
		childKey.FingerPrint = fingerprint[:4]
		childKey.Key = addPublicKeys(keyBytes, key.Key)
	}
	return childKey, nil
}
func (key *Key) getIntermediary(childIdx uint32) ([]byte, error) {
	childIndexBytes := uint32Bytes(childIdx)
	var data []byte
	if childIdx >= FirstHardenedChild {
		data = append([]byte{0x0}, key.Key...)
	} else {
		if key.IsPrivate {
			data = publicKeyForPrivateKey(key.Key)
		} else {
			data = key.Key
		}
	}
	data = append(data, childIndexBytes...)
	hmac := hmac.New(sha512.New, key.ChainCode)
	_, err := hmac.Write(data)
	if err != nil {
		return nil, err
	}
	return hmac.Sum(nil), nil
}
func (key *Key) PublicKey() *Key {
	keyBytes := key.Key
	if key.IsPrivate {
		keyBytes = publicKeyForPrivateKey(keyBytes)
	}
	return &Key{
		Version:     PublicWalletVersion,
		Key:         keyBytes,
		Depth:       key.Depth,
		ChildNumber: key.ChildNumber,
		FingerPrint: key.FingerPrint,
		ChainCode:   key.ChainCode,
		IsPrivate:   false,
	}
}
func (key *Key) Serialize() ([]byte, error) {
	keyBytes := key.Key
	if key.IsPrivate {
		keyBytes = append([]byte{0x0}, keyBytes...)
	}
	buffer := new(bytes.Buffer)
	buffer.Write(key.Version)
	buffer.WriteByte(key.Depth)
	buffer.Write(key.FingerPrint)
	buffer.Write(key.ChildNumber)
	buffer.Write(key.ChainCode)
	buffer.Write(keyBytes)
	serializedKey, err := addChecksumToBytes(buffer.Bytes())
	if err != nil {
		return nil, err
	}
	return serializedKey, nil
}
func (key *Key) B58Serialize() string {
	serializedKey, err := key.Serialize()
	if err != nil {
		return ""
	}
	return base58Encode(serializedKey)
}
func (key *Key) String() string {
	return key.B58Serialize()
}
func Deserialize(data []byte) (*Key, error) {
	if len(data) != 82 {
		return nil, ErrSerializedKeyWrongSize
	}
	var key = &Key{}
	key.Version = data[0:4]
	key.Depth = data[4]
	key.FingerPrint = data[5:9]
	key.ChildNumber = data[9:13]
	key.ChainCode = data[13:45]
	if data[45] == byte(0) {
		key.IsPrivate = true
		key.Key = data[46:78]
	} else {
		key.IsPrivate = false
		key.Key = data[45:78]
	}
	cs1, err := checksum(data[0 : len(data)-4])
	if err != nil {
		return nil, err
	}
	cs2 := data[len(data)-4:]
	for i := range cs1 {
		if cs1[i] != cs2[i] {
			return nil, ErrInvalidChecksum
		}
	}
	return key, nil
}