func wifToPrivkey(wifstr string) (prikey *elliptic.PrivateKey, err error) {
	i, err := base58.DecodeToBig([]byte(wifstr))
	if err != nil {
		err = errors.New("base58 decoding of the private key failed")
		return
	}
	wif_bytes := i.Bytes()
	if wif_bytes[0] != 0x80 {
		err = errors.New("invalid key, first byte not 0x80")
		return
	}
	prikey_bytes := wif_bytes[1 : len(wif_bytes)-4]
	checksum := wif_bytes[len(wif_bytes)-4:]
	sha256_h := sha256.New()
	sha256_h.Reset()
	sha256_h.Write(wif_bytes[:len(wif_bytes)-4])  
	prikey_hash_1 := sha256_h.Sum(nil)
	sha256_h.Reset()
	sha256_h.Write(prikey_hash_1)
	prikey_hash_2 := sha256_h.Sum(nil)
	if !bytes.Equal(prikey_hash_2[0:4], checksum) {
		err = errors.New("invalid checksum on key")
		return
	}
	prikey, err = elliptic.PrivateKeyFromRawBytes(constants.Curve, prikey_bytes)
	if err != nil {
		err = errors.New("creating private key from bytes failed: " + err.Error())
		return
	}
	return prikey, nil
}
Converts the wallet import format compatible key back to a private key
package identity
import (
	"bytes"
	"crypto/sha256"
	"crypto/sha512"
	"errors"
	"math/big"
	"github.com/ishbir/base58"
	"github.com/ishbir/elliptic"
	"golang.org/x/crypto/ripemd160"
	"github.com/ishbir/bmgo/bitmessage/constants"
	"github.com/ishbir/bmgo/bitmessage/protocol/types"
)
type Base struct {
	Address
	NonceTrialsPerByte types.Varint
	ExtraBytes         types.Varint
}
type Own struct {
	Base
	SigningKey    *elliptic.PrivateKey
	EncryptionKey *elliptic.PrivateKey
}
type Foreign struct {
	Base
	SigningKey    *elliptic.PublicKey
	EncryptionKey *elliptic.PublicKey
}
func (id *Own) ToForeign() *Foreign {
	return &Foreign{
		Base:          id.Base,
		SigningKey:    &id.SigningKey.PublicKey,
		EncryptionKey: &id.EncryptionKey.PublicKey,
	}
}
func Import(address, signingKeyWif, encryptionKeyWif string) (*Own, error) {
	addr, err := DecodeAddress(address)
	if err != nil {
		return nil, err
	}
	privSigningKey, err := wifToPrivkey(signingKeyWif)
	if err != nil {
		err = errors.New("signing key decode failed: " + err.Error())
		return nil, err
	}
	privEncryptionKey, err := wifToPrivkey(encryptionKeyWif)
	if err != nil {
		err = errors.New("encryption key decode failed: " + err.Error())
		return nil, err
	}
	return &Own{
		SigningKey:    privSigningKey,
		EncryptionKey: privEncryptionKey,
		Base: Base{
			Address:            *addr,
			NonceTrialsPerByte: constants.POWDefaultNonceTrialsPerByte,
			ExtraBytes:         constants.POWDefaultExtraBytes,
		},
	}, nil
}
func (id *Own) Export() (address, signingKeyWif, encryptionKeyWif string,
	err error) {
	copy(id.Address.Ripe[:], id.hash())
	address, err = id.Address.Encode()
	if err != nil {
		err = errors.New("error encoding address: " + err.Error())
		return
	}
	signingKeyWif = privkeyToWIF(id.SigningKey)
	encryptionKeyWif = privkeyToWIF(id.EncryptionKey)
	return
}
func (id *Foreign) CreateAddress(version, stream types.Varint) {
	id.Address.Version = version
	id.Address.Stream = stream
	copy(id.Address.Ripe[:], id.hash())
}
func (id *Own) CreateAddress(version, stream types.Varint) {
	id.Address.Version = version
	id.Address.Stream = stream
	copy(id.Address.Ripe[:], id.hash())
}
func (id *Base) SetDefaultPOWParams() {
	id.ExtraBytes = constants.POWDefaultExtraBytes
	id.NonceTrialsPerByte = constants.POWDefaultNonceTrialsPerByte
}
func hash_helper(signingKey []byte, encryptionKey []byte) []byte {
	sha := sha512.New()
	ripemd := ripemd160.New()
	sha.Write(signingKey)
	sha.Write(encryptionKey)
	ripemd.Write(sha.Sum(nil))  
	return ripemd.Sum(nil)      
}
func (id *Own) hash() []byte {
	return hash_helper(id.SigningKey.PublicKey.SerializeUncompressed(),
		id.EncryptionKey.PublicKey.SerializeUncompressed())
}
func (id *Foreign) hash() []byte {
	return hash_helper(id.SigningKey.SerializeUncompressed(),
		id.EncryptionKey.SerializeUncompressed())
}
func NewRandom(initialZeros int) (*Own, error) {
	if initialZeros < 1 {  
		return nil, errors.New("minimum 1 initial zero needed")
	}
	var id = new(Own)
	var err error
	id.SigningKey, err = elliptic.GeneratePrivateKey(constants.Curve)
	if err != nil {
		return nil, errors.New("creating private signing key failed: " + err.Error())
	}
	initialZeroBytes := make([]byte, initialZeros)  
	for {
		id.EncryptionKey, err = elliptic.GeneratePrivateKey(constants.Curve)
		if err != nil {  
			return nil, errors.New("creating private encryption key failed: " + err.Error())
		}
		if bytes.Equal(id.hash()[0:initialZeros], initialZeroBytes) {
			break  
		}
	}
	id.Base.SetDefaultPOWParams()
	return id, nil
}
func NewDeterministic(passphrase string, initialZeros uint64) (*Own, error) {
	if initialZeros < 1 {  
		return nil, errors.New("minimum 1 initial zero needed")
	}
	var id = new(Own)
	var temp []byte
	var err error
	var signingKeyNonce, encryptionKeyNonce uint64 = 0, 1
	initialZeroBytes := make([]byte, initialZeros)  
	sha := sha512.New()
	for {
		temp = append([]byte(passphrase),
			types.Varint(signingKeyNonce).Serialize()...)
		sha.Reset()
		sha.Write(temp)
		id.SigningKey, err = elliptic.PrivateKeyFromRawBytes(constants.Curve,
			sha.Sum(nil)[:32])
		if err != nil {
			return nil, errors.New("private key generation failed: " + err.Error())
		}
		temp = append([]byte(passphrase),
			types.Varint(encryptionKeyNonce).Serialize()...)
		sha.Reset()
		sha.Write(temp)
		id.EncryptionKey, err = elliptic.PrivateKeyFromRawBytes(constants.Curve,
			sha.Sum(nil)[:32])
		if err != nil {
			return nil, errors.New("private key generation failed: " + err.Error())
		}
		signingKeyNonce += 2
		encryptionKeyNonce += 2
		if bytes.Equal(id.hash()[0:initialZeros], initialZeroBytes) {
			break  
		}
	}
	id.Base.SetDefaultPOWParams()
	return id, nil
}
func privkeyToWIF(prikey *elliptic.PrivateKey) (wifstr string) {
	sha256_h := sha256.New()
	prikey_bytes := prikey.Key
	wif_bytes := append([]byte{0x80}, prikey_bytes...)
	sha256_h.Reset()
	sha256_h.Write(wif_bytes)
	prikey_hash_1 := sha256_h.Sum(nil)
	sha256_h.Reset()
	sha256_h.Write(prikey_hash_1)
	prikey_hash_2 := sha256_h.Sum(nil)
	checksum := prikey_hash_2[0:4]
	wif_bytes = append(wif_bytes, checksum...)
	i := new(big.Int).SetBytes(wif_bytes)
	wifstr = string(base58.EncodeBig(nil, i))
	return wifstr
}